Viewport 概念#
三个视口#
- 布局视口
- 本文的重点,meta 属性设置的对象。
- 布局视口 可以理解为 包含整个页面的区域,所以布局视口可能比可视区域还要大。
- 视觉视口
- 理想视口
- 移动端浏览器还有一个理想视口的概念。其宽度就是 下文提到的 理想视口宽度
- 布局视口的默认宽度并不是一个理想的宽度,大家从上面的图就可以看出来了,所以苹果公司就引进了理想窗口这个概念。
- 理想视口就是 最理想的布局视口的尺寸。将布局视口设置成理想视口,页面就能够适应到合适的尺寸,用户就不再需要自己去缩放和拖动网页了。
- 在 移动端,只有布局视口和理想视口一样大时,移动端显示在和 PC 预期一样,否则浏览器会缩放(不是修改布局视口,而是将整个内容缩小或放大),以适应移动端显示。从而导致了移动端字体过小等问题。Î
以下 viewport 默认指的是布局视口#
- 通俗的讲,viewport 就是 html 的 外层区域,在使用百分比布局时,html 设置 width:100%就是根据 viewport 宽度来的,所以 viewport 可以 理解为 html 的父素。
默认 viewport 的宽度#
initial-scale#
- 而 viewport 还有一个 initial-scale 的概念,这个 initial-scale 是一个数值,用于记录 理想视口宽度 / viewport 宽度 的值。即 initial-scale = 理想视口宽度 / viewport 宽度 。
- 而每个设备的 理想视口宽度 又是固定的,所以通过设置 initial-scale 就可确定 viewport 的值。
- initial-scale 默认值:
- 根据测试,在 iphone 和 ipad 上,你给 viewport 设置的宽度后,而又没有指定初始的缩放值的话,iphone 和 ipad 会自动计算 initial-scale 这个值: 当前缩放值 = 理想视口宽度 / viewport 宽度
看下效果#
代码:#
<body>
<p class="title">My Title</p>
<p class="content">
Apple documentation: Using the Viewport Meta Tag Mozilla: Using the viewport
meta tag to control layout on mobile browsers quirksmode.org: A tale of two
viewports w3.org Mobile Web Application Best Practices: Use Meta Viewport
Element To Identify Desired Screen Size Quick Tip: Never use
maximum-scale=1.0 on the A11y Project Tim Kadlec explains IE10 Snap Mode and
Responsive Design The @viewport rule proposal
</p>
</body>
PC 端 Chrome 显示效果:#
- width:775px
移动端不加 meta 的 Viewport 标签:#
- width:980px(iPhone6 的viewport 的默认宽度为 980px)
移动端加 meta 的 Viewport 标签:#
- head 添加 标签 :
<meta name="viewport" content="initial-scale=1.0">
- width:375px (iphone6 设备的 理想视口宽度 为 375px,所以
viewport = 375px / 1
, 参考initial-scale)
差别#
- 使用了
initial-scale=1.0
之后,浏览器的 viewport 从默认的 980px 变为 理想视口宽度 375px 的 1:1 关系的宽度 375px - 设置
initial-scale=2.0
后 viewport 变为375px/2=187px
- 可见
viewport宽度 = 理想视口宽度 / initial-scale值
关于缩放#
手机上放大,视觉视口缩小,布局视口不变,所以我们看到的 css 布局是不变的。
PC 上放大,视觉视口缩小,由于 PC 的布局视口和视觉视口是相同的,所以布局视口也变小,这就是我们在桌面端缩放的时候样式有时候会错乱的原因。
据说移动端 css 布局不改变也是因为移动端进行重绘的成本太高
布局视口的大小#
下面根据页面的解析过程来说明一下,浏览器在页面布局时的计算 viewport 的流程:
没有 viewport
- 当页面没有声明 viewport 时,手机浏览器会取 980px 作为默认 viewport 的 width 值(IE/BlackBerry:1024px),然后全部显示,所以 默认的 scale 值 = 理想视口宽度 / 默认 viewport 宽度 。
存在 viewport
当页面声明了 viewport 标签时,存在以下情况:
- 仅对于
width=device-width
,则 viewport 的宽高采用 理想视口 的尺寸(iPhone,iPad 横屏时宽度是 理想视口 的宽度,而非高度) - 仅对于
initial-scale=1
,则 viewport 的宽高采用 理想视口 的尺寸( IE 横屏时宽度是 理想视口 的宽度,而非高度) - 单独设置
width=x
或者initial-scale=x
时,可以通过 width 直接获得或者通过 initial-scale(理想视口宽度/initial-scale)计算出 viewport 的尺寸,需要注意的是 viewport 是有范围的(最小: 1/5 * 理想视口宽度),所以当超出尺寸范围时,浏览器会选择相应的最大值或者最小值。 - 如果 width 和 initial-scale 都存在时,会根据 initial-scale 计算出来的结果(理想视口宽度/initial-scale)与 width 值进行比较,取较大的值。(而 Android Webkit 则采用 width 值,IE 永远认为
initial-scale=1
,但是需要注意 layout 的取值范围)。
javascript 相关#
厂商间基本遵循的规范:
document.documentElement.clientWidth
: 表示 布局窗口宽度,可进行类似媒体查询;window.innerWidth
:表示 视觉窗口宽度,一般不会用;screen.width
: 表示 理想窗口宽度,兼容性据说差别很大;一般没啥用;orientationchange
事件,只要设备改变了方向都会触发,兼容性好;- 移动端最好不要用
resize
事件,支持很差;
可以通过 js 模拟类似 media 查询的功能,在布局足够宽的时候才加载某些第三方组件:
if (document.documentElement.clientWidth >= 600) {
// 加载组件
}
总结#
- 影响显示排版的是布局视口,布局视口变了,整个页面排版位置才会改变。
- 一般移动端进行适配:
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">
,width=device-width, initial-scale=1
可以确保大部分设备上 viewport 的宽度和理想宽度一致。 - 可以 利用 js 获取布局视口大小,进一步设置,适配出自己想要的效果。