资讯专栏INFORMATION COLUMN

viewport 的理解

UsherChen / 1726人阅读

摘要:首先屏幕是由一个一个显示单元组成的每一个显示单元都是物理世界真实存在的把一个显示单元的大小称为一个物理像素通常我们所说的分辨率就是指一块屏幕显示单元的个数比如叉表示这块屏幕由叉个显示单元组成其次通常情况下个显示单元对应计算机系统中的也就是说

首先

屏幕是由一个一个显示单元组成的.
1 每一个显示单元都是物理世界真实存在的;
2 把一个显示单元的大小称为一个"物理像素";
3 通常我们所说的 "分辨率", 就是指一块屏幕显示单元的个数, 比如 750 叉 1334, 表示这块屏幕由 750叉1334 个显示单元组成

其次

通常情况下, 1 个显示单元对应 计算机系统中的 1px.
也就是说, 如果你设置了一个元素的 height:100px; 在屏幕中会有 100个显示单元来渲染它.
后来出现了一种情况
在相同大小的屏幕下,
屏幕分辨率不一样, 一个分辨率是 A, 而另外一个分辨率是 2A --- 因为我们可以把显示单元做的更小了

这种情况的出现, 有如下的影响

如果我们维持着: 计算机系统中的 1px, 对应物理上的 1个显示单元.
那么同样一个页面, 在 A 显示正常, 在 2A 的情景下面, 就只会显示一半.

这种情况肯定是不可以的.所以我们需要针对这种情况做处理: 浏览器提供了一个 devicePixelRatio(设备像素比) 的属性, 用来标记:

标准显示单元的大小/当前设备的显示单元的大小

并且明确两条规则:

1px 始终对应 1个显示单元

标准的 1个显示单元大小为 x, 其他的显示单元, 可能是 1/2x, 1/3x

我们可以通过判断这个值, 来调整我们使用的 px 的大小,
比如:

devicePixelRatio = 1 的设备中, 元素a 的宽度为 100px;
devicePixelRatio = 2 的设备中, 元素a 的宽度为 200px;

ok, 那么我们来搞.
根据不同的 devicePixelRatio 来调整元素的样式.

    var box = document.querySelector(".box");
    
    var height = parseInt(getComputedStyle(box).height);
    var width = parseInt(getComputedStyle(box).width);

    box.style.height = height * parseInt(window.devicePixelRatio) + "px";
    box.style.width = width * parseInt(window.devicePixelRatio) + "px";

这仅仅是一个元素的两个属性, 1000个元素, 每个元素 5 个属性, 就可以让你哭掉了.
所以这种处理方式肯定是不可以的.

然后我们发现了 rem 单位.
它的简单解释:

当你给某个元素A 设置了 height:2rem 的时候
它会找到根节点(html) 的 font-size 值, 比如是 16px
然后拿 16 * 2 = 32px
作为元素A 的最终 height.

这个就可以利用了

让元素使用 rem 作单位

然后控制根元素的 font-size 值, 在不同的 devicePixelRatio 下面的时候, 呈现不同的值

比如:
    devicePixelRatio = 1, font-size(root) = 100px;
    devicePixelRatio = 2, font-size(root) = 200px;

元素在这个时候, 就会自动响应大小的变化.

好, 开始搞:

    var fontSize = 100 * parseInt(window.devicePixelRatio) + "px";
    document.documentElement.style.fontSize = fontSize;

嗯, 结果还是不错的, 在不同的分辨率下面, 我们也能实现页面相同了.
然后你会总是觉得, pc 上面的 100px, 和你 devicePixelRatio=2 的时候的 200px
的大小不一致的, 按道理来说应该是一致的.

的确不一致.

先明确一个概念
浏览器可视区域(visual viewport)
我们之前说了 "计算机系统中的 1px 始终对应 1个物理显示单元"
那么对应 750*1334 分辨率的屏幕, 我们同样可以这么描述它:

屏幕的大小为 750px*1334px.

前面已经说过了, 相同物理尺寸的屏幕, 分辨率可能不同, 因为显示单元的个数不同.
所以这里的 750px, 可能仅仅是标准下面的 375px;

另外一个概念:ideal viewport
它表示的是说:

当前设备, 使用标准显示单元为单位的时候的大小.

比如说 750*x 的分辨率, devicePixelRatio = 2,
那么它在标准显示单元下面, 宽度就是 375px * x/2

最后我们提一下 layout viewport, 这是为什么大小不一致的原因:

历史:

从 iPhone 发布前夕说起, 开发人员发现, 原本为 pc 开发的网页
在 iPhone 上面显示不全, 这部分可以通过滚动条来解决.
但是使用 百分比布局的页面就坑爹了, 原本在 pc 端浏览器上拥有
的 20% 在 iPhone 上面就一点点了, 布局完全乱了, 坑啊.
为了解决这个问题, 开发人员提出了一个的新的概念: "layout viewport"

layout viewport的默认大小为 980px, 并且默认缩放到和 visual viewport 区域一般大小.
在这种情况下, 我们可以计算出layout viewport下,
一个 100px 宽度的元素, 对应的 visual viewport 下面的宽度 x

layout viewport / visual viewport = ele-width(layout viewport) / x

也就是

x = ele-width(layout viewport) * (layout viewport / visual viewport);

ideal viewport 下面的宽度, 只要再除以 devicePixelRatio 即可.

很明显的看出来:

width(layout viewport) = width(visual viewport) 的时候, 两个 viewport 中的元素宽度值
是相等的.

width(visual viewport) / devicePixelRatio = ideal viewport 中的元素的大小.

