专栏名称: qize
前端交互开发工程师
目录
相关文章推荐
吉林市场监管  ·  3·15优化消费环境 市场监管在行动 ⑦|辉南县 ·  14 小时前  
吉林市场监管  ·  3·15优化消费环境 市场监管在行动 ⑦|辉南县 ·  14 小时前  
前端早读课  ·  【早阅】Vibe Coding 宣言 ·  昨天  
前端早读课  ·  【早阅】Axios 请求可能存在 ... ·  昨天  
青云说说  ·  如何定义好酒? ·  昨天  
青云说说  ·  如何定义好酒? ·  昨天  
前端早读课  ·  【第3474期】猫耳大型活动提效:组件低代码化 ·  2 天前  
51好读  ›  专栏  ›  qize

理解flexible.js所需的viewport知识

qize  · 掘金  · 前端  · 2018-01-04 09:35

正文

viewport探索 flexible.js解读

www.quirksmode.org/mob...
www.quirksmode.org/mob...
www.quirksmode.org/mob...
www.w3cplus.com/mobile...

这在这篇文章介绍了viewport的三种视口 visual layout ideal 、以及通过此三视口分析了淘宝的flexible.js方案的实现原理。

现代浏览器中实现缩放的方式,无怪乎都是「拉伸」像素。

在屏幕上,首先介绍的两个概念。「css像素」、「设备像素」

css像素与写在样式表中定义的宽的度量单位是一致的。

可以这么理解,css像素和设备像素 是容纳的关系。在缩放倍数是200%的情况下,1个css像素容纳了4个设备像素。。

缩放的作用就是改变一个css像素可以容纳设备像素的多少。

PC端

在正常情况下,一css像素等于一设备像素。放大到200%的情况下,一个css像素等于四个设备像素。(宽2倍 高2倍)

window.innerWidth

屏幕、页面有很多属性。

  • screen.width

  • window.innerWidth

  • document.documentElement.clientWidth

  • document.documentElement.offsetwidth

而这些属性的值的单位就是像素pixels。区别就是其中一些属性值的度量单位是「设备pixels」而大部分是「css pixels」

window.innerWidth度量的是浏览器窗口的宽度。度量单位是css pixels。

window.innerWidth的例子。

这是缩放100%的情况。header的宽1220px ,几乎沾满了浏览器屏幕宽度,window.innerWidth的值为1231px,根据这个现状很容易证明window.innerWidth的度量单位是css pixels。

现在将这个页面放大到200%。

我们发现现在的window.innerWidth变为了刚才的一半。就是因为这个属性的度量单位是css 像素(包含多少css像素),衡量css像素的直观大小,跟页面中的dom的css大小比较就ok。

看我们的页面,header还是1220px没有变。但是在浏览器中展示出来的却只有刚才的一半。由直观上的判断,目前浏览器窗口范围内的css宽的值为之前的一半。而这个值 就是当前window.innerWidth的值的大小。

一个dom元素的css在数值上大小不变,而设备的像素大小是物理值,也不变,所以也符合之前提到的。缩放实际改变的是一个css像素容纳的设备像素的多少。

viewport,用来约束网站中最顶级包含块元素 <html>

默认「body」的宽度取自「HTML」,而「HTML」的宽度取自「viewport」,「viewport」的宽度正好等于「浏览器」窗口的宽度。

可以把「viewport」当成比「html」更高一层的元素,不管我们有没有给「html」设置宽, document.documentElement.clientWidth 取到的都是「viewport」的宽。而 window.innerWidth 能取到「浏览器」窗口的宽。在PC端这两者的区别仅仅区分在 window.innerWidth 包含滚动条的宽。

这个定义有一个问题出现,红色背景设为100%宽,内元素设置min-width980px,当屏幕缩小到980以下时,会出现横向滚动条,但把滚动条右移就会发现背景缺失了。这就是因为100%的宽其实最大就是浏览器窗口的宽。当浏览器窗口小于980px时,红色背景也会缩小到小于980px,所以右划会出现空白。

offsetWidth

document.documentElement.offsetWidth 这个属性取得是html的宽度。(IE中度量的是viewport)

如果将html当做一个块级元素来讲,html的宽默认为父元素的100%,高度默认被子元素撑开。
所以默认情况下,offsetWidth取得值是继承于viewport的宽,而viewport的宽等于浏览器窗口的宽。
而offsetHeight的值默认由子元素的高决定。
显式书写了html的height或者width的时候,offsetHeight/width取的就是显式设置的值。

还有个情况就是设置html为100%的时候,实际上这个意思就是将html的高设置为viewport的高的100%,同理,viewport的高等于浏览器窗口的高。可以用window.innerHeight取得。

pc端小结

  1. window.innerWidth 的度量单位是「css像素」,表象的概念就是当前浏览器窗口包含了多少css像素大小的dom。

  2. 默认「body」的宽度取自「HTML」,而「HTML」的宽度取自「viewport」,「viewport」的宽度正好等于「浏览器」窗口的宽度。

移动端

  • layout viewport

  • visual viewport

layout viewport和visual viewport

layout viewport的概念其实跟pc端的viewport是一样的, 是作为html的”上层“元素 。将宽继承给html。html内的各元素都是以layout viewport为基准进行布局的。但跟pc端不同的是,pc端的viewport的宽是由浏览器的窗口的宽决定的,用户可以手动拖动窗口改变宽的大小。但是移动端的不同平台的浏览器呈现不同的layout viewport。

ios980px,android800px。

将visual viewport想象成覆盖手机屏幕的一个框,这个框带有类似pc端缩放的功能,而且这个框的度量单位也是css像素。这就意味着,在layout viewport不变的情况,我们能看到多少css像素的东西,取决于这个框的缩放程度。默认情况下。大多数移动端浏览器会将visual viewport这个框缩放到与layout viewport相同。

拿ios设备举例,layout viewport固定为980px,默认打开页面的情况下,visual viewport会将这个框缩放到980px。这样我们就能看到全部的内容了。

默认情况下html元素的宽取自layout viewport,那么不同机型浏览器的layout是不同的,ios980px,android800px。

所以在不设置任何条件的情况下,一个宽度是1220px的div在ios模拟器下是这样的。

html的宽继承自layout viewport,980px。多出的240px在layout viewport之外,需要通过滑动屏幕才能见到。

在pc端我们通过 document.documentElement.clientWidth 取得viewport的宽度。

但是移动端有layout和visual两个viewport,该怎么取值?

之前讲到了layout viewport的概念跟pc端的viewport相近,都是来约束html元素的宽的。即html元素是以layout viewport作为参考系进行布局的。所以这里的 document.documentElement.clientWidth 能获取到layout viewport的宽度尺寸。

在pc端是通过 window.innerWidth 来度量浏览器窗口的宽的,而在移动端,之前讲到的visual viewport模拟的那个框,就相当于浏览器的窗口。所以在移动端可以通过 window.innerWidth 来取得visual viewport的宽。其值会根据缩放的程度而改变。读到的值为当前屏幕上x方向的css像素的值。

在pc端我们总结过 window.innerWidth document.documentElement.clientWidth 在缩放不同的情况下只是相差一个滚动条的宽度。但是在移动端, window.innerWidth(visual viewport) document.documentElement.clientWidth(layout viewport) 在缩放的情况下值是不同的。原因在于移动端的 document.documentElement.clientWidth(layout viewport) 总是固定的。

viewport meta标签

width:控制 layout viewport 的大小。
height:和 width 相对应,指定高度。
initial-scale:初始缩放比例,也即是当页面第一次 load 的时候缩放比例。
maximum-scale:允许用户缩放到的最大比例。
minimum-scale:允许用户缩放到的最小比例。
user-scalable:用户是否可以手动缩放

width 设置layout viewport的宽度

为什么要设置这个属性?

我们之前提到过在原始的页面上visual viewport会自动将视口缩放到与layout viewport同宽,这样就能看到全部的内容,用户自然会放大页面,但是遇到较长的文字段落需要将屏幕左右滑动才能阅读完全。在没有viewport meta标签之前可以这样优化。







请到「今天看啥」查看全文


推荐文章
吉林市场监管  ·  3·15优化消费环境 市场监管在行动 ⑦|辉南县
14 小时前
吉林市场监管  ·  3·15优化消费环境 市场监管在行动 ⑦|辉南县
14 小时前
前端早读课  ·  【早阅】Vibe Coding 宣言
昨天
青云说说  ·  如何定义好酒?
昨天
青云说说  ·  如何定义好酒?
昨天
ZOL中关村在线  ·  怼完Intel又怼NVIDIA!AMD新显卡秒GTX 1080
8 年前
环球时报  ·  国足请贝克汉姆当技术顾问?
7 年前