基本知识
# 基本知识
# 视
视口(viewport)就是浏览器显示页面内容的屏幕区域。最先由 Apple 引入,用于解决移动端页面的显示问题,通过一个叫 <meta>
的 DOM 标签,允许我们可以定义视口的各种行为,比如宽度,高度,初始缩放比例等,视口可以分为布局视口、视觉视口和理想视口。
# 布局视口 layout viewport
一般移动设备的浏览器都默认设置了一个布局视口,用于解决早期的 PC 端页面在手机上显示的问题。
layout viewport
是一个固定的值,由浏览器厂商设定,
- IOS 和 Android 基本都是 980px
- 黑莓(BlackBerry)和 IE10 是 1024px
- 在 PC 端上,布局视口等于浏览器窗口的宽度
所以 PC 上的网页大多都能在手机上呈现,只不过元素看上去很小,一般默认可以通过手动缩放网页。
而在移动端上,由于要使为 PC 端浏览器设计的网站能够完全显示在移动端的小屏幕里,此时的布局视口会远大于移动设备的屏幕,就会出现滚动条。
|
|
# 视觉视口 visual viewport
- 字面意思,它是用户正在看到的网站的区域。注意:是网站的区域。
- 我们可以通过缩放去操作视觉视口,但不会影响布局视口,布局视口仍保持原来的宽度。
用户正在看到的网页的区域。用户可以通过缩放来查看网站的内容。如果用户缩小网站,我们看到的网站区域将变大,此时视觉视口也变大了,同理,用户放大网站,我们能看到的网站区域将缩小,此时视觉视口也变小了。不管用户如何缩放,都不会影响到布局视口的宽度。
|
|
# 理想视口 ideal viewport
现在已经有两个 viewport 了,但浏览器觉得还不够,因为现在越来越多的网站都会为移动设备进行单独的设计,所以必须还要有一个能完美适配移动设备的 viewport。
所谓的完美适配指的是:
- 不需要用户缩放和横向滚动条就能正常的查看网站的所有内容
- 显示的文字的大小是合适,比如一段 14px 大小的文字,不会因为在一个高密度像素的屏幕里显示得太小而无法看清,理想的情况是这段 14px 的文字无论是在何种密度屏幕,何种分辨率下,显示出来的大小都是差不多的,当然,不只是文字,其他元素像图片什么的也是这个道理。
这个 viewport 叫做 ideal viewport(理想视口),window.screen.width
我们可以通过 meta
设置将布局视口转换为理想视口,
|
|
# meta 视口标签
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
属性 | 解释 |
---|---|
width | 正整数|device-width,视口宽度,单位是 CSS 像素,如果等于 device-width,则为理想视口的宽度 |
height | 正整数|device-height,视口宽度,单位是 CSS 像素,如果等于 device-height,则为理想视口的宽度 |
initial-scale | 0-10,初始缩放比例,允许小数点 |
maximum-scale | 0-10,最大缩放比例,必须大于等于 minimum-scale |
minimum-scale | 0-10,最小缩放比例,必须小于等于 maximum-scale |
user-scalable | yes/no,是否允许用户缩放页面,默认是 yes |
# 常用单位
# 物理像素
设备屏幕实际拥有的像素点,屏幕的基本单元,是有实体的。比如 iPhone 6 的屏幕在宽度方向有 750 个像素点,高度方向有 1334 个像素点,所有 iPhone 6 总共有 750*1334 个像素点。同一个设备的物理像素是固定的,这是厂商在出厂时就设置好了的。
屏幕普遍采用 RGB 色域(红、绿、蓝三个子像素构成),而印刷行业普遍使用 CMYK 色域(青、品红、黄和黑)。
# 逻辑像素
也叫“设备独立像素”(Device Independent Pixel,DIP),可以理解为反映在 CSS/JS 程序里面的像素点,也就是说 css 像素是逻辑像素的一种。除了 css 像素是逻辑像素以外,我们平时描述一张图片宽高时一般用 200px * 100px
,这里的px
也是逻辑像素。
# 设备像素比(Device Pixel Ratio,DPR)
在很久以前,CSS 里写个 1px
,屏幕就给你渲染成 1 个实际的像素点,即 DPR=1。
后来苹果公司为其产品 mac、iPhone 以及 iPad 的屏幕配置了 Retina 高清屏,也就是说这种屏幕拥有的物理像素点数比非高清屏多 4 倍甚至更多。如果还按照 DPR=1 进行展示,那么同一张图片在高清屏上面显示的区域面积会是非高清屏的 1/4,这样的话由于图片在屏幕上的展示面积大大缩小,也会导致出现“看不清”的问题。
因此苹果使用 4 个乃至更多物理像素来渲染 1 个逻辑像素,这样一来,同样的 CSS 代码设置的尺寸,在 Retina 和非 Retina 屏幕上看起来大小是一样的,但在 Retina 屏幕上要精细得多。

