# CSS3教程 - 17 视口
下面来讲解视口,以及移动端网页的适配问题。
# 17.1 像素
# 1 屏幕像素
屏幕是由一个个发光的小点构成的,这每一个小点就是一个像素。我们经常说屏幕的分辨率,例如 1920x1080
,就表示屏幕中小点的数量,横向是1920个点,纵向是1080个点。
但是相同的分辨率,屏幕的尺寸却可能是不同的。例如24寸的显示器,分辨率是 1920*1080
,一个手机屏幕是5.5寸的,分辨率也能达到 1920*1080
,因为现在的手机普遍采用高清屏,也就是高清屏的像素点更小了,肉眼根本看不见像素,显示非常清晰。
所以如果有一张 200*200
像素的图片,在某些高清屏幕上,因为像素密度更大,像素点变小,显示出的图片就会变小。例如在像素密度是标准屏幕密度的两倍的屏幕上,显示出的图片看上去就像 100*100
的。
屏幕像素也可以称为物理像素。
# 2 CSS像素
我们在开发CSS时候,设置的以像素为单位的尺寸,并不是屏幕像素,而是CSS像素。
在以前没有高清屏幕的时候,一个 CSS像素 等于 一个屏幕像素。但是现在因为高清屏幕的原因,一个CSS像素可能需要多个屏幕像素来显示。浏览器在显示网页的时候,需要将CSS像素转换为屏幕像素进行显示。
所以这里涉及到一个概念,就是设备像素比(DPR),在标准屏幕(DPR = 1)上,1 CSS像素 等于 1 物理像素。但是在高 DPI 屏幕(例如 Retina 屏幕,DPR = 2)上,1 CSS像素的宽度对应 2个屏幕像素的宽度,那么一个 CSS像素需要4个屏幕像素显示(宽高2*2=4
)。
CSS像素也可以称为逻辑像素。
# 17.2 视口
视口(viewport)就是浏览器中用来显示网页的区域。通过查看网页的 <html>
标签的宽度,可以知道视口的大小。
默认情况下,通过移动端访问网页,视口的大小都是 980px (CSS像素),即使手机的尺寸不同,但是宽度都是 980 个CSS像素。
例如我们写一个网页如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--
<meta name="viewport" content="width=device-width, initial-scale=1.0">
-->
<title>Document</title>
</head>
<body>
<div class="box1">www.foooor.com</div>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
- 就是一个普通的网页,VSCode 自动生成的,但是注意,需要将上面
viewport
的<meta>
去掉,这个是用来适配移动端的。
此时使用浏览器的开发者工具,使用移动端模式来查看网页,可以看到不管选择什么设备,视口宽度都是 980px:
需要注意,现在的很多网页都是针对移动端单独开发的页面,使用移动端和PC端访问是不同的页面,那么就不是这个值了。
所以说,在移动端浏览器都会将视口设置为 980 个CSS像素,以保证PC端的网页可以在移动端正常显示,如果网页的宽度超过了 980 像素,那么移动端的浏览器会自动对网页进行缩放,以保证完整显示网页的内容。
但是如果不针对移动端进行适配,通过移动端来访问网页,体验往往很差,因为屏幕太小了,显示完整的网页后,内容基本看不清,需要手动放大查看局部信息。所以大部分网站都针对移动端单独设计网页,PC端和手机端访问的是不同的网页。
通过移动端查看网页,设备像素比 = 设备屏幕宽度像素 / 980CSS像素(视口宽度)
,如果设备屏幕宽度是 1960 像素,那么设备像素比就是 2 。也就是1个CSS像素需要2个屏幕像素来显示(只说宽度方向上)。
所以我们要编写移动端页面,首先需要调整设备像素比,根据上面的公式,屏幕像素是无法调整的,只能调整视口宽度,如果降低视口宽度,那么设备像素比就变大了,一个CSS像素就需要更多的屏幕像素来显示,那么元素就会变大了。
在 HTML 中通过 <meta>
标签来设置视口的宽度。
举个栗子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- 设置视口的宽度为 400 CSS像素 -->
<meta name="viewport" content="width=400px">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
.box1 {
width: 200px;
height: 200px;
background-color: skyblue;
}
</style>
</head>
<body>
<div class="box1"></div>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
- 在上面设置了视口的宽度为 400 CSS像素;
- 然后设置了 box1 的尺寸为 200 CSS 像素,那么此时box1 宽度为屏幕的一半。
显示如下:
操作的时候注意一下,保证上面显示的时候,屏幕水平和垂直都没有滚动条,如果有滚动条,通过
浏览器->显示
,重置一下显示比例。
# 17.3 完美视口
好了,现在思路已经有了,要想网页在移动端显示正常,就需要调整视口的宽度,保证 CSS 像素对应合理的屏幕像素。
不同的设备,屏幕尺寸和像素是不一样的,那么视口的宽度应该设置为多少呢?
每一款移动设备在设计时,都会有一个最佳的设备像素比,一般我们只需要将像素比设置为最佳像素比,就可得到一个最佳效果。所以只需要将视口宽度设置为最佳像素比对应的视口大小,就能得到完美视口。
网页中提供了一个变量 device-width
表示设备的完美视口宽度:
<-- 将网页的视口设置为完美视口 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
2
device-width
代表的是 逻辑像素(CSS 像素),而不是物理像素(屏幕像素)。假设有一台设备的物理屏幕宽度是 1920 像素,DPR = 2,那么浏览器会把 device-width
设为 960 像素,这是因为设备像素比为 2,浏览器会将每 2 个物理像素映射到 1 个 CSS 像素。如果 DPR = 3,那么 device-width
将是 640 像素。
所以以后写移动端的页面,需要添加上面的 <meta>
元数据标签,以实现完美视口。 initial-scale=1.0
是保证页面一开始不被缩放。
# 17.4 vw单位
在不设置网页视口宽度的时候,默认是 980 CSS像素,但是设置了完美视口以后,不同的设备视口宽度是不同的。
例如:
- iPhone12 Pro 完美视口宽度是 390 CSS像素
- iPhone14 Pro Max 完美视口宽度是 430 CSS像素
所以开发移动端页面,如何让网页在不同的设备上显示效果差不多,就不能直接用 px
了,因为设备的屏幕宽度是不同的。
例如 390px 在 iphone12 是全屏,在 iphone14 就短一些了,你说可以设置百分比,但是也不能所有的元素都全部使用百分比来设置吧。
# 1 vw
下面介绍一个新单位 vw
,vw
表示的是视口的宽度(viewport width)
100vw = 整个视口的宽度
;1vw = 1%视口宽度
;
vw
是相当于视口宽度进行计算的,在移动端可以使用 vw
单位。
举个栗子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
.box1 {
width: 20vw;
height: 20vw;
background-color: skyblue;
}
</style>
</head>
<body>
<div class="box1"></div>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- 上面设置 box1 的尺寸为
100vw
,这样在不同的设备上,显示效果是差不多的。
# 2 设计图宽度
上面说在移动端可以使用 vw
来定义元素的尺寸,但是设计师在给我们设计图的时候,图片是像素单位的。
如何转换为对应的 vw
值呢?
现在常见的设计图的宽度有:
750px
:是375px
的两倍,iPhone 很多早期设备完美视口的宽度都是375px
。1125px
:是375px
的三倍。
因为设备是高清屏幕,如果 375 像素的图片显示为 375 CSS像素,会很模糊,所以需要针对设备设计高清的图,也就是两倍三倍尺寸的图片,这样在设备像素比为2或3的设备上,显示才正常清晰。
所以如果一个设计图宽度为 750px
,设计图中一个 48px × 35px
大小的元素,使用 vw
来表示,值是多少呢?
100vw = 750px
,那么 1px = 0.1333...vw
,由此计算:
48px = 6.4vw
35px = 4.667VW
# 3 rem
设计图宽度为 750px
的情况下,通过上面的 1px = 0.1333...vw
的关系,来将 px
换算得到 vw
的值,这个操作有点麻烦。
有什么好方法吗?
在以前讲单位的时候,说过 rem
是相对于根元素的字体大小来计算的,1rem = 1个html的字体大小
,我们可以将 html的字体大小
定义为 0.1333333333333333
,然后使用 rem
作为元素的尺寸单位,这样岂不就可以了。
但是有一个问题,就是浏览器支持最小字体是 12 像素(0除外),不能设置一个比 12 像素还小的字体,所以 rem
的最小设置只能为 12px
(0除外),所以没办法,那么只能设置 rem
为 0.1333333333333333
的倍数,例如放大 40 倍(放大10倍不够),这样 1rem = 40px
,这样好换算一些。
举个栗子:
在一个宽度为 750px
的设计图中,有一个元素宽度为 100px
,就可以设置它的宽度为 100 / 40 = 2.5rem
。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
html {
font-size: 5.3333333333vw;
}
.box1 {
width: 2.5rem; /* x40,是100像素 */
height: 2.5rem;
background-color: skyblue;
}
</style>
</head>
<body>
<div class="box1"></div>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
- 上面设置 html 的字体大小为
5.3333333333vw;
,这样 2.5rem = 2.5 * 40 = 100px。
显示如下: