移动端适配

277 阅读3分钟

基础知识

关于移动端适配,你必须要知道的 - 掘金

flexible rem

flexible方案是阿里早期开源的一个移动端适配解决方案,引用flexible后,我们在页面上统一使用rem来布局。

它的核心代码非常简单:

// set 1rem = viewWidth / 10
function setRemUnit () {
    var rem = docEl.clientWidth / 10
    docEl.style.fontSize = rem + 'px'
}
setRemUnit();

rem 是相对于 html 节点的 font-size 来做计算的。

我们通过设置 document.documentElement.style.fontSize 就可以统一整个页面的布局标准。

上面的代码中,将 html 节点的 font-size 设置为页面 clientWidth (布局视口)的1/10,即1rem就等于页面布局视口的1/10,这就意味着我们后面使用的 rem 都是按照页面比例来计算的。

这时,我们只需要将UI出的图转换为 rem 即可。

以iPhone6为例:布局视口为375px,则1rem = 37.5px,这时UI给定一个元素的宽为75px(设备独立像素),我们只需要将它设置为75 / 37.5 = 2rem。

当然,每个布局都要计算非常繁琐,我们可以借助 PostCSS 的 postcss-pxtorem 插件来帮助我们完成这个过程。

postcss-pxtorem 仅仅是用来把 px 转换为 rem ,rootValue传入什么值,1rem 就等于什么值, 和 html 的 font-size 设置无关,也和页面渲染无关

假如 rootValue = 37.5 那么 CSS 中所有转换规则:width: 450px => 450 / 37.5 = 12 => width: 12rem

之后通过 rem.js 设置 html 的 font-size 及 1rem 的值,就实现了不同屏幕的适配

如果实际页面的视窗宽度是 390px 那么此时的 1rem = 39px,width: 12rem * 39px 即 width: 468px

h5 项目 rem 配置

'postcss-pxtorem': {
    rootValue: 75, // 75表示750设计稿,37.5表示375设计稿
    propList: ['*'],
    selectorBlackList: ['van'] // 排除掉vant组件,vant设计稿为375
}
const setRem = () => {
  const htmlWidth = document.documentElement.clientWidth
  const htmlDom = document.querySelector('html')
  // 根元素大小
  htmlDom.style.fontSize = htmlWidth / 10 + 'px'
}
setRem()
window.onresize = function () {
  setRem()
}

UI设计稿 750px,按照 rem 计算规则页面宽度十等分所以除以 10,font-size 为 75px = 1rem 来计算

比如设计稿 margin-top: 30px 应该这么转换 30 / 75 = 0.4rem

假如实际页面的视窗宽度是 390px 那么此时的 1rem = 39px , margin-top 为 39 * 0.4rem = 15.6px

目前项目的 h5 项目配置

'postcss-pxtorem': {
    rootValue: 37.5,
    propList: ['*'],
    selectorBlackList: ['van'] // 仍要排除vant组件,因为根据vant进行了二次封装,用的750设计稿
}
const setRem = () => {
  const htmlWidth = document.documentElement.clientWidth || document.body.clientWidth
  const htmlDom = document.querySelector('html')
  // 根元素大小
  htmlDom.style.fontSize = htmlWidth / 20 + 'px'
}
setRem()
window.onresize = function () {
  setRem()
}

因为 postcss-pxtorem 使用了 37.5 , 所以 px 到 rem 的转换规则变成了按照 375px 设计稿来,

原来 margin-top: 30px 会转换为 30 / 37.5 = 0.8rem ,为了让它仍然保持 0.4rem,rem 计算时除以 20

使用pxtorem时Vant变小问题

通过代码动态更改

const path = require('path');

module.exports = ({ webpack }) => {
  const designWidth = webpack.resourcePath.includes(path.join('node_modules''vant')) ? 375 : 750;

  return {
    plugins: {
      'autoprefixer': {},
      'postcss-pxtorem': {
        rootValue: designWidth / 10,
        propList: ['*'],
      }
    }
  }

}

viewport

移动端布局之postcss-px-to-viewport(兼容vant)【更新于2021/09/27】 - 陌上兮月 - 博客园

大屏适配

一次搞懂数据大屏适配方案 (vw vh、rem、scale) - 掘金

高级理解

真的,移动端尺寸自适应与dpr无关 - 掘金