起首
屏幕是由一个一个显现单元构成的.
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, 如许比例一直为 1devicePixelRatio 在差别的装备中有差别
假定 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)