在前端开发过程中,静态网页通常需要适应不同分辨率的设备,常用的自适应解决方案包括媒体查询、百分比、rem
、和vw
/vh
,本文主要分析px
在移动端布局中的不足,以及几种不同的自适应解决方案
一、px
和视口
一般情况下,我们写网页时最常用来描述长宽的单位是像素(px
),在pc
端,通常认为css
中,1px
表示的真实长度是固定的
其实并不是这样,px
是与设备有关的,例如font-size为16px
的时候,在pc
端和移动端的大小是不一样的
所以,css
中1px
的真实长度是由什么决定的呢? 首先我们要先知道像素和视口分别是什么
1、像素
像素是网页布局的基础,一个像素表示了计算机屏幕所能显示的最小区域,像素又分为两种,css
像素和物理像素。css
像素是为web开发者提供,在css
像素中使用的一个抽象单位;物理像素则是只与设备的硬件密度有关,任何设备的物理像素都是固定的
为了明确css
像素和物理像素的转换关系,必须先了解视口是什么。
2、视口
广义的视口是指浏览器显示内容的区域,狭义的视口包括了布局视口、视觉视口和理想视口
(1)布局视口
布局视口是pc
网页在移动端的默认布局行为,因为通常pc
的分辨率较大,布局视口默认为980px
。也就是说不设置网页的viewport
的情况下,pc
端的网页默认以布局视口为基准,在移动端进行展示。
(2)视觉视口
视觉视口是浏览器内看到的网站的显示区域,用户可以通过缩放来查看网页的内容,从而改变视觉视口。视觉视口的定义相当于拿着一个放大镜分别从不同距离观察同一个物体,视觉视口仅仅类似于放大镜中显示的内容,因此视觉视口不会影响布局视口的宽度和高度。
(3)理想视口
理想视口就是给定设备物理元素的情况下,最佳的“布局视口”
分辨率和物理像素之间有什么联系呢,通过一个用DPR
设备像素比来表示,则可以写成:
DPR = 物理像素/分辨率
在不缩放的情况下,一个css
像素就对应一个dpr
,也就是说,在不缩放的情况下:
CSS像素 = 物理像素/分辨率
在移动端的布局中,我们可以通过viewport
元标签来控制布局,比如一般情况下,我们可以通过下述标签使得移动端在理想视口下布局:
<meta id="viewport" name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1; user-scalable=no;">
width=device-width;
一般表示分辨率的宽,通过这个设置,我们就将布局视口设置成了理想的视口
属性名 | 取值 | 描述 |
---|---|---|
width | 正整数 | 定义布局视口的宽度,单位为像素 |
height | 正整数 | 定义布局视口的高度,单位为像素,一般不使用 |
initial-scale | [0,10] | 初始化缩放比例,1表示不缩放 |
minimum-scale | [0,10] | 最小缩放比例 |
maximum-scale | [0,10] | 最大缩放比例 |
user-scalable | yes/no | 是否允许手动缩放页面,默认值为yes |
3、px
与自适应
不同的移动设备分辨率是不同的,也就是说,一个css
像素可以表示的物理像素是不同的,因此如果在css
中仅仅通过px
作为长度和宽度的单位,造成的结果是无法通过一套样式实现各端的子适应
二、媒体查询
@media媒体查询是针对不同的媒体类型定义不同的样式,特别是响应式页面,可以针对不同屏幕的大小,编写多套样式,从而达到自适应效果
@media screen and (max-width: 960px){
body{
background-color:#6633FF;
}
}
@media screen and (max-width: 768px){
body{
background-color:#00FF66;
}
}
/*
通过max-width设置样式生效时的最大分辨率,上述的代码分别对分辨率在0~768px以及768px~960px的屏幕设置了不同的背景颜色。
*/
通过媒体查询可以给不同分辨率的设备编写不同的样式来实现响应式,但媒体查询的缺点也是非常明显的,当浏览器大小改变时,需要改变的样式太多了,就是就好多套样式的代码,显得很复杂
三、百分比
我们也可以用百分比来实现响应式效果,具体效果是当浏览器大小的改变的时候,通过百分比单位可以使浏览器中的组件宽和高随着浏览器的变化而变化。
最重要的一个问题就是css
中,子元素的百分比到底是谁的百分比
一般情况下,我们最先想到的就是完全相当于父元素,这个想法是正确的,但是对于css
盒式模型,除了height、width属性外,还具有padding、border、margin等等属性。
1、具体分析
接下来我们结合例子来说明
<div class="box1">
<div class="box2"></div>
</div>
.box1{
width: 200px;
height: 150px;
background-color: darkseagreen;
}
(1)子元素height和width的百分比
当只有width和height属性的时候
.box2{
width: 50%;
height: 50%;
background-color: darkslategray;
}
运行效果:
(2)top和bottom 、left和right
子元素默认定位的情况下,设置top
和bottom
的百分比时,是相对于父元素的高度,设置left
和right
的百分比时,是相对于父元素的宽度
.box2{
width: 80px;
height: 60px;
position: relative;
top: 50%;
bottom: 50%;
left: 50%;
right: 50%;
background-color: darkslategray;
}
运行结果如下:
(3)padding
/ margin
当padding
设置百分比的时候,不论是垂直方向还是水平方向,都只相对于直接父元素的width
,margin
和padding
类似
.box2{
width: 80px;
height: 60px;
position: relative;
/*padding-left和padding-top均为60px,因为父元素的width为200px*/
padding-left: 30%;
padding-top:30%;
background-color: darkslategray;
}
运行结果:
(4)border-radius
这个是圆角属性,如果设置百分比是相对于子元素自身的宽度
.box2{
width: 80px;
height: 80px;
position: relative;
border-radius: 50%;
background-color: darkslategray;
}
运行结果:
### 2、百分比单位布局的应用
我们要设置一个固定的长宽比的长方形时,我们可以通过padding
属性来实现。因为padding
不管是垂直方向还是水平方向,百分比单位都相对于父元素的宽度,因此可以设置padding-top
为百分比实现长宽自适应的长方形。
<div class="box1"></div>
.box1{
width: 600px;
height: 0;
padding-top:40%;
background-color: darkseagreen;
}
/*任意缩放,盒子大小改变,高度比例不变*/
四、自适应场景下的rem
1、rem
单位
rem
是一个灵活的可扩展的单位,由浏览器转化像素并显示。与em单位不同,rem
单位无论嵌套层级如何,都只相对于浏览器的根元素(HTML元素)的font-size。默认情况下,html
元素的font-size为16px
为了计算方便,通常也可以这样设置
html{
font-size:62.5% }
这种情况下,1rem=10px
2、rem
布局的缺点
在响应式布局中,必须通过js
来动态控制根元素font-size
的大小。
也就是说css
样式和js
代码有一定的耦合性。且必须将改变font-size
的代码放在css
样式之前。
五. 通过vw
/vh
来实现自适应
css3
中引入了一个新的单位vw
/vh
,与视图窗口有关,vw
表示相对于视图窗口的宽度,vh
表示相对于视图窗口高度
vh
和 vw
就是根据窗口的宽高,分成100等份,100vh
就表示满高,50vh
就表示一半高