响应式布局是为了同一页面在不同设备屏幕尺寸下都能正常显示。
常用响应式布局方案
>>媒体查询方案
媒体查询有两种用法
- 直接在 css 文件中定义不同屏幕下的样式
- 通过 link 中的媒体查询,不同屏幕引用不同的分辨率
如果要实现两个不同屏幕下的样式,可以这样使用媒体查询
/** 方式一:直接定义两个屏幕的样式 **/
@media screen and (max-width: 320px) {
.home {
width: 80%;
font-size: 14px
}
}
@media screen and (min-width: 768px) {
.home {
width: 100%;
font-size: 10px
}
}
<!-- 方式二:通过 link 引用不同屏幕的 css 文件 -->
<link rel="stylesheet" media="(max-width: 320px)" href="pc.css" />
<link rel="stylesheet" media="(min-width: 768px)" href="laptop.css" />
max-width:对最大宽度的限制。max-width: 320px,意思是说当设备屏幕宽度不大于320px时,则采纳这条声明对应的样式规则。
min-width:对最小宽度的限制。min-width: 768px,意思是说当设备屏幕宽度不小于768px时,则采纳这条声明对应的样式规则。
>>动态rem / em方案
em 和 rem 都是相对单位,区别在于
- em 根据自身字体大小计算
- rem 根据根节点 html 的字体大小计算(root em),默认是 16 px
所有单位都是相对于根元素html的font-size
来决定大小的,当页面的size发生变化时,只需要改变font-size
的值,那么以rem
或em
为固定单位的元素的大小也会发生响应的变化。所以我们只要根据屏幕宽度和设计图的宽度动态声明font-size
的大小,然后以rem
或em
作为长度单位声明所有节点的几何属性,就可以实现自适应布局的效果。
function autoResponse(width = 750) {
const target = document.documentElement
if (target.clientWidth >= 600) {
target.style.fontSize = '40px'
} else {
target.style.fontSize = `${target.clientWidth / width * 100}px`
}
}
autoResponse()
window.addEventListener('resize', autoResponse)
rem响应式的布局思想:
- 一般不要给元素设置具体的宽度,但是对于一些小图标可以设定具体宽度值。
- 高度值可以设置固定值。
- 所有设置的固定值都用
rem
做单位(首先在HTML总设置一个基准值:px
和rem
的对应比例,然后在效果图上获取px
值,布局的时候转化为rem
值) - js获取真实屏幕的宽度,让其除以设计稿的宽度,算出比例,把之前的基准值按照比例进行重新的设定,这样项目就可以在移动端自适应了。
rem布局的缺点:
- 在响应式布局中,必须通过js来动态控制根元素
font-size
的大小,也就是说css样式和js代码有一定的耦合性,且必须将改变font-size
的代码放在css
样式之前。 - 要在 html 的 meta 属性中将布局窗口设置为屏幕宽度,并且禁止缩放屏幕。
>>视口单位 vw/vh 方案
css3引入了新的单位 vw/vh
- vw:表示相对于视图窗口的宽度,1vw等于视口宽度的1%
- vh:表示相对于视图窗口的高度,1vh等于视口高度的1%
另外还有vmin和vmax两个相关单位
- vmin:vw和vh中的较小值
- vmax:vw和vh中的较大值
使用视口单位来实现响应式有两种做法:
1、仅使用vw作为CSS单位
- 对于设计稿的尺寸转换为vw、vh为单位
//iPhone 6尺寸作为设计稿基准
@function vm(px) {
@return (px / 375) * 100vw;
}
- 无论是文本还是布局宽度、间距等都使用
vm
作为单位
.mod_nav {
background-color: #fff;
&_list {
display: flex;
padding: vm(15) vm(10) vm(10); // 内间距
&_item {
flex: 1;
text-align: center;
font-size: vm(10); // 字体大小
&_logo {
display: block;
margin: 0 auto;
width: vm(40); // 宽度
height: vm(40); // 高度
img {
display: block;
margin: 0 auto;
max-width: 100%;
}
}
&_name {
margin-top: vm(2);
}
}
}
}
- 1物理像素线(也就是普通屏幕下1px,高清屏幕下0.5px的情况)采用
transform
属性scale
实现
.mod_grid {
position: relative;
&::after {
// 实现1物理像素的下边框线
content: '';
position: absolute;
z-index: 1;
pointer-events: none;
background-color: #ddd;
height: 1px;
left: 0;
right: 0;
top: 0;
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
-webkit-transform: scaleY(0.5);
-webkit-transform-origin: 50% 0%;
}
}
...
}
- 对于需要保持宽高比的图,应该用
padding-top
实现
.mod_banner {
position: relative;
padding-top: percentage(100/700); // 使用padding-top
height: 0;
overflow: hidden;
img {
width: 100%;
height: auto;
position: absolute;
left: 0;
top: 0;
}
}
2、搭配vw和rem
虽然采用vw
适配后的页面效果很好,但是它是利用视口单位实现的布局,依赖视口大小而自动缩放,无论视口过大还是过小,它也随着时候过大或者过小,失去了最大最小宽度的限制,此时我们可以结合rem
来实现布局
- 给根元素大小设置随着视口变化而变化的
vw
单位,这样就可以实现动态改变其大小 - 限制根元素字体大小的最大最小值,配合
body
加上最大宽度和最小宽度
// rem 单位换算:定为 75px 只是方便运算,750px-75px、640-64px、1080px-108px,如此类推
$vm_fontsize: 75; // iPhone 6尺寸的根元素大小基准值
@function rem($px) {
@return ($px / $vm_fontsize ) * 1rem;
}
// 根元素大小使用 vw 单位
$vm_design: 750;
html {
font-size: ($vm_fontsize / ($vm_design / 2)) * 100vw;
// 同时,通过Media Queries 限制根元素最大最小值
@media screen and (max-width: 320px) {
font-size: 64px;
}
@media screen and (min-width: 540px) {
font-size: 108px;
}
}
// body 也增加最大最小宽度限制,避免默认100%宽度的 block 元素跟随 body 而过大过小
body {
max-width: 540px;
min-width: 320px;
}
参考文章:
© 版权声明
文章版权归作者所有,未经允许请勿转载,侵权请联系 admin@trc20.tw 删除。
THE END