Skip to content
目录

移动端适配解决方案

1、rem

js
// 首先是一个立即执行函数,执行时传入的参数是window和document
(function flexible(window, document) {
  var docEl = document.documentElement; // 返回文档的root元素
  var dpr = window.devicePixelRatio || 1;
  // 获取设备的dpr,即当前设置下物理像素与虚拟像素的比值

  // 调整body标签的fontSize,fontSize = (12 * dpr) + 'px'
  // 设置默认字体大小,默认的字体大小继承自body
  function setBodyFontSize() {
    if (document.body) {
      document.body.style.fontSize = 12 * dpr + "px";
    } else {
      document.addEventListener("DOMContentLoaded", setBodyFontSize);
    }
  }
  setBodyFontSize();

  // set 1rem = viewWidth / 10
  // 设置root元素的fontSize = 其clientWidth / 10 + ‘px’
  function setRemUnit() {
    var rem = docEl.clientWidth / 10;
    docEl.style.fontSize = rem + "px";
  }

  setRemUnit();

  // 当页面展示或重新设置大小的时候,触发重新
  window.addEventListener("resize", setRemUnit);
  window.addEventListener("pageshow", function(e) {
    if (e.persisted) {
      setRemUnit();
    }
  });

  // 检测0.5px的支持,支持则root元素的class中有hairlines
  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);
css
//以750为基准的设计稿
@function px2rem($px, $base: 75) {
  @return ($px / $base) * 1rem;
}
//稿子上量得某按钮宽60px,高20px
.btn {
  width: px2rem(60);
  height: px2rem(20);
}

或者

```js
(function () {
    var html = document.documentElement;
    function onWindowResize() {
        html.style.fontSize = html.getBoundingClientRect().width / 20 + 'px';
    }
    window.addEventListener('resize', onWindowResize);
    onWindowResize();
})();

2、vw vh

css
//以iphone7尺寸@2x 750像素宽的视觉稿为例
@function vw($px) {
    @return ($px / 750) * 100vw;
}
//假设一个div元素在视觉稿中,宽度为120px,字体大小为12px
div {
    width: vw(120);
    font-size: vw(12);
}

3、vw vh与rem结合

设置根元素font-size大小

css
 html {
       font-size: calc(100vw / 750 * 100);
  }

750 / 100 = 7.5
vw 是视口单位,被均分成了100,1vw = 1,所以根据上面计算,1vw = 7.5px 1px=0.13333333vw

100 / 7.5 = 13.333333vw
一般使用 rem 会给 html 的 font-size 设置大小为 100px,因为方便计算这里需要把100px 换算为 13.333333vw

1rem=100px=13.333333vw

css
 div {
  width: 3.75rem;
  height: 3.75rem;
  background: green;
  margin: 0 auto;
}

4、vm vh与postcss结合

安装postCss插件

js
npm i --save 
postcss-aspect-ratio-mini 
postcss-px-to-viewport 
postcss-write-svg 
postcss-cssnext 
postcss-viewport-units 
postcss-url 
postcss-import 
cssnano

配置postcssrc.js

js
module.exports = {
  plugins: {
    'postcss-import': {},
    'postcss-url': {},
    'postcss-aspect-ratio-mini': {},
    'postcss-write-svg': {
      utf8: false
    },
    'postcss-cssnext': {},
    'postcss-px-to-viewport': {
      viewportWidth: 750, // (Number) The width of the viewport.
      viewportHeight: 1334, // (Number) The height of the viewport.
      unitPrecision: 3, // (Number) The decimal numbers to allow the REM units to grow to.
      viewportUnit: 'vw', // (String) Expected units.
      selectorBlackList: ['.ignore', '.hairlines'], // (Array) The selectors to ignore and leave as px.
      minPixelValue: 1, // (Number) Set the minimum pixel value to replace.
      mediaQuery: false, // (Boolean) Allow px to be converted in media queries.
      exclude: /(\/|\\)(node_modules)(\/|\\)/ // 排除 node_modules
    },
    'postcss-viewport-units': {},
    cssnano: {
      preset: [
        'advanced',
        {
          zindex: false
        }
      ],
      autoprefixer: false, // 和cssnext同样具有autoprefixer,保留一个
      'postcss-zindex': false
    }
  }
}

如何在Vue项目中使用vw实现移动端适配