postcss-px2rem配置

18,388 阅读1分钟

首先需要安装postcss-plugin-px2rem

npm install --save-dev postcss-plugin-px2rem

可以在package.json中配置

var px2rem = require('postcss-px2rem');

module.exports = {
  module: {
    loaders: [
      {
        test: /\.css$/,
        loader: "style-loader!css-loader!postcss-loader"
      }
    ]
  },
  postcss: function() {
    return [px2rem({remUnit: 75})];
  }
}

一般postcss建议单独配置在文件postcss.config.js中,

module.exports = {
  plugins: [
    require('autoprefixer')({ browsers: 'last 2 versions' }),
    require('postcss-px2rem')({remUnit: 75})
  ]
}

REM是根据根结点来计算各个子节点的值,所以根结点也要做响应式变化。定义一个utils/setRem.js

export default function setRem(baseWidth = 750) {
  const dpr = window.devicePixelRatio;
  const currentWidth = document.documentElement.clientWidth;
  let remSize = 0;
  let scale = 0;
  scale = currentWidth / baseWidth;
  remSize = baseWidth / 10;
  remSize = remSize * scale;
  document.documentElement.style.fontSize = remSize + 'px';
  document.documentElement.setAttribute('data-dpr', `${dpr}`);
}

index.js中引入即可

import setRem from './utils/setRem'
setRem()

考虑到CRA的webpack配置隐藏,我们使用react-app-rewired的配置该插件,

新建config-overrides.js文件,里面配置信息如下:

const { override, fixBabelImports, addPostcssPlugins } = require('customize-cra');

module.exports = override(
  fixBabelImports('import', {   //antd-mobile按需加载,不需要额外引入css文件
    libraryName: 'antd-mobile',
    style: 'css',
  }),
  addPostcssPlugins([require('postcss-plugin-px2rem')({ // rem 配置
    rootValue: 37.5,
    unitPrecision: 3,
    propWhiteList: [],
    propBlackList: [],
    selectorBlackList: [],
    ignoreIdentifier: false,
    replace: true,
    mediaQuery: false,
    minPixelValue: 0
  })])
);

另外REM是根据根结点来计算各个子节点的值我们使用阿里的amfe-flexible,新建utils/amfe-flexible.ts文件:

(function flexible(window, document) {
  var docEl = document.documentElement;
  var dpr = window.devicePixelRatio || 1;

  // adjust body font size
  function setBodyFontSize() {
    if (document.body) {
      document.body.style.fontSize = 12 * dpr + "px";
    } else {
      document.addEventListener("DOMContentLoaded", setBodyFontSize);
    }
  }
  setBodyFontSize();

  // set 1rem = viewWidth / 10
  function setRemUnit() {
    var rem = Math.min(docEl.clientWidth / 10, 50); // 最大 50
    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();
    }
  });

  // detect 0.5px supports
  if (dpr >= 2) {
    var fakeBody = document.createElement("body");
    var testElement = document.createElement("div");
    testElement.style.border = ".5px solid transparent";
    fakeBody.appendChild(testElement);
    docEl.appendChild(fakeBody);
    if (testElement.offsetHeight === 1) {
      docEl.classList.add("hairlines");
    }
    docEl.removeChild(fakeBody);
  }
})(window, document);

export default null;

在index.tsx中直接引入即可

import "./utils/amfe-flexible";

也可以使用 npm i -D amfe-flexible, 感兴趣的可以自己试验下!

gitHub地址: github.com/amfe/lib-fl…