响应式布局浅析
所谓响应式布局,就是页面会根据当前运行的设备的大小自行进行调整,实现方案主要有以下三种:
1)隐藏
例如在 PC 端的一些友情链接或者不重要的内容在移动端可以选择隐藏起来。
2)换行
在 PC 端显示一行的内容,由于移动端设备宽度比较小,所以可以选择显示为几行。
3)自适应空间
例如,左边元素给定一个具体的值,右边元素的宽度令其根据不同的设备宽度自行调整。
具体的实现方法主要有以下几种:
1)rem
rem 是一个相对单位,一般 1rem = html设置的 font-size 的值。
关于 rem 的详细介绍可以参考 移动 web 开发适配秘籍 Rem 这个免费课程。
通过设置不同设备 html 的 font-size 改变 rem 的值,令 1rem 单位的值随着设备的增大而增大。
2)viewport
设置 <meta name="viewport" content="width=device-width, initial-scale=1.0" >
,关于这个下面会介绍。
3)media query
判断当前是什么设备,然后根据不同的设备设置不同的样式。
接下来先说一下 viewport 这个 meta 标签。
<meta name="viewport" content="width=device-width, initial-scale=1.0" >
为什么要让可视区域的宽度等于设备的宽度
viewport 指的是可视区域(说白了就是展示页面的区域,一般情况下当然是设备的屏幕多大就让展示页面的区域是多大,如果屏幕的宽度是 320px,不设置可视区域的大小为 320px,将一个 960px 的页面(假设PC端页面是960px这么大)硬生生地展示在 320px 屏幕上,只能将页面整体缩小为原来的 1/3 去展示,那用户看起来页面上的字就太小了。
如果将可视区域的宽度调整为设备屏幕的宽度,这样会PC端 960px 的页面会在 320px 宽度的设备上重新布局,例如之前在 PC 端要展示在一行的内容,在移动端由于宽度只有 320px 一行肯定展示不下了,所以就会进行换行。经过这样布局显示出来的字体大小和 PC 端是一样的,用户体验就会比较好。
所以我们需要将可视区域的宽度设置为设备的宽度,接下来会有代码进行验证。
对于下面的代码
<style>
.container{
margin:0 auto;
max-width:800px;
display: flex;
border:1px solid black;
}
.left{
display: flex;
width: 200px;
background:red;
margin:5px;
}
.right{
display: flex;
flex: 1;
background:blue;
margin:5px;
}
</style>
</head>
<body>
<div class="container">
<div class="left">
这里是一些不重要的内容,比如友情链接、广告
</div>
<div class="right">
这里是一些重要的内容,比如一篇文章,文章是整个页面的核心内容。这里是一些重要的内容,比如一篇文章,文章是整个页面的核心内容。这里是一些重要的内容,比如一篇文章,文章是整个页面的核心内容。这里是一些重要的内容,比如一篇文章,文章是整个页面的核心内容。这里是一些重要的内容,比如一篇文章,文章是整个页面的核心内容。这里是一些重要的内容,比如一篇文章,文章是整个页面的核心内容。这里是一些重要的内容,比如一篇文章,文章是整个页面的核心内容。这里是一些重要的内容,比如一篇文章,文章是整个页面的核心内容。这里是一些重要的内容,比如一篇文章,文章是整个页面的核心内容。这里是一些重要的内容,比如一篇文章,文章是整个页面的核心内容。
</div>
</div>
</body>
如果不加 <meta name="viewport" content="width=device-width, initial-scale=1.0" >
,在PC 端的页面如下
在 iPhonex上的页面
很明显,在移动端上并没有进行适配只是进行了等比例缩放,导致字体很小,用户体验差。
这个时候再加上 <meta name="viewport" content="width=device-width initial-scale=1.0">
,在移动端的页面如下所示
可见并不是进行整体缩放,而是根据设备的宽度通过换行等方式进行了适配,这个时候的字体和PC端的字体大小也差不多,用户体验好。
通过 <meta name="viewport" content="width=device-width initial-scale=1.0">
这条语句来进行移动端适配在一些比较简单的情况,对移动端适配要求比较低的情况下是可以的,但是如果想要进行更好的移动端适配还要采用一些其他的措施,例如媒体查询等。
上图中,红色的部分实际上在移动端可以不用显示的,因为它并不是重要的内容,这个时候就可以采用媒体查询的方式当设备的宽度小于某个值之后就隐藏左边红色的区域。
可以在上面的 css 代码中添加媒体查询,当设备的宽度小于 640px 时就隐藏左边的红色区域。
@media (max-width: 640px){
.left{
display: none;
}
}
在 iphonex 的显示情况如下图所示:
再来看一个案例:
HTML 代码:
<div class="container">
<div class="intro">
介绍1
</div>
<div class="intro">
介绍2
</div>
<div class="intro">
介绍3
</div>
<div class="intro">
介绍4
</div>
</div>
CSS 代码
.container{
margin:0 auto;
max-width:800px;
border:1px solid black;
}
.intro{
display: inline-block;
width:180px;
height:180px;
line-height: 180px;
text-align: center;
border-radius: 90px;
border:1px solid red;
margin:7px;
}
在 PC 端页面显示如下:
不加 <meta name="viewport" content="width=device-width initial-scale=1.0">
时移动端页面如下:
会发现页面只是在 pc 端的基础上进行了等比例缩放,现在加上 meta 标签,
可以看到添加meta标签后会自动根据设备的宽度进行适配,iphone 5 的宽度为 320px,圆圈的宽度为 182px, margin-left 为 7px,再加上右边还有 7px 的 margin-right,所以加起来一共占了 196px,所以还剩下 124px,所以第二个圆圈只能排在第二行。
现在有个问题是靠左边太多了,我们想让它在移动端时可以居中,所以利用媒体查询,加上下面的 css 代码。
@media (max-width: 640px) {
.intro {
margin: 7px auto;
display: block;
}
}
注意这个地方必须加上 display: block,不加之前是 inline-block,在 inline-block 条件下 auto 是不会起效果的,左右没有 margin 值。
block 元素是会占据一行的,所以 auto 可以居中,向 inline-block 并不会单独占一行,它的宽度是有限的,谈不上 auto。
加上上面的媒体查询之后,当设备宽度小于 640px 时就会圆圈就会居中显示。
现在还有一个问题是由于圆圈的数值是通过 px 单位写死的,所以无论设备的大小如何改变,圆圈的大小是不会改变的,随着设备宽度(小于640px)的变化,圆圈的大小始终是不会变化的。
这样随着设备宽度的增加,圆圈就显得比较小了,那么有没有什么方法可以使得随着设备宽度的增加,圆圈也可以随着增加呢?
可以的,通过 rem 就可以实现。
rem 是一种根据 html 的 font-size 改变动态修改值的相对单位。
我们可以通过设置媒体查询,设置几个设备宽度下不同的 html 的 font-size ,这样当设备宽度变大时,1 rem 的值也随着变大,这样就可以实现圆圈跟着变大了。
这里假设 1rem = 20px
将 css 代码中的 px 变为 rem
.container{
margin:0 auto;
max-width:800px;
border:1px solid black;
}
.intro{
display: inline-block;
width:9rem;
height:9rem;
line-height: 9rem;
text-align: center;
border-radius: 4.5rem;
border:1px solid red;
margin:.3rem;
}
@media (max-width: 375px){
html{
font-size:24px;
}
}
@media (max-width: 320px){
html{
font-size:20px;
}
}
@media (max-width: 640px) {
.intro {
margin: .3rem auto;
display: block;
}
}
注意 @media (max-width: 375px) 一定要写在 @media (max-width: 320px) 的前面,否则将会一直应用 @media (max-width: 375px) 的样式,例如 设备的宽度为 220px,这个时候两个都满足,但是由于@media (max-width: 375px) 在后面所以它设置的样式会覆盖前面的样式。
设置完后,当设备宽度为 375 时 html 的 font-size为 24px,此时 1rem = 24px(之前 1rem = 20px)所以圆圈会被放大一些。
通过上图可以看到,圆圈的大小变成了 218*218
,不再是之前的 182*182
。
注意 使用 rem 时有时计算出来的像素是不精准的,例如上例中我想令 .intro 元素的高度为 175 px,由于 1 rem = 24 px,所以 需要设置
height = 7.2916666666666666666666666666667rem
在实际应用一般不会取小数点后那么多位,假设这里取 height = 7.3 rem
所以 height 应该为 7.3 * 24 = 175.2,但是在浏览器中 height 却是 177.19 减去上下的边框等于 175.19 并不等于 175.2,所以会有一点偏差。
所以,在对像素精度要求很高的地方,使用 rem 时要格外谨慎。
完,如有不恰当之处欢迎指正哦。