我在无意中看到这样一个专题页http://action.weixin.qq.com/payact/readtemplate?t=mobile/2015/wxzfsht/index_tmpl,正好我看了一下它的代码,我看到它的图片设置的都是px单位,我就想px单位怎么做自适应呀,然后我就调整浏览器测试窗口的大小,发现完美适配,我又像是不是js动态控制窗口文档大小了,但是html上面也没有行内样式fontsize的变化,因此它并没有使用基于字体的rem方案。我当时就纳闷了,这是什么神奇的技术,如此厉害。我仔细看了一下,发现它的meta标签写的和我们平时不一样,<meta name="viewport" content="width=750, user-scalable=no, target-densitydpi=device-dpi">,意思是这个网页基于750宽的布局视口来做,浏览器根据移动设备的虚拟视口的不同去动态缩放布局视口以使两个视口保持一致。
viewport是一个浏览器级别的概念,它是存放html文档的上一级容器,从字面上理解视口,我们观看网页的窗口,这个窗口的越大,我们能够看到的内容就越多,就像大的显示器比小的显示器呈现的内容多是一个道理。PC端和移动端的viewport差别比较大,我们先从PC端的viewport入手,下面是我总结的几个关于PC端viewport的要点
- viewport的功能在于控制你网站html元素的大小(如果你没有对html设置宽度的情况下),viewport是html的父级容器,比如html的宽用css设置为100%,那么这个100%计算的依据就是viewport的宽度,及浏览器可视区的宽度。viewport可以限制html,但是html控制不了viewport,因此在PC端开发网页的时候我们其实并不关心viewport。
- PC端的viewport始终与浏览器的可视区大小一致。它会随着浏览器窗口的变大而变大,缩小而缩小,并且不能通过css去修改,viewport的大小可以通过window.innerWidth和window.innerHeight获得,整个html文档可以通过document. documentElement. offsetWidth/Height获得宽和高;
- PC端的CSS像素与电脑系统设置的分辨率单位保持一一对应。如果系统分辨率与物理分辨率一一对应,那么CSS单位与物理分辨率也一一对应,我们其实不用关心物理像素,只关注CSS像素即可;
只看文字可能有点不好理解,我喜欢用图片表达我所说的,
在移动端视口就稍微复杂一些。我们假设在移动端依然采用PC端的方案(下图左),视口与移动端可以去屏幕大小完全一致,那用户看到的网页内容就会非常少,用户就会拖动网页查看,体验非常的不好。由此在移动端引入了虚拟视口和布局视口。
我们可以这样理解这两个概念,布局视口是真实网页的大小,比如一张图片,虚拟视口犹如一个查看图片的窗口,这个窗口和手机屏幕的可视区一致,我们如果想看到完整的图片大小必须移动窗口与图片的距离,相当于用户对网页的缩放。在我们不对viewport进行设置的情况下,移动端会自动缩放布局视口以适应虚拟视口,避免出现滚动条。这个落地页也正是利用了浏览器自动缩放的原理,它以75px宽为基准,也就是iphone6的大小为标准制作,然后让移动端浏览器自动根据自己的虚拟视口去缩放匹配,避免了我们自己维护的麻烦。
补充一下
meta viewport 有6个属性(暂且把content中的那些东西称为一个个属性和值),如下:
width | 设置layout viewport 的宽度,为一个正整数,或字符串"width-device" |
initial-scale | 设置页面的初始缩放值,为一个数字,可以带小数 |
minimum-scale | 允许用户的最小缩放值,为一个数字,可以带小数 |
maximum-scale | 允许用户的最大缩放值,为一个数字,可以带小数 |
height | 设置layout viewport 的高度,这个属性对我们并不重要,很少使用 |
user-scalable | 是否允许用户进行缩放,值为"no"或"yes", no 代表不允许,yes代表允许 |
这些属性可以同时使用,也可以单独使用或混合使用,多个属性同时使用时用逗号隔开就行了。
此外,在安卓中还支持 target-densitydpi 这个私有属性,它表示目标设备的密度等级,作用是决定css中的1px代表多少物理像素
target-densitydpi | 值可以为一个数值或 high-dpi 、 medium-dpi、 low-dpi、 device-dpi 这几个字符串中的一个 |
特别说明的是,当 target-densitydpi=device-dpi 时, css中的1px会等于物理像素中的1px。
因为这个属性只有安卓支持,并且安卓已经决定要废弃target-densitydpi 这个属性了,所以这个属性我们要避免进行使用 。