Skip to content
本页目录

Rem 与 vw 方案实现移动端适配

REM 方案

目前项目中一直使用的是阿里的 lib-flexible 方案, 它会自动在 htmlhead 中添加一个 meta name="viewport" 的标签,同时会自动设置 htmlfont-size 为屏幕宽度除以 10,也就是 1rem 等于html根节点的 font-size

js
function setRemUnit () {
    var rem = docEl.clientWidth / 10
    docEl.style.fontSize = rem + 'px'
}
function setRemUnit () {
    var rem = docEl.clientWidth / 10
    docEl.style.fontSize = rem + 'px'
}

假如设计稿的宽度是 750px,此时 1rem 应该等于 75px。假如量的某个元素的宽度是 50px,那么在 css 里面定义这个元素的宽度就是 width: 2rem。但是当分辨率大于某个特定值时,它便不再生效。

项目配置:

  1. 安装 lib-flexible
npm install lib-flexible --save-dev
npm install lib-flexible --save-dev
  1. 引入 lib-flexible
JS
// main.js
import 'lib-flexible'
// main.js
import 'lib-flexible'
  1. 安装 px2rem-loader 自动将 css 中的 px 转换成 rem
npm install px2rem-loader --save-dev
npm install px2rem-loader --save-dev
  1. 配置
js
chainWebpack: (config) => {
    config.module
      .rule("scss")
      .oneOf("vue")
      .use("px2rem")
      .loader("px2rem-loader")
      .before("postcss-loader")
      .options({
        remUnit: 75, // 以设计稿750为例, 750 / 10 = 75
        remPrecision: 8, // 小数点精度
      })
      .end()
},
chainWebpack: (config) => {
    config.module
      .rule("scss")
      .oneOf("vue")
      .use("px2rem")
      .loader("px2rem-loader")
      .before("postcss-loader")
      .options({
        remUnit: 75, // 以设计稿750为例, 750 / 10 = 75
        remPrecision: 8, // 小数点精度
      })
      .end()
},

缺点:

  • 可能存在精度换算问题
  • 提供的 /* no */ 注释不转换的方法,其注释会在预处理器中处理掉导致不生效

引申:vant 组件库是基于 375pxrem 方案实现的,我们项目中一般使用的是 750px 方案,会产生冲突,vant 官方文档给出了解决方案,通过改写 postcss.config.js 文件实现

JS
module.exports = {
  "plugins": {
    "postcss-pxtorem": {
      rootValue({ file }) {
        return file.indexOf('vant') !== -1 ? 37.5 : 75;
      },
      propList: ['*'] // 需要被转换的属性
    }
  }
}
module.exports = {
  "plugins": {
    "postcss-pxtorem": {
      rootValue({ file }) {
        return file.indexOf('vant') !== -1 ? 37.5 : 75;
      },
      propList: ['*'] // 需要被转换的属性
    }
  }
}

vw 方案