在 Retian 屏上,DPR 不再是 1,而是大于 1,比如 2(iPhone 5 6 7 8)或 3(iPhone 6 Plus 等一系列 Plus)或者为非整数(一些 Android 机),说不定还会涨。
举个例子:iPhone 6 的物理像素上面已经说了,是 750 _ 1334,那它的逻辑像素呢?我们只需在 iPhone 6 的 Safari 里打印一下screen.width
和screen.height
就知道了,结果是 375 _ 667,这就是它的逻辑像素,据此很容易计算出 DRP 为 2。当然,我们还可以直接通过window.devicePixelRatio
这个值来获取 DRP,打印结果是 2,符合我们的预期。
PS:在苹果的带动下,Retina 技术在移动设备上已经成了标配,所以前端攻城狮必须直面如下事实:
|
|
这就是初级前端面试必考题之“1px 边框问题”的由来。
# EM
EM 相对于元素自身的 font-size
,
|
|
如果元素没有显式地设置 font-size
,那么 1em
等于多少呢?
这个问题其实跟咱说的 em
没啥关系,这里跟 font-size
的计算规则相关,回顾一下。如果元素没有设置 font-size
,会继承父元素的 font-size
,如果父元素也没有,会沿着 DOM 树一直向上查找,直到根元素 html
,根元素的默认字体大小为 16px。
# REM
REM = Root EM,顾名思义就是相对于根元素的 EM。所以它的计算规则比较简单,
1 rem
就等于根元素 html
的字体大小,
|
|
所以,如果我们改变根元素的字体大小,页面上所有使用 rem
的元素都会被重绘。
EM 和 REM 都是相对单位,我们在做响应式布局的时候应该如何选择呢?
根据两者的特性,
- EM 更适合模块化的页面元素,比如 Web Components
- REM 则更加方便,只需要设置
html
的字体大小,所以 REM 的使用更加广泛一些
实际开发中,设计图的单位是 CSS 像素,我们可以借助一些工具将 px 自动转换为 rem,下面是一个用 PostCSS
插件在基于 Webpack 构建的项目中自动转换的例子:
|
|
# vw,vh,百分比
浏览器对于 vw
和 vh
的支持相对较晚,在 Android 4.4 以下的浏览器中可能没办法使用,下面是来自 Can I use 完整的兼容性统计数据,

新生特性往往逃不过兼容性的大坑,但是这并不妨碍我们了解它。
响应式设计里,vw
和 vh
常被用于布局,因为它们是相对于理想视口:
- vw,viewport width,视口宽度,所以 1vw = 1% 视口宽度
- vh,viewport height,视口高度,所以 1vh = 1% 视口高度
以 iPhoneX 为例,vw 和 CSS 像素的换算如下,
|
|
我们说百分比也可以用来设置元素的宽高,它和 vw
,vh
的区别是什么?
这里只需要记住一点,百分比是相对于父元素的宽度和高度计算的。
# 二倍图
- 对于一张 50px * 50px 的图片,在手机 Retina 屏中打开,按照刚才的物理像素比会放大倍数,这样会造成图片模糊
- 在标准的 viewport 设置中,使用倍图来提高图片质量,解决在高清设备中的模糊问题
- 通常使用二倍图, 因为 iPhone 6\7\8 的影响,但是现在还存在 3 倍图 4 倍图的情况,这个看实际开发公司需求
- 背景图片也注意缩放问题
|
|
# 媒体查询
媒体查询(Media Query)是 CSS3 规范中的一部分,媒体查询提供了简单的判断方法,允许开发者根据不同的设备特征应用不同的样式。响应式布局中,常用的设备特征有,
- min-width,数值,视口宽度大于
min-width
时应用样式 - max-width,数值,视口宽度小于
max-width
时应用样式 - orientation,
portrait
|landscape
,当前设备的方向
选择 min-width
和 max-width
取值的过程,称为设备断点选择,它可能取决于产品设计本身,下面是 百度 Web 生态团队 总结的一套比较具有代表性的设备断点,
|
|