• 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();
    });


  • 相关阅读:
    参考阿里规范,优秀的 Java 项目代码该如何分层?
    SpringBoot 中实现跨域的5种方式
    美团一面:你既然写过Mybatis插件,说说它底层是怎么加载一个自定义插件的
    陌陌面试官:说说Spring AOP 的原理、SpringMVC 的处理过程?
    这16条规范代码,同事,拍桌子 大喊 “666”
    微服务很简单,用一张架构图了解一下
    K8S部署Metrics-Server服务
    cookie
    html标签默认样式整理
    html 语义化标签
  • 原文地址:https://www.cnblogs.com/caoshufang/p/12515928.html
Copyright © 2020-2023  润新知