首先,屏幕是由一个个显示单元组成的。1.每个显示单元都是物理世界中的真实存在;2、显示单元的大小称为“物理像素”;3、通常我们所说的“分辨率”,是指一块屏幕上显示单元的个数,比如750cross1334,就是说这块屏幕是由750个十字和1334个显示单元组成的。其次,一般情况下,1个显示单位在计算机系统中对应1px。也就是说,如果你设置元素的高度:100px;屏幕中将有100个显示单元来渲染它。那么有一种情况就是在同样尺寸的屏幕下,屏幕分辨率是不同的,一个分辨率是A,另一个分辨率是2A---因为我们可以把显示单元做得更小,出现这种情况,就会有如果我们维护它会产生以下影响:1px在计算机系统中对应一个物理显示单元。那么同样的页面在A中是正常显示的,但是在2A的情况下只会显示一半。这种情况是绝对不可能的。所以我们需要处理这种情况:浏览器提供了一个devicePixelRatio(设备像素比)属性,用来标记:标准显示单元的大小/当前设备显示单元的大小并指定两条规则:1pxalways对应1个显示单元。一个标准显示单元的大小是x,其他显示单元可能是1/2x,1/3x我们可以通过判断这个值来调整我们使用的px的大小,例如:在devicePixelRatio=1的设备中,元素a的宽度为100px;在devicePixelRatio=2的设备中,元素a的宽度为200px;ok,那我们来做吧。根据不同的devicePixelRatio调整元素的样式。varbox=document.querySelector('.box');varheight=parseInt(getComputedStyle(box).height);varwidth=parseInt(getComputedStyle(box).width);box.style.height=height*parseInt(window.devicePixelRatio)+'px';box.style.width=宽度*parseInt(window.devicePixelRatio)+'px';这只是一个元素的两个属性,1000个元素,每个元素有5个属性,可以让你哭泣。所以这种处理是肯定不允许的。然后我们发现了rem这个单元。它的简单解释:当你给一个元素A设置height:2rem时,它会找到根节点(html)的font-size值,比如16px然后取16*2=32px作为元素的最终高度A、这个可以用来让元素以rem为单位,然后控制根元素的font-size值。在不同的devicePixelRatio下,呈现不同的值。例如:devicePixelRatio=1,font-size(root)=100px;devicePixelRatio=2,font-size(root)=200px;这时候元素会自动响应大小的变化。好的,让我们开始吧:varfontSize=100*parseInt(window.devicePixelRatio)+'px';document.documentElement.style.fontSize=fontSize;嗯,效果不错,我们可以实现不同分辨率下的同一个页面。然后你会一直觉得PC上的100px和你的devicePixelRatio=2一样,200px的大小不一致,按理来说应该是一致的。这确实是不一致的。首先,我们要明确一个浏览器可视区域(visualviewport)的概念。我们之前说过,‘1px在计算机系统中总是对应1个物理显示单元’对应的是一个分辨率为750*1334的屏幕。我们也可以这样描述:屏幕的尺寸是750px*1334px。上面说了,物理尺寸相同的屏幕,分辨率可能不同,因为显示单元的数量不同。所以这里的750px在标准下可能只有375px;另一个概念:idealviewport,意思是:以标准显示单元为单位时,当前设备的大小。比如750*xrate的分辨率,devicePixelRatio=2,那么会显示single元素下方,宽度为375px*x/2最后提一下布局视口,这也是大小不一致的原因:PC没有完全显示在iPhone上。这部分可以通过滚动条来解决。但是使用百分比布局的页面是作弊的。原本在PC浏览器上拥有的20%,在iPhone上只有一点点,布局完全乱了。这是一个坑。为了解决这个问题,开发者提出了一个新的概念:'layoutviewport'布局视口的默认大小为980px,默认缩放到与视觉视口区域相同的大小。在这种情况下,我们可以计算出布局视口下,一个100px宽度的元素,对应视觉视口下方的宽度xlayoutviewport/visualviewport=ele-width(layoutviewport)/x是x=ele-width(layoutviewport)*(布局视口/视觉视口);低于理想的视口宽度,只需除以设备像素比。很明显,当width(layoutviewport)=width(visualviewport)时,两个视口中元素的宽度值是相等的。width(visualviewport)/devicePixelRatio=理想视口中元素的大小。而我们的终极追求是,当你写下100px的时候,任何devicePixelRatio下的size都是一样的。要做到这一点,我们必须做到以下几点理想视口下的尺寸始终保持一致。理想视口下元素尺寸的计算公式为:(ele-width(layoutviewport)*(layoutviewport/visualviewport))/devicePixelRatio;因为不同设备的视觉viewport的值是不同的,我们可以控制layoutviewport的大小总是等于visualviewport,这样比例总是1devicePixelRatio,不同的设备有不同的假设ele-width(idealviewport)=x;设备像素比=n;然后ele-width(layoutviewport)=nx;所以我们只需要保证ele-width的宽度总是nx即可,因为通常我们知道x。如何?通过metaname=控制layoutviewport的大小始终等于visualviewportinitial-scale控制“viewport”内容的initial-scale=1,layoutviewport的宽度为375(与idealviewport相同)initial-scale=2,布局视口的宽度为188initial-scale=0.5,布局视口的宽度为750;所以结论是:当initial-scale的值为1/devicePixelRatio时,width(layoutviewport)=width(visualviewport)2通过rem,根据不同的devicePixelRatio设置根节点的font-size值,来控制nx值的大小。然后你需要给一个基准值:at750(visualviewport),devicePixelRatio=2,root(font-size)=200px;如果都做到这里,那么至少可以实现:不同devicePixelRatio下的元素大小是一样的。但是还有一个问题,当前页面是按照750(视觉视口)来定义的,也就是说,当你的设备实际只有640(视觉视口)时,你的整个页面还是750px,会出现滚动条.所以我们想按比例缩放它。怎么做?直接按比例缩放root(font-size)的值:750/200=640/xx=640/(750/200)
