最近在工作中发现华为部分机型遇到一个移动端适配的兼容性问题
场景: 华为部分机型的微信浏览器
不兼容的适配方案:amfe-flexible + postcss-px2rem
具体表现: 并没有根据视图宽度动态适配,且目前只出现在微信浏览器,华为内置浏览器表现正常
不兼容原因分析:
我想 px to rem 这一部分一定是执行的,且现代浏览器rem不至于失效或不支持,可以排除这类问题,那么问题大概率出在amfe-flexible
上。
amfe-flexible 做了什么:
在分析问题前我们先来看看 amfe-flexible
为我们做了什么。我们之所以要使用postcss-px2rem
来把px单位转化为rem,是想利用rem的特性通过动态计算设置根元素的fonts-size
来达到动态适配的目的,在这整个过程中我们需要做两点,第一是让根元素的fonts-size
属性根据视图大小动态计算改变,第二将我们编写的px单位计算成我们配置好比例的rem单位。而amfe-flexible
就为我们做了第一步。
具体我们来看看它的源码:
var docEl = document.documentElement
// set 1rem = viewWidth / 10
function setRemUnit () {
var rem = docEl.clientWidth / 10
docEl.style.fontSize = rem + 'px'
}
setRemUnit()
// reset rem unit on page resize
window.addEventListener('resize', setRemUnit)
window.addEventListener('pageshow', function (e) {
if (e.persisted) {
setRemUnit()
}
})
代码还是很容易理解,主要是监听了window
视图的resize
事件,通过计算根元素 document.documentElement
的 clientWidth
,已一定的比例设置根元素的font-size
属性,这里默认设置里1:10,也就是说,子元素设置10rem的宽度即达到满屏的宽度,而我想出现问题的机型定是在这里的某个环节出现了问题。
至此,我们清楚了,其实要达到移动端适配的目的最重要的因素的一个动态性的参考,像是rem利用根元素的字体大小。那如果这一动态变化的参考出现了问题,我们是不是考虑替换这个参考,于是我们想到了现代浏览器的天生优势——viewport,一个根据视图动态变化的参考单位,简直是为移动端适配量身打造,因为我们的场景是在移动端,所以viewport支持性还是比较好的。
那我们来看下如何使用这个px to viewport方案,用法很简单,如果你之前使用的是px to rem方案,那可以完美迁移。
首先我们要安装一下 postcss-px-to-viewport
npm i postcss-px-to-viewport --save-dev
然后配置postcss.config,js(注意注释之前的px2rem配置),我这里列举了比较有用的几个参数配置,详细可参考原作者文档 -> postcss-px-to-viewport
// postcss.config,js
module.exports = {
'plugins': {
'postcss-px-to-viewport': {
unitToConvert: 'px', // 需要转换的单位,默认为 px
viewportWidth: 750, // 设计稿的视口宽度
unitPrecision: 3, // 单位转换后保留的精度
viewportUnit: 'vw', // 希望使用的视口单位
selectorBlackList: [], // 需要忽略的CSS选择器
minPixelValue: 1, // 设置最小的转换数值
mediaQuery: true, // 媒体查询中的单位是否需要转换
exclude: /vant/i, // 忽略某些文件夹下的文件或特定文件
}
}
}
最后重新跑一下项目即可看到效果。
Happy coding~