前两篇博客,把像素和 viewport 的概念讲清楚了。现在开始,用 meta 标签来设置 viewport。
meta 标签
meta 标签里面的内容,主要是提供关于这个 HTML 页面的元信息的。简单点说,就是你用这些信息来告诉浏览器,应该如何解析这个 HTML 文件。比如
<meta charset="utf-8">
这个标签是告诉浏览器,该 HTML 文件的字符编码格式是 utf-8。当浏览器解析该 HTML 文件时,由于 meta 标签位于头部,会先获取到这个信息,然后浏览器就用这个 utf- 8 编码来解析这个 HTML 文件中的字符。
当然,除了上面这种简单的格式外,meta 标签更常见的是这种 name + content
的形式:
<meta name="format-detection" content="telephone=no" />
name 属性的值告诉浏览器,这个 meta 标签设置的是format-detection
,其具体值是 content 中的telephone=no
,即忽略将数字识别成电话号码。
viewport 的设置
上一篇博客的最后已经提到,我们所做的适配,就是要调整 layout viewport 的大小,而用 meta 标签就可以调整 layout viewport 的大小。上网去搜移动端适配,一定会看到下面这句代码:
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
先介绍一下这几个属性:
属性名 | 说明 |
---|---|
width | 设置 layout viewport 的宽度,为一个正整数,或字符串 width-device |
initial-scale | 设置页面的初始缩放值,为一个数字,可以带小数 |
minimum-scale | 允许用户的最小缩放值,为一个数字,可以带小数 |
maximum-scale | 允许用户的最大缩放值,为一个数字,可以带小数 |
height | 设置 layout viewport 的高度,这个属性对我们并不重要,很少使用 |
user-scalable | 是否允许用户进行缩放,值为 ”no” 或 ”yes”, no 代表不允许,yes 代表允许 |
target-densitydpi | 值可以为一个数值或 high-dpi、medium-dpi、low-dpi、device-dpi 这几个字符串中的一个。安卓中支持,当 target-densitydpi=device-dpi 时,css 中的 1px 会等于物理像素中的 1px。 |
回到应用场景,我们用这个标签的主要目的是做移动端的适配,一般都是做一个专门为移动端设计的页面。所以,我们在设置 layout viewport 时,当然希望这个 viewport 的尺寸等于 ideal viewport。
需求已经明确了,接下来看看我们如何利用上面表里的属性来实现。
利用 width
<meta name="viewport" width="device-width">
这个 width,就是用来设置 layout viewport 的宽度。我们设置其值为 device-width,也就是设置成设备的实际宽度。而 ideal viewport 的宽度是与设备的宽度相等的,所以,这句代码就把 viewport 设置成了 ideal viewport 的大小。可以分别用 window.innerWidth
和document.document.clientWidth
查看:
当然,只要你高兴,也可以设置成别的值,比如把宽度设置成 1000,那么 layout viewport 就会比 visual viewport 大,浏览时会有一个滚动条。具体实现时,代码上最好加上initial-scale=1.0
,防止浏览器对页面进行缩放。
利用 scale
<meta name="viewport" initial-scale="1.0">
Initial-scale
用来设置初次加载页面时 layout viewport 相对于 ideal viewport 的大小。具体计算公式是:
layout viewport = ideal viewport / scale
scale = ideal viewport / layout viewport
需要注意的是,利用 scale 设置,无论计算出来的 layout viewport 的值大小如何,最后都会被浏览器自动缩放到与 visual viewport 大小相等,并不会出现滚动条。具体看下面的例子,我们设置的红框大小为 100x100px,字体大小为 32px。
initial-scale=1.0
设置 scale 值为 1.0,那么 layout viewport 的大小与 ideal viewport 大小相等:
此时红框显示出来的大小就是 100px,字体大小也就是 32px。
initial-scale=0.5
设置 scale 值为 0.5,那么 layout viewport 的大小就是 ideal viewport 的两倍,即 750px:
但是浏览器会把 layout viewport 进行缩放,从而达到与 visual viewport 大小适配。对于已经是 visual viewport750px 的 layout viewport,需要缩放到以前的 0.5 倍,才能正好适配 375px。所以,100px 的红框看起来只会有 50px 的大小,字体也会对应的缩小一半。如果设计图的大小是 750px,那么样式大小完全可以按照设计图来写,最后只要设置 scale 为 0.5,视觉上的效果就是缩小后的。
这里用 window.innerWidth 打印出来的 visual viewport 大小不对,用 screen.width 打印出来是对的,具体原因网上也没查到。有知道的同学欢迎在评论区留言~
initial-scale=2.0
设置 scale 的值为 2,那么 layout viewport 的大小就是 ideal viewport 的一半,即 188px:
同样的,浏览器会自动缩放。本来是 188px 的 layout viewport,需要放大两倍,才能填满 visual viewport。此时,100px 的红框会被放大成 200px,字体大小会放大到 64px。
同时使用
width 和 scale 两种方式都可以实现,但是兼容性不同。我们的目的,是为了把 layout viewport 设置成 ideal viewport 的带下。为了能兼容所有的设备,就有了下面的方案:
<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,然后再设置缩放值为 1,就完全限制了 layout viewport 的大小为 visual viewport 了。其他的属性,都是来控制缩放的。其实,设置了 maximum-scale=1.0, minimum-scale=1.0
就相当于设置了 user-scalable=no
了。如果不禁用缩放,那么 layout 的 viewport 的大小在缩放时还是会变的。
小结
用 viewport 的目的,是为了设置 layout viewport 的大小,从而保证能在移动端设备上合适的显示出来。