viewport 的明白

起首

屏幕是由一个一个显现单元构成的.
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 即可.

很明显的看出来:

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

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

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

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


( ele-width(layout viewport) * (layout viewport / visual viewport) ) / devicePixelRatio;
  1. 由于差别的装备的 visual viewport 的值是差别的, 我们能够掌握让 layout viewport 的大小一直
    即是 visual viewport, 如许比例一直为 1

  2. devicePixelRatio 在差别的装备中有差别

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

所以我们只需保证, ele-width 的宽度, 一直为 nx 即可, 由于平常状况下我们是晓得 x 的.

how?

  1. 掌握 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://segmentfault.com/a/1190000009861458
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