茶话

茶话viewport
一个典型的针对移动端优化的页面会包含类似酱紫的内容:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
这玩意儿看起来眼熟不?这篇博将来茶话一下这个 name="viewport" 中的 viewport —— 视口
我们常说的 viewport 也就是视口 就是显示器显示页面内容的屏幕区域,其中涉及到以下几个概念
1. layout viewport(布局视口) 2. visual viewport(视觉视口) 3. ideal viewport(理想视口) 4. css 像素 5. dip(device independent pixels)设备独立像素和 css 像素之间的关系
viewport 的概念
通俗的来说移动设备上的 viewport 就是设备的屏幕上能用来显示网页的那个区域,再具体点儿就是浏览器上或是 app 中的 webview 用来显示网页的那部分区域。
但 viewport 又不局限于浏览器可视区域的大小,它可能比浏览器的可视区域要大或小。通常移动设备上的 viewport 都是要大于浏览器可视区域的,因为考虑到移动设备的分辨率相对于桌面电脑来说都比较小,所以为了 能在移动设备上正常显示为桌面浏览器设计的网站,移动设备上的浏览器都会把自己默认的 viewport 设置为 980px 或者 1024px 或者其他。但带来的后果则是会出现横向滚动条。
layout viewport 布局视口
一般呢,移动设备的浏览器都默认设置了一个 viewport 定义了一个虚构的布局视口,用于解决早期页面在手机上 的显示问题。 ios 和 android 基本都将介个视口分辨率设置为 980px,所以 pc 上的网页基本可以在手机上呈 现,只是元素看上去会比较小,并可以手动缩放页面。
移动设备上的浏览器认为自己必须能正常显示所有的网站,无论是不是为移动设备而设计的网站。但由于移动设备 的屏幕都不是很宽,如果以浏览器的可视区域作为 viewport 的话,那些为桌面浏览器设计的网站放到移动设备上 显示时,必然会因为移动设备的 viewport 太窄而挤作一团,甚至毁掉布局。
2017/8/8 茶话viewport | wonderland of code
https://emily-says.github.io/2017/08/01/%E8%8C%B6%E8%AF%9Dviewport/ 2/10
也许你会想到:现在不是有很多手机分辨率都非常大吗?比如 768 1024,或者 1080 1920 这样,那这样的手机 用来显示为桌面浏览器设计的网站是没问题的吧?
在后面的内容我们会详细的看到 css 中的 1px 并不一定代表屏幕上的 1px,分辨率越大,css 中 1px 代表的物理 像素就会越多,分辨率比的值也越大。这很好理解,你分辨率增大了,但屏幕尺寸并没有变大,就必须让 css 中的 1px 渲染(塞入)更多的物理像素,才能让 1px 的东西在屏幕上的大小与那些低分辨率的设备看起来差不多,不 然就会因为太小而看不清。
所以如果把移动设备上浏览器的可视区域设为 viewport 的话,某些网站(例如左右分区的网页)就会因为 viewport 太窄而显示错乱,所以这些浏览器就决定:默认情况下把 viewport 设为一个较宽的值,比如 980px。 这样的话即使是那些为桌面设计的网站也能在移动浏览器上正常显示了。所以也把这个 浏览器默认的 viewport 叫做 layout viewport 。它的宽度可以通过 document.documentElement.clientWidth 来获取。
到底 layout viewport 有多宽
初始状态下
初始状态下的 layout viewport
例如在谷歌下初始 layout viewport 的宽度是 980px,这时页面处于缩小的状态,通过 visual viewport 正好看到 layout viewport 中所有内容。或者说,在没有设置 <meta name="viewport"> 的情况下 layout viewport 根据 不同浏览器的特性有一个初始值。举个栗子:无论在 iPhone5 或在 iPad 下访问该页面,layout viewport 都是 980px 宽
固定layout viewport980
visual viewport 视觉视口与 device pixel 设备物理像素(分辨率)
2017/8/8 茶话viewport | wonderland of code
https://emily-says.github.io/2017/08/01/%E8%8C%B6%E8%AF%9Dviewport/ 3/10
然而,layout viewport 的宽度是 > 浏览器可视区域的宽度的,所以我们还需要一个 viewport 来代表 浏览器可视 区域的大小,这个 viewport 叫做 visual viewport。
无论你是用桌面设备或是移动设备的浏览器去访问一个页面的时候,你所看到的浏览器窗口就是你的 visual viewport ,它的宽度可以通过 window.innerWidth 来获取。对于一个移动设备来说就是你通过浏览器看到的那 部分的大小,它的计量单位为 px,设备独立像素 dip 的那个 px。这个 visual viewport 通常是可以变化的,比如 你对屏幕进行缩放,就可以改变它的大小,或者移动屏幕的滚动条就可以改变 visual viewport 的位置。
视觉视口是物理屏幕的可视区域,屏幕显示器的物理像素。相同尺寸的屏幕像素密度大的设备,硬件像素会更多。
浏览器可视区域的大小 visual viewport
设备像素
设备像素是物理概念,指的是设备中使用的物理像素,用 px 表示,它是一个“相对绝对单位”,即:
在同一设备上每个设备像素所代表的物理长度是固定不变的(绝对性) 但在不同设备之间每个设备像素所代表的物理长度是可以变化的(相对性)
我们需要明白一个概念就是在我们手机上呈现的一条线、一个区块、一个图像都是由最小单位“像素”来表示的。 这看起来就像是十字绣或是贴近电视看到的画面:
2017/8/8 茶话viewport | wonderland of code
https://emily-says.github.io/2017/08/01/%E8%8C%B6%E8%AF%9Dviewport/ 4/10
你也可以这样理解:物理像素或者说物理尺寸,就是我们现实生活中真实的计量单位、计量大小,1cm 它就是 1cm ,1m 就是1m ,不会因为你是仙女就少一点儿,更不会因为你是老爷们儿就多一点儿。
那么物理像素也是一样,我们以 iphone5 || iphone5s || iphone 5se 为例,它的物理像素宽是 320*2 px,也就是 说,iphone5 这个系列的屏幕横向上,真实存在640个像素点儿 或者说640个像素小格格。至于这个 320 是怎么 回事我们一会再看
layout viewport 与 visual viewport 的区别与联系
把 layout viewport 想像成为一张不会变更尺寸的大图。想像你有一个小一些的镂空框架(比如一个没放照片的相 框),你通过这个框来看这张大图。类似于看望远镜 这个框架的周围被不透明的材料所环绕,于是掩盖了你所 有的视线,只留这张大图的一部分给你。你通过这个框架所能看到的大图的部分就是 visual viewport 。你可以拿 远框架(缩小)来看整个图片,或者可以靠近一些(放大)只看局部。你也可以移动框架的位置、改变框架的方 向,但是大图(layout viewport)的大小和形状永远不会变。
2 2
2017/8/8 茶话viewport | wonderland of code
https://emily-says.github.io/2017/08/01/%E8%8C%B6%E8%AF%9Dviewport/ 5/10
当进行页面放大时,你可以想象你拿着这个框架离这张大图越来越近了,那么你所看到的大图的内容也越来越少 了。原本在未缩放的页面上看起来很小的尺寸,现在看上去变大了,事实上这部分的设备独立像素( css 的 px 值)并没有变化,仅仅是因为进行放大后,css 的 1px 的值所占的屏幕分辨率的值变大了。
同理,当你缩小整个页面的时候,看到大图的内容也越来越多,同时,原本看起来很大的尺寸,现在看上去的时候 又变小了。同理,css 的独立像素 1px 的值并没有发生变化,但是 1px 值所占的屏幕分辨率的值变小了。
在放大和缩小的过程中,visual viewport 和 layout viewport 的宽、高都没发生任何的变化,变化的仅仅就像是 用户拿着这个 visual viewport 去远离或者靠近 layout viewport,在远离或者靠近的过程中,就会呈现出缩放的 效果来。
ideal viewport 理想视口与 device independent pixels(dip) 设备独立像素
上面已经介绍了两种 viewport 了:layout viewport 和 visual viewport。但浏览器觉得还不够,因为现在越来越 多的网站都会为移动设备进行单独的设计,所以必须还要有一个能完美适配移动设备的 viewport。
所谓的完美适配指的是
1. 不需要用户缩放和横向滚动条就能正常的查看网站的所有内容 2. 显示的文字的大小合适。比如一段 14px 的文字不会因为在一个高密度像素的屏幕里显示得太小而无法看 清,理想的情况是这段14px的文字无论是在何种密度屏幕、何种分辨率下都能显示出来尺寸差异小。当然, 不只是文字,其他元素像图片什么的也是这个道理。
这个 viewport 就被叫做 ideal viewport —— 移动设备的理想视口。
ideal viewport 并没有一个固定的尺寸,不同的设备拥有不同的 ideal viewport。以 iPhone 来说,所有的非 plus 系列的 iPhone 的 ideal viewport 宽度都是 320px,也就是说,在非 plus 系列的 iPhone 中,css 中的 320px 就代表 iPhone 屏幕的理想宽度。
安卓设备就比较复杂了,有320px的,有360px的,有384px的等等
移动设备上的 viewport 分为 layout viewport、 visual viewport 和 ideal viewport 三类,其中 ideal viewport 是最适合移动设备的 viewport,它宽度 = 移动设备的屏幕宽度,只要在 css 中把某一元素的宽度设为 ideal viewport 的宽度(单位用px),那么这个元素的宽度就是设备屏幕的宽度了,也就是宽度为100%的效果。ideal viewport 的意义在于,无论在何种分辨率的屏幕下,那些针对 ideal viewport 而设计的网站,不需要用户手动缩 放,也不需要出现横向滚动条,都可以完美的呈现给用户。
2017/8/8 茶话viewport | wonderland of code
https://emily-says.github.io/2017/08/01/%E8%8C%B6%E8%AF%9Dviewport/ 6/10
dip
dip 设备独立像素是跟设备的硬件像素(物理像素)无关的,一个 dip 在任意像素密度的设备屏幕上都占据相同的 空间。
设备的独立像素宽 与 物理像素宽(或者说像素分辨率)的关系可以满足酱紫的公式: 物理像素宽度 = 独立像素 宽度 * 倍率
所以上例 320 2 中的 320 就是独立像素宽度,作为 Retina 屏倍率为2,所以物理像素宽度就是 320 2 = 640px
但移动端手机屏幕通常来说是不可以设置分辨率的,都是由设备厂家默认设置的宽度值。也就是说 dip 值就是 ideal viewport 的值,我们拿 iPhone 的屏幕分辨率来举个栗子:
iPhone 5 系列(iPhone 5s || iphone 5 se )的分辨率 320 568,物理像素 640 1136 也就是说 iPhone 5 系列的手机屏幕上,横向上真实存在 640 个像素点,纵向上有 1136 个像素点, 所以它们之间的设备像素比就是 640 / 320 && 1136 / 568 比值为2 iPhone 6 系列的分辨率 375 667,物理像素 750 1334 设备像素比同样也是 2 但需要注意的是 plus 系列,plus 的分辨率是 414 736 ,物理像素 1242 2208 ,设备像素比就不是 2 了, 是 3 倍。但图像从渲染的 1242 2208 缩小至 1080 1920。缩小比例为 1080/1242 = 1920/2208 = 20 /23 这就意味着从原始渲染中每23个像素必须映射到20个物理像素。换句话来说也就是图像缩小到原始大 小的约87%
缩小
* 你可以从 [这里](https://www.paintcodeapp.com/news/iphone-6-screens-demystified) 查看到 plus 系列的实际显示图像等比降低至 1080 * 1920 的原因
你还可以从 这里http://viewportsizes.com 查询到更多设备的 ideal veiwport
css 像素
首先我们需要明确一个点那就是 css 中的 1px 并不一定就等于设备的 1px
2017/8/8 茶话viewport | wonderland of code
https://emily-says.github.io/2017/08/01/%E8%8C%B6%E8%AF%9Dviewport/ 7/10
px 是用于 webpage 页面布局的单位,在桌面浏览器中 css 的1个像素往往是对应着电脑屏幕的1个物理像素,这 可能就会给我们造成一个错觉就是 css 中的像素就是设备的物理像素。但事实并非如此,我们前面提到 css 中的像 素值是一个抽象单位,在不同的设备或环境中,css 中的 1px 所代表的设备物理像素是不同的。
在早先的移动设备中屏幕像素密度都比较低,比如 iPhone3GS 它的分辨率是 320 480,1个 css 像素确实是等于1 个物理像素哒,后来随着技术的发展,移动设备的屏幕像素密度越来越高,从 iPhone4 开始苹果公司就出了所谓 的 Retina 屏分辨率提高了整一倍,也就是 640 960
屏幕尺寸没有变化像素却多了一倍,这时,1个 css 像素就等于2个物理像素。其他品牌的移动设备也是这个道 理。1个 css 像素相当于多少个物理像素,也因设备的不同而不同,比率五花八门没有一个定论。
根据上述设备像素与CSS像素之间的关系、及DPR的官方定义,我们可以推断出:CSS像素 = 设备独立像素(逻辑 像素)
使用 meta 标记控制 viewport
还是最头上那行代码: <meta name="viewport" content="width=device-width, initial-scale=1.0, maximumscale=1.0, user-scalable=no"> 移动设备默认的 viewport 是 layout viewport 也就是比屏幕要宽的那个。但在 进行移动页面开发时我们需要的却是 ideal viewport 所以会使用到这行代码。
要得到 ideal viewport 就必须把默认的 layout viewport 宽度设置为移动设备的屏幕宽度 因为其中的 width 能控制 layout viewport 的宽度,所以把 width 设置为 device-width
这行代码的作用是让当前的 layout viewport 宽度 = 设备宽度,不允许用户手动缩放,当然不同的网站有不同的 需求你也可以允许手动缩放 但让 layout viewport 宽度 = 设备宽度这是大家都想要的效果。如果不酱紫设定的话 就会默认为了比屏幕宽的 layout viewport 也就是说会有横向滚动条的粗现~
meta viewport 标记首先是由苹果公司在 safari 浏览器中引入的,就是解决移动设备的显示问题,后来各大浏览 器厂商也在效仿。这里罗列了每个属性的详细介绍
2017/8/8 茶话viewport | wonderland of code
https://emily-says.github.io/2017/08/01/%E8%8C%B6%E8%AF%9Dviewport/ 8/10
width
width 属性被用来控制 layout viewpoet 布局视口的宽度,默认值是由设备厂家指定的,基本都会将这个视口分 辨率定为 980px ,你可以设置类似 width=320 酱紫确切的像素值,但为了自适应布局通常的做法是设置为 device-width
接着上面 “到底 layout viewport 有多宽” 的栗子
在上面(很上面 - - )的栗子中我们看到了当没有设置 <meta name="viewport"> 的情况下谷歌会将页面 layout viewport 设置为 980px 酱紫的初始值 那么在声明了的情况下呢? <meta name="viewport" content="width=300">
这里可以看出:无论宽度是 320 的 iPhone5 或是宽度为 768 的 iPad layout viewport 初始宽度就是 300px,也 适应于 visual viewport 。换句话说,通过 visual viewport 可以看到 layout viewport 里所有的内容,并且没有 横向滚动条。当然了,width 的值设置为其他值也是如此。
当对手机屏幕翻转时
2017/8/8 茶话viewport | wonderland of code
https://emily-says.github.io/2017/08/01/%E8%8C%B6%E8%AF%9Dviewport/ 9/10
如果 visual viewport 宽度 > layout viewport 宽度,那么 viewport 需要 zoom in (放大) 以适应 visual viewport 宽度 如果 visual viewport 宽度 < layout viewport 宽度,那么 viewport 需要 zoom out (缩小) 以适应 visual viewport 宽度
所以设置 device-width 会将手机横向物理像素 / 转化系统 点击这里看换算 作为其值,重制相应的 layout viewport 值适应 visual viewport。此时无论手机是否翻转,visual viewport 都会 = layout viewport 的值。而 不出现缩放的情况。
height 并不常用 ( ꒪⌓꒪) initial-scale
用于指定页面的初始缩放比例。 initial-scale=1 表示将布局视口宽度设置为理想视口的宽度,其实作用同于 width=device-width
那为啥会有相同的结果呢?首先需要知道这个“缩放”是相当于啥来缩放的,因为这里的缩放值是1,也就是不缩 放,也就是说,缩放是相对于 ideal viewport 来进行缩放的,当对 ideal viewport 进行 100% 缩放(也就是1) 时,不就是 ideal viewport 了么。
initial-scale=1.5 就表示布局视口的宽度设置为理想视口的宽度的 1.5 倍
如果 width 和 initial-scale = 1 同时出现
<meta name="viewport" content="width=400, initial-scale=1"> 如果出现了酱紫的写法,width=400 表示把 当前 viewport 的宽度设为 400px,initial-scale=1 则表示把当前 viewport 的宽度设为 ideal viewport 的宽度, 那么浏览器会取它们两个中较大的那个值。例如
当 width=400,ideal viewport 的宽度为320时,取的是 layout viewport 的400 当 width=400,ideal viewport的宽度为480时,取的是 ideal viewport 的480
要把当前的 viewport 宽度设为 ideal viewport 的宽度,既可以设置 width=device-width ,也可以设置 initial-scale=1 ,但这两者各有一个小缺陷,就是iphone、ipad 以及 IE 会横竖屏不分,都以竖屏的 ideal viewport 宽度为准。所以,最完美的写法应该是两者都写上去,这样就 initial-scale=1 解决了 iphone、ipad的 毛病,width=device-width 则解决了 IE 的毛病。
maximum-scale 与 minimun-scale
maximum-scale 用于指定用户能放大的最大比例,假设设置为 <meta name="viewport" content="initialscale=1,maximum-scale=3" /> 那么用户最终能将页面最大到这个初始页面的3倍大小。
minimum-scale 类似 maximum-scale 不过它是用来制定页面缩小比例的,通常不会去定义该属性的值,页面如 果太小,那么对于用户来说就将难以阅读。
2017/8/8 茶话viewport | wonderland of code
https://emily-says.github.io/2017/08/01/%E8%8C%B6%E8%AF%9Dviewport/ 10/10
user-scalable
这个属性用来控制用户是否可以通过手势对页面进行缩放。默认值为 yes 即可以被缩放,通常会将其设置为 no 不 允许用户缩放页面。
最后
在做移动页面开发时如果不设置 meta viewport 标签,那么移动设备上浏览器默认的宽度值为 800px、980px、 1024px 等,总之是大于屏幕宽度的。这里的宽度所用的 px 都是指 css 独立像素中的 px,不是屏幕物理像素的 px。
每个移动设备浏览器中都有一个理想的宽度(css 中的宽度,非物理宽度),在 css 中这个宽度就相当于 100% 所 代表的那个宽度。我们可以用 meta 标签把 viewport 的宽度设为那个理想的宽度,如果不确定这个设备的理想宽 度是多少,那么用 device-width 就好。同时 initial-scale=1 也有把 viewport 的宽度设为理想宽度的作 用。所以,我们可以使用 <meta name="viewport" content="width=device-width, initial-scale=1"> 来得到一个 ideal viewport。
为什么需要有理想的 viewport 呢?比如一个分辨率为 320 480 的手机,理想 viewport 的宽度当然是320px,而 另一个屏幕尺寸相同但分辨率为 640 960 的手机的理想 viewport 宽度也是为320px,那为什么分辨率大的这个手 机的理想宽度要 = 分辨率小的那个手机的理想宽度呢?这是因为只有这样才能保证同样的页面在不同分辨率的设 备上看起来都是一样或差不多的。
实际上,现在市面上虽有各种种类不同、品牌不同、分辨率不同的手机,但它们的 ideal viewport 宽度归纳起来 无非也就 320、360、384、400等几种,都是非常接近的,理想宽度的相近也就意味着我们针对某个设备的 ideal viewport 而做出的页面在其他设备上的表现也不会相差非常多甚至是表现一样哒!
推荐阅读: ppk第一篇,ppk第二篇,ppk第三篇,参考阅读移动前端开发之 viewport 的深入理解,visual l viewport 和 layout viewport

posted @ 2017-12-31 00:15  小小小梅子  阅读(143)  评论(0编辑  收藏  举报