01.meta viewport原理
发布于 2022年 04月 01日 14:24
什么是Viewport
手机浏览器是把页面放在一个虚拟的“窗口”(viewport)中,
通常这个虚拟的“窗口”(viewport)比屏幕宽,
这样就不用把每个网页挤到很小的窗口中(这样会破坏没有针对手机浏览器优化的网页的布局),
用户可以通过平移和缩放来看网页的不同部分。
移动版的 Safari 浏览器最新引进了 viewport 这个 meta tag,让网页开发者来控制 viewport 的大小和缩放,其他手机浏览器也基本支持。
例子
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
content内容
字段名称 | 类型 | 描述 |
---|---|---|
width | number | device-width | 控制 viewport 的宽度 |
height | number | device-width | 控制 viewport 的宽度 |
initial-scale | device-width | 初始缩放比例,也即是当页面第一次 load 的时候缩放比例 |
maximum-scale | number | 允许用户缩放到的最大比例 |
minimum-scale | number | 允许用户缩放到的最小比例 |
user-scalable | yes | no | 用户是否可以手动缩放 |
提示
如果不显示地设置viewport,那么width的默认为980。
如果页面的所有元素宽度都小于980,此时width为980,如果页面最宽的位置超过980,
那么width等于最大宽度。总之,默认能将整个页面从左到右显示出来。
如果设置了viewport,比如,只单纯地设置了user-scalable=no,
例如<meta name="viewport" content="user-scalable=no" />
,
那么ios下width还是按980显示(即默认就会通过dpi缩放),
但android和winphone下却不会再缩放了,浏览器分辨率和真实设置分辨率一致。
三种viewport
(1)layout viewport
如果把移动设备上浏览器的可视区域设为viewport的话,
某些网站会因为viewport太窄而显示错乱,
所以这些浏览器就默认会把viewport设为一个较宽的值,比如980px,
使得即使是那些为PC浏览器设计的网站也能在移动设备浏览器上正常显示。
这个浏览器默认的viewport叫做 layout viewport。
layout viewport的宽度可以通过 document.documentElement.clientWidth
来获取。
(2)visual viewport
layout viewport的宽度是大于浏览器可视区域的宽度的,
所以还需要一个viewport来代表浏览器可视区域的大小,
这个viewport叫做 visual viewport。
visual viewport的宽度可以通过 document.documentElement.innerWidth
来获取。
(3)ideal viewport
ideal viewport是一个能完美适配移动设备的viewport。
首先,不需要缩放和横向滚动条就能正常查看网站的所有内容;
其次,显示的文字、图片大小合适,
如14px的文字不会因为在一个高密度像素的屏幕里显示得太小而无法看清,
无论是在何种密度屏幕,何种分辨率下,显示出来的大小都差不多。
这个viewport叫做 ideal viewport。
ideal viewport并没有一个固定的尺寸,不同的设备有不同的ideal viewport
。
例如,所有的iphone的ideal viewport宽度都是320px,无论它的屏幕宽度是320还是640。
ideal viewport 的意义在于,无论在何种分辨率的屏幕下,针对ideal viewport 而设计的网站,
不需要缩放和横向滚动条都可以完美地呈现给用户。
css中的1px并不等于设备的1px
在css中我们一般使用px作为单位,在桌面浏览器中css的1个像素往往都是对应着电脑屏幕的1个物理像素,
这可能会造成我们的一个错觉,那就是css中的像素就是设备的物理像素。
但实际情况却并非如此,css中的像素只是一个抽象的单位,
在不同的设备或不同的环境中,css中的1px所代表的设备物理像素是不同的。
在为桌面浏览器设计的网页中,我们无需对这个津津计较,但在移动设备上,必须弄明白这点。
在早先的移动设备中,屏幕像素密度都比较低,如iphone3,它的分辨率为320x480,在iphone3上,
一个css像素确实是等于一个屏幕物理像素的。
后来随着技术的发展,移动设备的屏幕像素密度越来越高,
从iphone4开始,苹果公司便推出了所谓的Retina屏,分辨率提高了一倍,变成640x960,
但屏幕尺寸却没变化,这就意味着同样大小的屏幕上,像素却多了一倍,
这时,一个css像素是等于两个物理像素的。其他品牌的移动设备也是这个道理。
例如安卓设备根据屏幕像素密度可分为ldpi、mdpi、hdpi、xhdpi等不同的等级,
分辨率也是五花八门,安卓设备上的一个css像素相当于多少个屏幕物理像素,
也因设备的不同而不同,没有一个定论。
还有一个因素也会引起css中px的变化,那就是用户缩放。
例如,当用户把页面放大一倍,那么css中1px所代表的物理像素也会增加一倍;
反之把页面缩小一倍,css中1px所代表的物理像素也会减少一倍。
关于这点,在文章后面的部分还会讲到。
在移动端浏览器中以及某些桌面浏览器中,window对象有一个devicePixelRatio属性,
它的官方的定义为:设备物理像素和设备独立像素的比例,
也就是 devicePixelRatio = 物理像素 / 独立像素。
css中的px就可以看做是设备的独立像素,所以通过devicePixelRatio,
我们可以知道该设备上一个css像素代表多少个物理像素。例如,在Retina屏的iphone上,
devicePixelRatio的值为2,也就是说1个css像素相当于2个物理像素。
但是要注意的是,devicePixelRatio在不同的浏览器中还存在些许的兼容性问题,
所以我们现在还并不能完全信赖这个东西,
具体的情况可以看下这篇文章
参考资料: 1. 浅谈meta viewport设置移动端自适应 2. viewport 详解 讨论地址: 记录学习中遇到的问题,记录成长