1.视口概念
视口(viewport)代表当前可见的计算机图形区域。视口在响应式设计中是一个非常重要的概念。视口的概念针对移动端浏览器,分为两种视口,一种是可见视口即设备大小,另一种是视窗视口即网页宽度。 移动端浏览器通常宽度是 240px~640px,而大多数为 PC 端设计的网站宽度至少为 800px,如果仍以浏览器窗口作为视口的话,网站内容在手机上看起来会非常窄,因此,引入视口(虚拟容器)。在 Web 浏览器术语中,通常与浏览器窗口相同,但不包括浏览器的 UI, 菜单栏等——即指你正在浏览的文档的那一部分。文档,比如这篇文章,可能会非常长。你的 viewport 就是你现在所能见到的所有事物。值得注意的是“什么是视口区域”这个问题,页面中的一些导航菜单也包括在其中。Viewport 的大小取决于屏幕的大小,无论浏览器是否处于全屏模式,是否被用户缩放了。Viewport 外的区域,比如这个文档的 See Also 部分,可能需要滚动到其所在的区域才会出现在屏幕上。 •在尺寸较大的设备中,在这些设备上,应用显示区域不一定是全屏的,viewport 是浏览器窗口的大小。 •在大多数移动设备中,浏览器是全屏的,viewport 是整个屏幕的大小。 •在全屏模式下,viewport 是设备屏幕的范围,窗口是浏览器窗口,浏览器窗口大小小于或等于视口的大小,并且文档是这个网站,文档的大小可比 viewport 长或宽。 概括地说,viewport 基本上是当前文档的可见部分。
2.视口大小是可变的 Viewport 的宽度并不总是窗口的宽度。 如果你测试 Chrome 或 Firefox 浏览器中 window 和 document 的宽度和高度,会得到如下值:
`document.documentElement.clientWidth /* 1200 / window.innerWidth / 1200 / window.outerWidth / 1200 */
document.documentElement.clientHeight /* 800 / window.innerHeight / 800 / window.outerHeight / 900 */`
3.移动设备的视口
对于各种不同形状,不同设备像素比移动设备,其浏览器的视口(窗口中显示网页信息的区域)不一定与渲染页面大小相同。移动设备的视口的默认值为 980px,一般情况下都要比这些设备的屏幕尺寸要大。
为了让页面能够全部展示,这些浏览器在渲染时会对页面进行缩放。比如在一个宽 320px 的移动设备显示一个视觉视口宽为 980px 的页面,移动设备浏览器会对这个页面进行缩放直至其视觉视口宽度为 320px(具体取决于浏览器实现)。但直接缩放页面会导致页面字体变小,使得缩放后的页面显示效果都不会很理想。
如果开发者想让移动端浏览器使用屏幕宽度作为视口替换默认的 980px 宽度视口,则可以在 HTML 的头部添加以下标签:
这里 width 属性指的是视口宽度,现在视口的宽度被设置为了设备的屏幕宽度,即文档视口宽度大小与设备宽度大小 100% 对应(转换为 CSS 像素值相同)。除了 width 属性外,还有initial-scale、maximum-scale、minimum-scale,以及 user-scalable 属性可供设置。这些属性分别设置了文档的初始缩放比例、最大缩放比例、最小缩放比例以及是否允许用户进行缩放操作。但这些属性的默认值已经很好了,开发时可以忽略掉这些属性。
下面具体谈谈移动端的视口 移动端涉及到三个视口:布局视口(Layout Viewport)、视觉视口(Visual Viewport)和理想视口(Ideal Viewport)。
两种像素 像素是计算机屏幕中显示特定颜色的最小区域。屏幕中的像素越多,同一范围内能看到的内容就越多。或者说,当设备尺寸相同时,像素越密集,画面就越精细。 两种像素之间也存在一定的关系,即:在电脑端,一个逻辑像素等于一个物理像素。
那么,当我们在 CSS 中为一个元素设置属性 width: 250px; 时,会发生什么?这个元素的宽度究竟是多少像素呢?
事实上,这里已经涉及了两种不同的像素:物理像素和 CSS 像素。
物理像素(设备像素,device pixels)指的是设备屏幕的物理像素,任何设备的物理像素数量都是固定的。
CSS 像素(CSS pixels)是 CSS 和 JS 中使用的一个抽象概念。它和物理像素之间的比例取决于屏幕的特性(是否为高密度)以及用户进行的缩放,由浏览器自行换算。
在 Apple 的视网膜屏(Retina)中,每 4 个像素为一组,渲染出普通屏幕中一个像素显示区域内的图像,从而实现更为精细的显示效果。此时, 250px 的元素跨越了 500 个物理像素的宽度。
三种视口
移动端浏览器通常宽度是 240px~640px,而大多数为 PC 端设计的网站宽度至少为 800px,如果仍以浏览器窗口作为视口的话,网站内容在手机上看起来会非常窄。 因此,引入了布局视口、视觉视口和理想视口三个概念,使得移动端中的视口与浏览器宽度不再相关联。
布局视口(layout viewport)
一般移动设备的浏览器都默认设置了一个 viewport 元标签,定义一个虚拟的布局视口(layout viewport),用于解决早期的页面在手机上显示的问题。iOS, Android 基本都将这个视口分辨率设置为 980px,所以 PC 上的网页基本能在手机上呈现,只不过元素看上去很小,一般默认可以通过手动缩放网页。布局视口的宽度/高度可以通过 document.documentElement.clientWidth / Height 获取。它使视口与移动端浏览器屏幕宽度完全独立开。CSS 布局将会根据它来进行计算,并被它约束。
视觉视口(visual viewport)
视觉视口是用户当前看到的区域,用户可以通过缩放操作视觉视口,同时不会影响布局视口。 视觉视口和缩放比例的关系为: 当前缩放值 = 理想视口宽度 / 视觉视口宽度 所以,当用户放大时,视觉视口将会变小,CSS 像素将跨越更多的物理像素。 理想视口(ideal viewport) 布局视口的默认宽度并不是一个理想的宽度,于是 Apple 和其他浏览器厂商引入了理想视口的概念,它对设备而言是最理想的布局视口尺寸。显示在理想视口中的网站具有最理想的宽度,用户无需进行缩放。 理想视口的值其实就是屏幕分辨率的值,它对应的像素叫做设备逻辑像素(device independent pixel, dip)。dip 和设备的物理像素无关,一个 dip 在任意像素密度的设备屏幕上都占据相同的空间。如果用户没有进行缩放,那么一个 CSS 像素就等于一个 dip。
用下面的方法可以使布局视口与理想视口的宽度一致: 实际上,这就是响应式布局的基础。
视口的设置
我们可以使用视口元标签(viewport meta 标签)来进行布局视口的设置。
一倍图、二倍图、三倍图 * MacBook Pro 视网膜屏(Retina)显示器硬件像素是 2880px * 1800px。当设置屏幕分辨率为 1920px * 1200px 的时候,理想视口的宽度值是 1920px, 那么 dip 的宽度值就是 1920px。其与理想视口宽度的比值为1.5(2880/1920),这个比值叫做设备像素比: 逻辑像素宽度 * 设备像素比 = 物理像素宽度
设备像素比可以通过 window.devicePixelRatio 来获取,或者使用 CSS 中的 device-pixel-ratio。
下面是常见的设备像素比: •普通密度桌面显示屏:devicePixelRatio = 1 •高密度桌面显示屏(Mac Retina):devicePixelRatio = 2 •主流手机显示屏:devicePixelRatio = 2 or 3
对于一张 100px * 100px 的图片,通过 CSS 设置其宽高: { width:100px; height:100px; }
在普通显示屏的电脑中打开是正常的,但假设在手机或 Retina 屏中打开,按照逻辑分辨率来渲染,他们的 devicePixelRatio = 2,那么就相当于拿 4 个物理像素来描绘 1 个电子像素。这等于拿一个2倍的放大镜去看图片,图片就会变得模糊。这时,就需要使用 @2x 甚至 @3x 图来避免图片的失真。 在移动端开发中,常将视口抽象划分为布局视口、视觉视口和理想视口。为什么这么划分呢?我觉得还是为了让我们更好理解CSS像素和设备像素的区别,也就是逻辑像素和物理像素的区别。在PC端开发书写CSS时,对元素的尺寸的限定单位经常就是PX,即像素大小。从一开始接触和学习过程中,一直都是使用PX,导致我们的思维产生定式,总觉得CSS中元素的大小的度量就只有PX了。 另一个默认的思维定式就是在我们CSS代码中,CSS的PX像素单位就是真实的代表一个像素,导致当网页开发转到移动端开发时,一个新概念的出现对我们冲击特别大,很难转过弯来理解,比如现在要说的视口的理解,牵扯出来的CSS像素和设备像素的概念。 其实,只要记住一点,CSS像素PX只是代表WEB网页中的一个度量单位,可以理解为同rem和em等单位一样,需要有一个参照尺寸才能确定其实际大小。比如rem参照根字节点的字体大小来确定自身大小,em参照父级元素字体大小来确定自身大小。思维定式中rem和em参照物是我们“绝对单位”像素PX而定的。