而我们的最终追求, 就是
当你写下 100px 的时候, 在任何 devicePixelRatio 下面的大小都是一致的.
要做到这一点, 就要做到它们的 ideal viewport 下面的大小始终一致的.

而一个元素在 ideal viewport 下的大小的计算公式为:

( ele-width(layout viewport) * (layout viewport / visual viewport) ) / devicePixelRatio;

因为不同的设备的 visual viewport 的值是不同的, 我们可以控制让 layout viewport 的大小始终
等于 visual viewport, 这样比例始终为 1

devicePixelRatio 在不同的设备中有不同

假设 ele-width(ideal viewport) = x;
devicePixelRatio = n;
那么 ele-width(layout viewport) = nx;

所以我们只要保证, ele-width 的宽度, 始终为 nx 即可, 因为通常情况下我们是知道 x 的.

how?

控制 layout viewport 的大小始终等于 visual viewport
通过 meta name="viewport" 的 content 的 initial-scale 来控制.

initial-scale = 1 , layout viewport 的宽度为 375 (同ideal viewport)
initial-scale = 2 , layout viewport 的宽度为 188
initial-scale = 0.5, layout viewport 的宽度为 750;

所以得到的结论:

当 initial-scale 的值为 1/devicePixelRatio 的时候, 
width(layout viewport) = width(visual viewport)

2 通过 rem, 以及根据不同的 devicePixelRatio 设置 根节点的 font-size 值, 来控制 nx 的值的大小.
然后需要给出一份基准值:

在 750(visual viewport), devicePixelRatio = 2 的时候, 
root(font-size) = 200px;

如果都做到这里了, 那么至少可以达到:
在不同的 devicePixelRatio 下面元素的大小都是一致的.

但是依旧存在一个问题, 当前页面是基于 750 (visual viewport) 定义的, 也就是说
当你的设备实际上只有 640(visual viewport) 的时候,

你的整个页面还是 750px, 就会出现滚动条.

所以我们想要等比缩放一下.

如何操作?
直接等比缩放一下 root(font-size) 的值:

    750/200 = 640/x
    x = 640 / (750 / 200)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/112138.html

相关文章

  • 对于移动设备页面尺寸理解

    摘要:为移动设备制作前端页面,往往会遇到很多令人迷惑的情况,本文中,我整理了一些相关的概念和方法,与大家分享一下。所以现代针对移动端的网页设计或者响应式设计通常采用的方法是,精简页面内容,放大视觉元素,避免体验不好的缩放和移动页面。 为移动设备制作前端页面,往往会遇到很多令人迷惑的情况,本文中,我整理了一些相关的概念和方法,与大家分享一下。 设备像素和CSS像素 css像素是固定不变的...

    Magicer 评论0 收藏0
  • 对于移动设备页面尺寸理解

    摘要:为移动设备制作前端页面,往往会遇到很多令人迷惑的情况,本文中,我整理了一些相关的概念和方法,与大家分享一下。所以现代针对移动端的网页设计或者响应式设计通常采用的方法是,精简页面内容,放大视觉元素,避免体验不好的缩放和移动页面。 为移动设备制作前端页面,往往会遇到很多令人迷惑的情况,本文中,我整理了一些相关的概念和方法,与大家分享一下。 设备像素和CSS像素 css像素是固定不变的...

    leon 评论0 收藏0
  • 移动端开发系列——像素与viewport

    摘要:目录移动端开发的基本观点像素基础知识原理解析弹性布局响应式设计的运用移动端的事件库的使用移动端开发的基本观点移动端开发的意义移动端用户使用量市场需求市场供给公司需要移动端开发人才工资高,就业易涌现大波程序猿到了猴年马月,工资才会 目录 移动端开发的基本观点 像素基础知识 viewport原理解析 弹性布局 响应式设计 1rem的运用 移动端的事件 zepto库的使用 移动端开发的...

    JayChen 评论0 收藏0
  • 移动端开发系列——像素与viewport

    摘要:目录移动端开发的基本观点像素基础知识原理解析弹性布局响应式设计的运用移动端的事件库的使用移动端开发的基本观点移动端开发的意义移动端用户使用量市场需求市场供给公司需要移动端开发人才工资高,就业易涌现大波程序猿到了猴年马月,工资才会 目录 移动端开发的基本观点 像素基础知识 viewport原理解析 弹性布局 响应式设计 1rem的运用 移动端的事件 zepto库的使用 移动端开发的...

    lingdududu 评论0 收藏0
  • [技術分享] 理解 SVG 中 Viewport 和 ViewBox-拖曳與縮放功能實做(上)

    摘要:註在這篇文章中我們只考慮和為等比例的情況。最後實做出來的功能會像這樣子實做拖曳與縮放瞭解中的和在的世界中,空間的概念可以分成和兩個部分。實際感受的效果在她所撰寫文章中提供了非常好的實做案例。這個座標系統是相對固定的。 理解 SVG 中的 Viewport 和 ViewBox - 實做縮放(zoom)和拖曳(drag)效果 本文章同步刊載於 PJCHENder 前端網頁資源站 不同於以往...

    Leo_chen 评论0 收藏0
  • [技術分享] 理解 SVG 中 Viewport 和 ViewBox-拖曳與縮放功能實做(上)

    摘要:註在這篇文章中我們只考慮和為等比例的情況。最後實做出來的功能會像這樣子實做拖曳與縮放瞭解中的和在的世界中,空間的概念可以分成和兩個部分。實際感受的效果在她所撰寫文章中提供了非常好的實做案例。這個座標系統是相對固定的。 理解 SVG 中的 Viewport 和 ViewBox - 實做縮放(zoom)和拖曳(drag)效果 本文章同步刊載於 PJCHENder 前端網頁資源站 不同於以往...

    AJie 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<