px转rem的填坑之路

这是要为一个vue项目做自适应,设计稿是1920*1080的,要适应各种手机、ipad、3840*2160的超大屏,所以就选择了rem,包用的是 postcss-pxtorem

在适配的时候遇到了很多问题,初版是这样的:

// 设计稿以1920px为宽度
function setRem() {
  const htmlWidth = document.documentElement.clientWidth || document.body.clientWidth;
  const htmlHeight = document.documentElement.clientHeight || document.body.clientHeight;

  let baseSize = 192;
  let scale = htmlWidth / 1920;
  document.documentElement.style.fontSize = (baseSize * scale) + 'px';
}

setRem();

window.addEventListener('resize', () => {
  setRem();
});

.postcssrc.js文件是这样配置的:

module.exports = {
  "plugins": {
    // to edit target browsers: use "browserslist" field in package.json
    "autoprefixer": {},
    "postcss-pxtorem": {
      "rootValue": 192,
      "propList": ["*"],
      "selectorBlackList": ["weui-"]
    }
  }
}
rootValue的值就是设计稿的宽度/10。
我以为大功告成了,各种想不到的问题就出现了:
1.页面一打开就出现高度滚动条,复现条件:pc端
这个原因是因为rem布局是以宽度为基准的,比如我电脑的屏幕是1920*1080的,但是往往浏览页面的时候,浏览器给的宽度都是给够的,但是高度不够,比如浏览器的头部、电脑任务栏,这些都会抢占页面的高度。而rem计算又是以宽度为基准的,滚动条就出现了:
解决办法:计算设计稿跟实际的宽高比
  const designRatio = 1920 / 1080;
  const realRatio = htmlWidth / htmlHeight;
// 存在宽度够了,高度不够的情况
  if (realRatio > designRatio) {
    document.documentElement.style.fontSize = (baseSize * Math.min(scale, 2)) * (designRatio / realRatio) + 'px'
  }

好了,现在 在各种iPhone7、8,以及pc端都没问题,结果又出问题了:

在部分安卓手机会出现样式错乱:

原因:用户设置了系统字体大小

这一部分可以参考这个博客解决: rem在webview中错乱

 

整体代码:

/**
 * 以1920设计稿为准
 */
function setRem() {
  const htmlWidth = document.documentElement.clientWidth || document.body.clientWidth;
  const htmlHeight = document.documentElement.clientHeight || document.body.clientHeight;
  const designRatio = 1920 / 1080;
  const realRatio = htmlWidth / htmlHeight;

  let baseSize = 192;
  let scale = htmlWidth / 1920;
  document.documentElement.style.fontSize = (baseSize * Math.min(scale, 2)) + 'px';

  // 防止用户设置系统字体大小
  let computedFontSize = parseFloat(window.getComputedStyle(document.documentElement).fontSize);
  let configFontSize = parseFloat(document.documentElement.style.fontSize);
  document.documentElement.style.fontSize = (configFontSize * configFontSize / computedFontSize) + 'px';

  // 存在宽度够了,高度不够的情况
  if (realRatio > designRatio) {
    document.documentElement.style.fontSize = (baseSize * Math.min(scale, 2)) * (designRatio / realRatio) + 'px'
  }
}

setRem();

window.addEventListener('resize', () => {
  setRem();
});

 



posted @ 2020-03-18 10:45  Sofiaღ  阅读(556)  评论(0编辑  收藏  举报