flexible.js-移动端H5页面适配应用

3,387 阅读3分钟

前端页面适配有两大方向:一是布局适配,可以使PC、手机、平板共用一份代码,实现方法有css 媒体查询、css 弹性盒子布局、 css grid布局等。二是高清适配,面对的是移动开发中设备不同分辨率和不同尺寸,最大限度还原设计稿效果。

flexible.js是高清适配的一种方法,它通过javascript根据不同设备的dpr值和设备宽度为html动态设置font-size,其他元素使用rem做单位。

原理:

与flexible密切相关的是dpr概念,有以下公式:

dpr(设备像素比) = 物理像素(屏幕像素) / 设备独立像素(css像素)

普通屏幕dpr为1,高清屏幕的dpr为2或者更高。我们样式代码上定义的元素大小是css像素,因此意味着普通屏和高清屏上展现的像素会有不同。例如

width:2px; height:2px在普通屏上物理像素是 2X2=4,在高清屏上则是(2X2)X(2X2)=16

这一现象带来了图片高清问题:由于图片像素是物理像素,如果以普通屏为标准制图(一倍图)在高清屏上展示会导致放大模糊(1个像素放大为4个),如果以高清屏为标准制图(二倍图)在普通屏上显示会导致缩小(4个像素缩小到1个)。因此完美的办法是UI提供1倍图和2倍图,前端通过代码适配:

1. css media
@media screen and (-webkit-min-device-pixel-ratio: 2) {}
2. img srcset
<img width="100" height="100" src="image100.png" srcset="image200.png 2x,image300.png 3x"/>

同样也会带来字体和元素大小的问题,但显然不能再使用媒体查询的方式来适配,适配代码太多了,这时可以引入 flexible 的方式。

flexible的原理就是rem ,rem是CSS3新增的相对长度单位,是指相对于根元素html的font-size标准值的大小。

通常为了兼容第三方插件的样式,我们想以原始比例显示页面,并且不允许用户修改,所以都会设置页面缩放scale=1,flexible再设置dpr = parseInt(1/scale)=1如下:

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">

根元素html的font-size标准值 = document.documentElement.clientWidth * dpr / n 这里的n可自由设定,flexible将n定为10,从而使元素大小适配不同手机屏幕尺寸和dpr

  • iPhone3gs: 320px / 10 = 32x
  • iPhone6: 375px / 10 = 37.5px

元素通过rem单位来设置,从而实现了屏幕适配。例如设置div width:10rem;在iPhone3gs上表示320px,在iPhone6上表示375px,都实现了铺满屏幕宽度。

最后flexible会监听resize事件重新计算html的font-size flexible仓库

  • 单位换算

我们从设计稿得到的尺寸是px为单位的,如果要换算成rem作单位需要依赖编译器插件,而且会出现小数的情况。所以可以自定义flexible.js文件,将计算font-size标准值的n定为3.75,这样可以使得在高清屏中1rem = 100px, 这样只需心算一下就能换算单位了。

  • 自动编译

px2rem-loader : webpack加载器,将px换算rem

gulp-px3rem : gulp插件,将px换算rem

参考资料

解惑好文:移动端H5页面高清多屏适配方案

flexible.js如何实现rem自适应