需求背景
目前组内使用的移动端适配方案是基于rem
的flexible
方案,其他组想要使用任务中心的部分样式代码,但是不确定其他组是否也使用flexible
方案。就算用的是flexible
方案,也不确定使用的转换单位是否一致,所以就试着用一下和js解耦的vw布局方案。
参考文章
知乎的一篇文章,ts的部分可以先无视掉https://zhuanlan.zhihu.com/p/36913200。
vw是啥请自行搜索MDN
简介
比起rem方案vw方案的问题就是兼容性,但是从caniuse提供的信息来看安卓4.4+,iOS7+的兼容性已经符合客户端的兼容要求了。
postcss插件
文章中提到的插件有postcss-aspect-ratio-mini postcss-px-to-viewport postcss-write-svg postcss-cssnext postcss-viewport-units cssnano
,postcss-aspect-ratio-mini
是用来固定长宽比的插件,postcss-write-svg
是用来绘制移动端1px用的,postcss-cssnext
是用来支持一些新css写法的,postcss-viewport-units
是用来提供vw兼容的,cssnano
是用来去除无用css的,实际上其中核心插件是postcss-px-to-viewport
。
postcss-px-to-viewport配置
GitHub上有中文readmehttps://github.com/evrone/postcss-px-to-viewport/blob/master/README_CN.md
我用的设置,基本是参考知乎的那篇文章来的。
'postcss-px-to-viewport': {
viewportWidth: 750, // 设计稿宽度
unitPrecision: 3, // px to vw无法整除时,保留几位小数
viewportUnit: 'vw', // 希望使用的视口单位
fontViewportUnit: 'vw', // 字体使用的视口单位
selectorBlackList: ['.ignore', '.hairlines'], // 不转换的类名
minPixelValue: 1, // 小于1px不转换
mediaQuery: false // 允许媒体查询中转换
},
切换时遇到的问题
因为之前采用的是基于rem
的flexible
方案,所以在代码中使用了rpx这种非标准单位,不经过打包工具处理的话是不能在浏览器中正常显示出来的。看原意postcss-px-to-viewport
应该是想通过minPixelValue
或者selectorBlackList
的配置项来解决展示真实像素的需求,所以postcss-px-to-viewport
插件不会处理rpx
直接导致css样式失效。解决方案其实有两个
使用PX,Px,pX这种非标准单位
在这两个插件中都不会对PX
,Px
,pX
这种非标准单位进行处理,因为HTML是大小写不敏感的所以在HTML中是可以生效的,但是副作用目前发现的就有两个。
- 在vue模板等处理环境中会被认为是错误而失效,虽然一般是用在css里的所以感觉问题也不大。
- 原有代码使用rpx,要进行全局替换代码无法和rem方案共存。
好处是可以顺带消灭rpx
在ide中无法识别导致的一些手贱格式化后样式失效的问题。
先过一遍postcss-px-to-viewport再过postcss-plugins-px2rem
先用postcss-px-to-viewport
处理转换px为vw,剩下的rpx让postcss-plugins-px2rem
去处理为px。
- 优点,两种打包方案可以共存,通过打包时传入不同参数即可切换。
- 缺点,要进行一下骚操作,因为如果是自己用合并方式塞插件配置进postcss会出现执行顺序不一致的问题,所以实现的时候是反过来的,当为vw打包方式时删掉vw相关的插件配置。