zoukankan      html  css  js  c++  java
  • 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();
    });


  • 相关阅读:
    Centos7 下 PHP 添加缺少的组件 sockets 和 openssl
    vue使用 video.js动态切换视频源视频源不刷新问题
    vue+js清除定时器
    获取ip地址,并根据ip获取当前省份
    html页面引用video.js播放m3u8格式视频
    uniapp每隔几秒执行一下网络请求(h5端亲测可以,其他端未测试)
    关于uniapp获取当前距离屏幕顶部的距离
    按值传递与按值引用详解(java版)
    JavaScript的深入理解(1)
    vue-cli3配置webpack-bundle-analyzer插件
  • 原文地址:https://www.cnblogs.com/caoshufang/p/12515928.html
Copyright © 2011-2022 走看看