实现不同倍率设计图同时用px开发,使用vw vh 与 rem 共存方式解决问题。
在开发中经常会用到ui框架,本例使用vant ui框架。
一般我们在移动端项目开发中都会使用px然后通过postcss 转换成 rem或vw vh 进行适配
,但是遇到ui框架与设计图像素倍率不同的时候,都会选择修改设计图像素倍率进行兼容ui框架。
或者也有人使用postcss的 selectorBlackList: ['vant'], exclude: /(\/|\\)(node_modules)(\/|\\)/
进行忽略第三方插件样式。这也是一个方法,但是你忽略掉第三方框架后,如果样式需要根据设计图调整,那么就要把第三方插件的样式写成rem,或者vw vh。不可以直接写px进行转换。
这里进行介绍,兼容两种不同倍率的ui界面 同时集成在一个项目里面,实现同时使用px开发,用以方便修改ui框架css。
// 我们项目使用的是375/根font-size:16px的设计图。 以下是vue-cli3的postcss.config.js的配置
module.exports = {
plugins: {
'postcss-import': {},
'postcss-url': {},
'postcss-aspect-ratio-mini': {},
'postcss-write-svg': {
utf8: false
},
autoprefixer: {},
'postcss-preset-env': {},
'postcss-px-to-viewport-opt': {
viewportWidth: 750, // 设计稿宽度
viewportHeight: 1334, // 设计稿高度,可以不指定
unitPrecision: 3, // px to vw无法整除时,保留几位小数
viewportUnit: 'vw', // 转换成vw单位
selectorBlackList: ['vant'], // 不转换的类名,这里忽略掉项目中的vant框架
minPixelValue: 1, // 小于1px不转换
mediaQuery: false, // 允许媒体查询中转换
exclude: /(\/|\\)(node_modules)(\/|\\)/ // 排除node_modules文件中第三方css文件
},
// 这里设置ui框架使用px转成rem的方式进行兼容设备。
'postcss-pxtorem': {
rootValue: 16, // 根据项目与ui框架的像素倍率来设置。
propList: ['*']
},
// 'postcss-viewport-units': {
// // 解决content 伪属性的 问题
// filterRule: rule => rule.nodes.findIndex(i => i.prop === 'content') === -1,
// },
cssnano: {
preset: 'advanced',
autoprefixer: false, // 和cssnext同样具有autoprefixer,保留一个
'postcss-zindex': false
}
}
};
编写rem.js
// 这里是px转rem代码
const baseSize = 16;
// 设置 rem 函数
function setRem() {
// 当前页面宽度相对于 750 宽的缩放比例,可根据自己需要修改。
const scale = document.documentElement.clientWidth / 375;
// 设置页面根节点字体大小
document.documentElement.style.fontSize = baseSize * Math.min(scale, 2) + 'px';
}
// 初始化
setRem();
// 改变窗口大小时重新设置 rem
window.onresize = function() {
setRem();
};
以上使用的是vant框架给出的rem适配,当然网上有很多适配方案,以下是另一种。
/**
* @desc 设置根据界面宽度375比16px进行响应式适配。如果嫌麻烦,也可以直接使用 postcss-pxtorem 设置"selectorBlackList":[".ignore",".hairlines","van"],忽略框架代码(本例不建议)。
*/
// (function (doc, win) {
// var docEl = doc.documentElement,
// resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
// recalc = function () {
// var clientWidth = docEl.clientWidth;
// if (!clientWidth) return;
// docEl.style.fontSize = 16 * (clientWidth / 375) + 'px';
// };
// if (!doc.addEventListener) return;
// win.addEventListener(resizeEvt, recalc, false);
// doc.addEventListener('DOMContentLoaded', recalc, false);
// })(document, window);
以上便解决了两种不同倍率设计图的兼容,并同时使用postcss进行设备适配。
// 某些设备不支持vwvh,这时候可以使用以下代码进行兼容。
1. 引入cdn
<!-- 兼容无法使用vwvh的设备,自动转换px -->
<script src="https://g.alicdn.com/fdilab/lib3rd/viewport-units-buggyfill/0.6.2/??viewport-units-buggyfill.hacks.min.js,viewport-units-buggyfill.min.js"></script>
2. 把以下代码加到rem.js
window.onload = function() {
// 兼容vh写法的插件
window.viewportUnitsBuggyfill.init({ hacks: window.viewportUnitsBuggyfillHacks });
// var winDPI = window.devicePixelRatio;
// var uAgent = window.navigator.userAgent;
// var screenHeight = window.screen.height;
// var screenWidth = window.screen.width;
// var winWidth = window.innerWidth;
//
};