屏幕适配和像素级还原视觉稿是一个老生常谈的话题了,但是具体做到了这一点的线上项目并不多,相关技术并不复杂,只是老项目一但成形,改造成本不亚于重构整个项目。但是我们应该在新的项目中去实践这种技术,更好的还原视觉稿。
现有适配的方案
- 百分比布局 / Flex 布局
不同的屏幕宽度下布局不一致,宽屏下会布局被拉长,1px的边框使用hack的方式实现,例如:天猫 - 查询+REM
一定范围内固定的根字体大小,并不能完全适配所有手机屏幕,特别是Android手机,1px通过hack方式实现 - REM 布局
能保持布局一致,但高清适配需要结合其它方案,如:小米 - REM布局 + Flex布局 + 视口缩放
能灵活控制布局,也能高清适配,例如:手淘
其它布局方案及原理,这里不详细介绍了,如果有不明白的地方,请参考我之前写的 移动端高清屏适配方案
这里着重介绍如何应用实践 REM+视口缩放 的适配方案
高清适配
方案
手淘 Flexible.js 可伸缩布局方案
这两种方案都是动态的根据屏幕宽度和当前设置的DPR的值,设置根字体的大小。
首先给定一个rem参考值,比如100px,750的设计稿还原到iphone6下,就是缩放一倍,根字体大小为50px,但iphone6中DPR为2,为了适配高清,应将原来的750大小的页面缩放0.5倍,这样,按照根字体100px的标准切出来的图,在iphone6下就高清还原视觉稿了
为了适应不同的DPR和屏幕宽度就需要JS动态设置当前的viewport的缩放比例和根字体的大小了
PX转REM
由于我们动态的要的屏幕度设置了不同的根字体大小,并且需要界面随根字体大小而调整,所以需要将px单位转换为rem单位。
结合Webpack插件,安装 postcss-pxtorem 插件,自动转换px为rem,在webpack.config.js里新增pxtorem配置、代码如下:
const pxtorem = require('postcss-pxtorem'); |
rootValue
为初始根字体参照大小,
比如750的设计稿,rootValue
为 100px
, 那么750设计稿中,30px
会被转换为 0.3rem
如果是采用上面 flexible.js
的方案,那么750设计稿的根字根会被计算为75px,使用 postcss-pxtorem
时,rootValue
应该设置为 75px
当然也可以结合postcss的 px2rem
插件去做转换。
具体如何使用 flexible方案做适配,请查看大漠老师的教程使用Flexible实现手淘H5页面的终端适配
用来做适配的js必须在所有css引入之前加载
标注工具
Mark Man 部分功能收费
- 长度、坐标、矩形、颜色、文字标注
- 按Tab键自动测量
- 拖拽删除和调整
- 末尾是@2x的图自动缩小50%,以便测量
PxCool 免费且功能十分强大,智能标注绝对可以解放双手了,强烈推荐。
PxCool
除以上功能外还具有:
- 具有自动吸附
- 自动检测边距、字体类型、字体大小、颜色等等
这两个工具都是Adobe AIR程序,兼容Win与Mac平台
应用实践
第一步
在html模板的头部引用适配JS并执行
<head>
<meta charset="utf-8" />
<title>title</title>
<script>/** 高清方案脚本 */
!function(e){function t(a){if(i[a])return i[a].exports;var n=i[a]={exports:{},id:a,loaded:!1};return e[a].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var i={};return t.m=e,t.c=i,t.p="",t(0)}([function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var i=window;t["default"]=i.flex=function(e,t){var a=e||100,n=t||1,r=i.document,o=navigator.userAgent,d=o.match(/Android[\S\s]+AppleWebkit\/(\d{3})/i),l=o.match(/U3\/((\d+|\.){5,})/i),c=l&&parseInt(l[1].split(".").join(""),10)>=80,p=navigator.appVersion.match(/(iphone|ipad|ipod)/gi),s=i.devicePixelRatio||1;p||d&&d[1]>534||c||(s=1);var u=1/s,m=r.querySelector('meta[name="viewport"]');m||(m=r.createElement("meta"),m.setAttribute("name","viewport"),r.head.appendChild(m)),m.setAttribute("content","width=device-width,user-scalable=no,initial-scale="+u+",maximum-scale="+u+",minimum-scale="+u),r.documentElement.style.fontSize=a/2*s*n+"px"},e.exports=t["default"]}]);
flex(100, 1);
</script>
</head>
<body></body>
</html>
这里使用的是 antd mobile
的flex高清适配方案
第二步
使用px to rem 插件转换px
在 webpack.config.js
中添加插件
const pxtorem = require('postcss-pxtorem'); |
第三步
使用标注工具标注,按照标注图上的实际尺寸编写CSS,构建时,webpack或gulp借助插件自动将px转为rem。
另外,关于图片的高清适配,可以根当前的dpr的值,借助七牛的图片处理能加,使用不同的后缀加载不同的图片即可。
关于REM的参考标准
根字体应该设定为多少,并没有一定的标准,设置的根字体大小只是rem的参考标准,比如我的设计稿是750的宽度,那么根字体设置为100px,1rem就为100px,10px就等于0.1rem,这样设计稿上的尺寸就算不借助于工具也能心算出来,14px = .14rem,40px = .4rem,设置为100px的好处是可以心算出rem的值同时减少小数位。