视口(viewport)
视口(viewport)
viewport (视口)就是浏览器显示页面内容的屏幕区域。其中涉及几个重要概念是 dip ( device-independent pixel 设备逻辑像素 )和 CSS 像素之间的关系。
layout viewport(布局视口)
一般移动设备的浏览器都默认设置了一个 viewport 元标签,定义一个虚拟的 layout viewport(布局视口),用于解决早期的页面在手机上显示的问题。iOS, Android基本都将这个视口分辨率设置为 980px,所以 PC 上的网页基本能在手机上呈现,只不过元素看上去很小,一般默认可以通过手动缩放网页。
- 在PC端上,布局视口等于浏览器窗口的宽度。
- 在移动端上,由于要使为 PC 端浏览器设计的网站能够完全显示在移动端的小屏幕里,此时的布局视口会远大于移动设备的屏幕。
在移动端,默认情况下,布局视口等于浏览器窗口宽度。布局视口限制了CSS的布局。
在 JavaScript 上,获取布局视口的宽度可以通过 document.documentElement.clientWidth
或者 document.body.clientWidth
得到。
visual viewport(视觉视口)和物理像素
视觉视口是用户正在看到的区域。用户可以缩放来操作视觉视口,而不影响视觉视口的宽度。视觉视口决定了用户看到了什么。
在 JavaScript 上,获取视觉视口的宽度可以通过 window.innerWidth
得到。
在 PC 端上,视觉视口等于布局视口的宽度,无论用户是放大屏幕还是缩小屏幕,这两个视口的宽度仍然相等。
在移动端上,缩放屏幕的过程实质上就是CSS像素缩放的过程。
当用户将屏幕放大到两倍时,视觉视口变小了(因为视觉视口中 CSS 像素变少了),而每单位的 CSS 像素却变大了,因此 1px (1个 CSS 像素)等于 2 个设备像素。当为 iPhone6(dpr=2) 时,视觉视口中 CSS 像素变少了,但是 1px 等于 2 个设备像素。当用户缩小屏幕时也是同样的道理。
缩放的过程并不会影响布局视口的大小。也就是说:
- 高清屏(dpr>=2)或屏幕放大时,视觉视口变小(CSS像素变少),每单位的CSS像素等于更多的设备像素;
- 非高清屏(dpr<2)或屏幕缩小时,视觉视口变大(CSS像素变多),每单位的CSS像素等于更少的设备像素。
iPhone的物理像素:
- iPhone5 :
640 * 1136
- iPhone6:
750 * 1334
- iPhone6 Plus:
1242 * 2208
ideal viewport(理想视口)和 dip (设备逻辑像素)
- ideal viewport(理想视口)通常是我们说的屏幕分辨率。
- dip (设备逻辑像素)跟设备的硬件像素无关的。一个 dip 在任意像素密度的设备屏幕上都占据相同的空间。
默认情况下,布局视口等于浏览器窗口宽度,因此在移动端上需要通过放大或缩小视觉视口来查看页面内容,这当然体验糟糕啊!因此,在移动端引入了理想视口的概念。理想视口的出现必须需要设置 meta
视口标签,此时布局视口等于理想视口的宽度。
在 JavaScript 上获取视觉视口的宽度 window.screen.width
得到。
设备的逻辑像素宽度和物理像素宽度(像素分辨率)的关系满足如下公式:逻辑像素宽度 * 倍率 = 物理像素宽度
比如: MacBook Pro 的 Retina (视网膜)屏显示器硬件像素是:2880 * 1800
。当你设置屏幕分辨率为 1920 * 1200
的时候,ideal viewport(理想视口)的宽度值是 1920 像素, 那么 dip 的宽度值就是 1920。设备像素比是 1.5(2880/1920)。
在移动端手机屏幕通常不可以设置分辨率,一般都是设备厂家默认设置的固定值,换句话说 dip 的值就是 ideal viewport(理想视口)(也就是分辨率)的值。
iPhone 的屏幕分辨率:
- iPhone5 :分辨率
320 * 568
,物理像素640 * 1136
,@2x - iPhone6:分辨率
375 * 667
,物理像素750 * 1334
,@2x - iPhone6 Plus :分辨率
414 * 736
,物理像素1242 * 2208
,@3x,(注意,实际显示图像等比降低至 1080×1920 )
CSS 像素
- CSS像素(px):用于页面布局的单位。
- 设备像素:设备屏幕的物理像素,任何设备的物理像素的数量都是固定的。
样式的像素尺寸(例如, width: 100px)是以 CSS 像素为单位指定的。CSS 像素与 dip 的比例即为网页的缩放比例,如果网页没有缩放,那么一个 CSS 像素就对应一个 dip(设备逻辑像素)。
1个 CSS 像素等于多少个设备像素取决于屏幕特性(是否是高清屏)和用户缩放的比例。当用户将屏幕从 100% 放大到 200% 时,1个 CSS 像素等于 2 个设备像素,反之相反;当屏幕为 Retina 高清屏(如,iPhone6,dpr=2)时,1个 CSS 像素就等于 2 个设备像素,反之相反。
需要明白一点的是,2 个设备像素并不是说它扩大了两倍,而是说在页面上仍然显示的是 1 px(1个CSS像素),但是这 1 px 是由 2 个设备像素组成。像素点变多了,因此图像会变得更加清晰。
分辨率与设备像素比
分辨率是指每英寸内点的个数,单位是 dpi 或者 dppx 。设备像素比是指设备像素与理想视口宽度的比值,没有单位。
分辨率在 CSS 上可以通过 resolution
属性设置。
一般情况下会使用 dpi 作为分辨率的单位,因为 dppx 并非所有浏览器都支持。而设备像素比在 CSS 上可以通过 device-device-pixel-ratio
属性设置,而在 JavaScript 上可以通过 window.devicePixelRatio
属性获取。
同时,1dpr=96dpi。举个例子。在 iPhone6 下,理想视口宽度为 375px,而设备像素为 750px,因此,此时设备像素比为 2,分辨率为 192dpi。
使用 viewport 元标签控制布局
<meta id="viewport" name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1; user-scalable=no;" />
width
:被用来控制 layout viewport(布局视口)的宽度,layout viewport(布局视口)宽度默认值是设备厂家指定的。iOS, Android 基本都将这个视口分辨率设置为 980px。我们可以
width=320
这样设为确切的像素数,也可以设为device-width
这一特殊值,一般为了自适应布局,普遍的做法是将width
设置为device-width
width=device-width
也就是将 layout viewport(布局视口)的宽度设置 ideal viewport(理想视口)的宽度。网页缩放比例为 100% 时,一个 CSS 像素就对应一个 dip(设备逻辑像素),而layout viewport(布局视口)的宽度、 ideal viewport(理想视口)的宽度(通常说的分辨率)、dip 的宽度值是相等的。height
:与width
类似,但实际上却不常用。initial-scale
:用于指定页面的初始缩放比例。initial-scale=1
表示将 layout viewport(布局视口)的宽度设置为 ideal viewport(理想视口)的宽度;initial-scale=1.5
表示将 layout viewport(布局视口)的宽度设置为 ideal viewport(理想视口)的宽度的1.5倍。
maximum-scale
:用于指定用户能够放大的最大比例,假设页面的默认缩放值initial-scale
是1
,那么用户最终能够将页面放大到这个初始页面大小的 3 倍。minimum-scale
:类似maximum-scale
的描述,不过minimum-scale
是用来指定页面缩小比例的。通常情况下,不会定义该属性的值,页面太小将难以阅读。user-scalable
:用来控制用户是否可以通过手势对页面进行缩放。该属性的默认值为yes
,可被缩放,你也可以将该值设置为no
,表示不允许用户缩放网页。