vh、vw、rem究极适配方案

实现不同倍率设计图同时用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;
  //
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值