我们在做响应式布局的时候,肯定要考虑到适配移动端的屏幕,大多数同学也一定复制粘贴过下面这段代码:
添加了这段代码以后,我们在移动端看到的显示效果就非常好,整个页面不会缩成一团。但是很多时候我们只是拿来用了,没有去理解这段代码究竟干了什么,为什么会影响移动端页面的布局效果,它又是怎么起作用的。今天我们就花点时间来彻底搞明白 viewport 到底是什么。
1. 单位
在讨论 viewport 之前,我们需要理解一些单位的概念:
设备像素 / 物理像素(physical pixels)
是指屏幕的实际物理像素点,比如 iPhone6 Plus 是 1920*1080 的像素分辨率,那么代表它纵向有 1920 个物理像素点,横向有 1080 个物理像素点。
CSS 像素(css pixel) / 密度独立像素(density independent pixels - dip)
CSS 像素是 web 编程中的概念,是抽象的,不是实际存在的。它是独立于设备用于逻辑上衡量像素的单位,所以又叫密度独立像素。dip 有时候也缩写为 dp 。
屏幕尺寸
指屏幕的对角线长度,单位是英寸(inch),1 英寸 = 2.54 厘米。常见屏幕尺寸有 5.0、5.5 和 6.0 等。
屏幕像素密度(pixels per inch - ppi)
指屏幕上每英寸可以显示的物理像素点的数量。比如 iPhone6 Plus 是 5.5 英寸,分辨率(也就是物理像素)是 1920*1080 像素,那么它的 ppi = √(19202+10802) / 5.5 ≈ 401ppi 。也就是说它每英寸可以显示 440 个物理像素点。
设备像素比
指物理像素和密度独立像素的比值。
window.devicePixelRatio = 物理像素 / dip。
可以通过 window.devicePixelRatio 获得,该属性被所有WebKit浏览器以及Opera所支持。
2. viewport
viewport 是指 web 页面上用户的可见区域。
viewport 的大小是和设备相关的,在移动端例如手机上,viewport 的大小是比 PC 端要小的,一般无论手机还是平板,默认的 viewport 大小都是 980px 。
刚开始 web 页面仅仅是在 PC 端进行查看的,但是后来随着移动互联网的发展,越来越多的 web 访问是通过移动端进行的,但是因为 PC 的 viewport 要比移动端大,所以为了快速修复这个问题,移动端的浏览器默认只是把整个页面等比例缩小到移动端的 viewport 大小。
这样做的后果就是,用户看到的是一个缩小版的整个页面,字体、图标和内容等等都非常小,想要点击或者查看都需要去放大页面进行操作,放大页面之后就会出现横向滚动条,这对用户体验来说是非常不好的。
那么回到我们最开始写的 meta 标签:
device-width 是指这个设备最理想的 viewport 宽度。iPhone6 之前的 device-width 都是 320px ,iPhone6 是 375px ,iPhone6 Plus 是 414px ,而这个 device-width 是和 CSS像素(也叫密度独立像素 dip)是相同的。也就是说,web 页面中的 CSS像素的值等于 device-width 时,对应到手机上就是占满全屏的宽度。
安卓手机的 device-width 有320px、360px 和 384px 等等,不同的设备 device-width 是不一样的。
initial-scale=1.0 是指初始化的时候缩放大小是1,也就是不缩放。
user-scalable=0 是指禁止用户进行缩放。
maximum-scale=1.0 是指用户最大缩放大小是1,其实在禁止用户缩放以后,这一句可以省略。
在设计人员为移动端设计页面的时候经常可以听到2倍图和3倍图这些词语,这又是什么意思呢,我们以 iPhone6 举例:
iPhone6 的分辨率(也就是物理像素)是 1334*750 像素,它的 device-width 是 375px 。
如果我们将屏幕横向分成 375 份,CSS 中 1px 占用的1份,因为屏幕就那么大,CSS中 width 等于 375px 时横向就会占满全屏,但是实际上存在的物理像素点横向是750个 ,所以在我们写 CSS 时 1px 对应到屏幕上是占用了2个物理像素点。
如果我们不写 width=device-width 这一句的话,默认 viewport 宽是 980px 。那么把 iPhone6 的屏幕横向分成980份,CSS 中 1px 占用1份,但是真正的像素点横向只有750个,这就意味着,实际上渲染出来的宽度是 75/98 个像素大小(只是理论上)。
设计人员在设计原型图的时候以 750px 的宽度为基准,我们在写 CSS的时候缩写一半来使用,但是在渲染的时候 1px 等于 2px 的物理像素,所以整个图片还是按 750px 的宽度来显示的,不会失真。
如果设计人员以 375px 的宽度为基准,那么我们在使用的时候直接把设计图中的像素宽度用在 CSS 中,那么在渲染的时候,1px 等于 2px 的物理像素,相当于图片会放大2倍,就会产生失真。
3. 总结
在添加 之后,移动端的 viewport 宽度会从默认的 980px 变成各个设备的 device-width 。
CSS 中的 100% 就等于 device-width 。
知道了这些,我们就可以结合别的知识,为页面进行响应式布局了。