为什么需要适配
一些基本概念
一个屏幕的DPR是根据屏幕的物理像素除以屏幕的设备独立像素(也叫密度无关像素)得来的(DPR = 物理像素 / 设备独立像素)。iphone6宽度的设备独立像素是375,宽度的物理像素是750,那么就意味着DPR是2。这就意味着需要四个物理像素来描绘一个设备独立像素,就像一个田(请忽略边框)的形状。
设备独立像素又叫做密度无关像素,可以认为是系统中一个点,这个点可以是可以由程序使用的虚拟像素(如CSS的px),然后系统会将这个像素转换为物理像素,在屏幕的DPR为2的设备上CSS的1px就会转为4个物理像素。
屏幕密度(PPI),通常是计算每英寸有多少个像素(设备独立像素),计算公式是:屏幕斜对角的像素数除以屏幕的英寸得出PPI的值。
对一开始适配问题做出一定程度的解释
根据上面DPR解释可以知道在DPR为2的屏幕上会使用四个设备像素来描述一个CSS像素。在这种情况下一张100*100的图片在页面上的尺寸也是100*100那么其实是200*200个物理像素来描绘这张图片,很明显图片的像素是不够的,这时候系统就会让剩下的像素就近取色,这样就造成了图片的模糊,想要图片不模糊要么提供一个200*200的图片,要么将页面上100*100的容器缩小到50*50。
在DPR为2的屏幕上高度的1px其实是由2个物理像素描绘的,所以该屏幕可以描绘的最小像素应该是0.5px,所以这个1px应该是0.5px才对。
怎么做适配
既然提出了问题那么就需要解决,解决方案主要来自手淘的flexibleJS,其原理就是适配不同屏幕尺寸主要用到了rem,而适配不同的DPR主要用到了
不同屏幕尺寸
<div class='container'>
div> <style> .container {
width: 1rem; /* (100px / 100)rem */ height: 1rem; /* (100px / 100)rem */ }
style> <script> document.querySelector('html').style = 'font-size: ' + document.documentElement.clientWidth / 750 /* 设计稿尺寸 */ * 100 /* 将1rem对应的font-size值放大 */) + 'px'
script>
不同DPR
- 将整个页面的基础单位,也就是rem放大 DPR倍
- 使用meta name=“viewport” 将整个页面缩小到 1 / DPR
这样就可以保证一个物理像素对应一个逻辑像素,让整个画面看起来清晰很多。
function adapterHD (width = 750) {
const dpr = window.devicePixelRatio || 1 document.querySelector('meta[name="viewport"]').setAttribute("content", "width=device-width, initial-scale=" + 1 / dpr) const oneRem = Math.floor(document.documentElement.clientWidth / width * 100) document.querySelector('html').style = 'font-size: ' + (oneRem) + 'px' }
因为首先设置了缩放,缩放后 documentElement.clientWidth就会放大 DPR倍,所以onRem没有显式乘以DPR。
到这里还有两个问题需要解决:
- html元素被设置font-size之后因为font-size属性可以继承,整个网站的font-size默认都会变的很大,所以需要在body元素上重置下font-size属性
- 因为默认的font-size需要乘以100,所以在CSS中我们需要将设计稿上的尺寸除以100并且转换成rem单位,这个事情开发者手动去做十分繁琐且容易出错,所以可以用下面提到的postcss插件完成
flexibleJS
在引用上文提到的手淘的flexibleJS之后会自动设置html的font-size为75px,这时候的主要问题就是怎么将设计稿(一般都是750*1334)中的各个px值转换为rem。可以自己手动算(比较麻烦),可以使用编辑器插件,使用postcss插件等详情见使用Flexible实现手淘H5页面的终端适配
参考
移动端H5页面高清多屏适配方案
使用Flexible实现手淘H5页面的终端适配
viewports剖析
再聊移动端页面的适配
移动端Web页面适配方案
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/218585.html原文链接:https://javaforall.net
