假设我们规定了 CSS 像素值需要与设备像素大小相等,但当随着手持设备距离人的远近不同,设备像素密度的不同,都会导致我们看见的设备上的 CSS 像素的可见大小发生变化(类似于巨大的月亮因为离地球遥远在人眼看来也不过像硬币一样大小)。为了保证 CSS 像素在不同设备和不同距离上观测到的大小保持一致保持连贯性。W3C 定义了一个 CSS 相对像素(CSS reference pixel)的概念。
W3C 规定,把人眼能够辨别到的,距离自己一个手臂长度(约 28 英寸),像素密度为 96dpi 设备上的一个物理像素设为参考像素。所以我们可以算出眼睛看到参考像素的视野角度为 0.0213 度:
![](http://cndpic.dodoke.com/632b46072b57e6c962283451052aeed8)
有了这一系列参照,通过三角函数关系,我们可以算出同样一台设备在不同距离下 CSS 像素理想的大小。 当远离观察者时像素应该增大,当靠近观察者时像素应该减小:
![](http://cndpic.dodoke.com/809cd4a899438ebd56ad5413fc610886)
这么做的优势在于无论设备距离观察者距离是多少,也无论设备的像素密度和物理像素大小是多少,观察者看到的 CSS 像素是一致的,保证了用户体验的一致性:
![](http://cndpic.dodoke.com/b72a6926cf5c15c74dc567597e27358b)
我们有了物理像素,CSS 像素——那么问题来了,当你在手机上使用浏览器打开网页时,网页应该按照哪一种宽度进行渲染?
此时我们需要了解一个概念:viewport,常见到的中文译为视口。
假设 body 标签内有一个块状元素宽度为 10%:`div {width:10%;}`,我们知道当我们缩放浏览器时这个块状元素的宽度也会跟着变化。 这是因为它的宽度占它父元素的 10%。那么它的父元素,也就是 body 元素的宽度是由谁决定的呢?
我们知道一个块状元素默认宽度为它父元素的 100%,也就是 body 元素的宽度与包裹它的 html 元素宽度相同。那么问题又变成了 html 元素的宽度是由谁决定的?
答案是浏览器窗口。现在我们可以归纳起来,html 元素是被浏览器限制并且包裹起来的。html 的宽度就是浏览器的宽度。
但事实上,html 元素宽度是占据 viewport 的 100%,而在桌面浏览器中,viewport 与浏览器窗口大小刚好相等。
OK,在于是我们得到了一个结论,html 宽度是由 viewport 决定的,但是 在桌面浏览器中,viewport 大小与浏览器窗口大小相等。
但这一套规则在手机则是无法被执行的。大部分手机的屏幕分辨率目测只有 400px,如果页面上真的有某一个页面元素仅占 10%,也就是 40px 的话,肉眼几乎是无法分辨的。实际情况应该会更糟糕,iPhone4 的 Safari 默认是以 980px 来渲染网页的。
第一个办法,放大页面。我们会很习惯的用手势去放大页面。但是要注意我们这里做的仅仅是放大页面,改变的是页面的缩放 (scale),效果与 PC 上浏览器的类似。但是没有改变页面的布局,此时用于渲染页面布局的 layout 仍然是 980px。
第二个办法是,改变布局。比如一个页面上有一张 320px 宽的图片,如果我们以默认的 980px 去渲染的话,它会显得过于窄小。
![](http://cndpic.dodoke.com/8b0caa04be4ec155d251621a89686537)
但如果我们可以将渲染它的布局设为 320px 的话,看上去就会好很多了,同时此时我们也未对页面进行缩放:
![](http://cndpic.dodoke.com/e6b33c560db9232d0969e7ff4fa83829)
在 320px 的像素下,我们可以对页面进行缩放:
![](http://cndpic.dodoke.com/d1ea3acae05dc3e3f67df704f86e7633)
回归到技术上,以上这些都可以通过 viewport 标签来解决,比如说上面的需求,把布局设定为 320px,同时进行 1.5 倍的缩放:
~~~html
<meta name="viewport" content="width=320, initial-scale=1.5">
~~~
所见即所得,需要设置的属性在 content 以逗号分割开来,`width`表示页面布局宽度,`initial-scale`代表页面初始状态的缩放比例,如果你不想让用户进行缩放,还可以添加`user-scalable=no`字段来保证用户无法进行缩放。
更重要的是,我们还可以无需指定特定宽度,通过设置`width=device-width`,指定布局宽度等于手机分辨率宽度来更好的利用响应式设计。注意这里的`device-width`表示手机的分辨率宽度,而并非手机物理像素宽度。iPhone4 在垂直状态下物理像素宽度为 640,这里的`device-width`代表的则应该是它的 dip 像素 320px。
~~~html
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"/>
~~~
- 第一章:移动开发入门
- 第一节:概述
- 第二节:基础概念
- 第一课时:像素
- 第二课时:视口
- 第二章:Flex 布局
- 第一节:概述
- 第二节:容器属性
- 第一课时:flex-direction 属性
- 第二课时:flex-wrap 属性
- 第三课时:flex-flow 属性
- 第四课时:justify-content 属性
- 第五课时:align-items 属性
- 第六课时:align-content 属性
- 第三节:项目属性
- 第一课时:order 属性
- 第二课时:flex-grow 属性
- 第三课时:flex-shrink 属性
- 第四课时:flex-basis 属性
- 第五课时:flex 属性
- 第六课时:align-self 属性
- 第四节:Flex 实例
- 第一课时:常见页面布局
- 第三章:响应式布局
- 第一节:概述
- 第二节:媒体查询
- 第一课时:概述
- 第二课时:响应式设计
- 第三节:栅格系统
- 第一课时:概述
- 第二课时:案例分析
- 第三课时:Bootstrap 简介
- 第四节:响应式案例
- 第一课时:三星首页
- 第四章:移动端适配
- 第五章:移动端事件
- 第一节:概述
- 第二节:touch 事件
- 第三节:触摸事件对象
- 第四节:其他事件
- 第五节:移动端幻灯片
- 第六章:移动端常见问题
- 第一节:浏览器兼容性
- 第二节:移动端动画
- 第三节:300ms 延迟
- 第四节:文字溢出省略
- 第五节:水平居中和垂直居中
- 第七章:项目案例
- 第一节:美团外卖
- 第一课时:首页
- 第二课时:订单页面
- 第三课时:我的页面
- 第四课时:详情页面
- 第五课时:购物车页