阅读 833

移动端rem、vw等手机适配原理详解

  • 什么是rem?
    REM是相对单位,是相对HTML根元素,rem就是根元素html的字体大小,其他元素调用rem,能统一根据这个适配比例进行调整。
  • 什么是vw?
    vw是视窗宽度(viewport width),100vw等于设备宽度,例如:设备宽度是375px,那么1vw就等于3.75px。
  • 原理
    • vw的适配原理
      将视窗划分成100份,不考虑dpi的影响,也不用考虑html根元素的font-size的大小。相当于网易的rem适配原理中将视窗划分成100的情况,相比网易的适配方案的优点是省去了rem处理,缺点是vw兼容性没rem好。
      换算举例:例如设计图尺寸750px,设备尺寸是375px,那么如果设计图上一个元素的宽度是75px,那么换算到设备上面的宽度尺寸就是 37.5px也就是10vw;
      • 1、通过 【设计图上的元素宽度 / 设计图尺寸 = 设备上的元素宽度? / 设备宽度】计算出设备上的元素宽度 37.5px;
      • 2、通过 【设备宽度 / 100(vw原理)= 1vw ?】计算出 1vw 等于 3.75px
      • 3、通过 【设备上的元素宽度 / 1vw = 设备上的元素宽度(单位vw)?】的到 10vw
    • rem的适配原理(网易)
      将设计图划分成6.4份,假设设计图尺寸是640px,那么每份就是100px,也就是根元素html的font-size的大小,也就是1rem的大小;不考虑dpi影响和meta上标签的scale变化。 相当于淘宝适配方案忽略dpi的变化运算并且将设计图划分为6.4份的情况。
      换算举例:例如设计图尺寸640px,设备尺寸是320px,那么如果设计图上一个元素的宽度是100px,那么换算到设备上面的宽度尺寸就是 50px也就是1rem;
      • 1、通过 【设计图上的元素宽度 / 设计图尺寸 = 设备上的元素宽度? / 设备宽度】计算出设备上的元素宽度 50px;
      • 2、通过 【设备宽度 / 6.4(网易rem划分原理)= 1rem ?】计算出 1rem 等于 50px
      • 3、通过 【设备上的元素宽度 / 1rem = 设备上的元素宽度(单位rem)?】的到 1rem
      • 4、html根元素rem处理代码如下:
      remJsW () {
          let html = document.documentElement
          // 设备尺寸
          let deviceWidth = window.screen.width
          // 划分份数 【FIX】
          let fen = 6.4;
          (function () {
              function onWindowResize () {
              // 1rem ? = 设备宽度【FIX】 / 划分份数【FIX】
              html.style.fontSize = deviceWidth / fen + 'px'
              }
              window.addEventListener('resize', onWindowResize)
              onWindowResize()
          })()
      } 
      复制代码
    • rem的适配原理(淘宝)
      将设计图划分成10份,假设设计图尺寸是750px,那么每份就是75px,也就是根元素html的font-size的大小,也就是1rem的大小;考虑dpi影响和meta上标签的scale变化。
      换算举例:例如设计图尺寸750px,设备尺寸是375px,那么如果设计图上一个元素的宽度是75px,那么换算到设备上面的宽度尺寸就是 37.5px(未经过像素密度转换)也就是1rem;
      • 1、通过 【设计图上的元素宽度 / 设计图尺寸 = 设备上的元素宽度? / 设备宽度】计算出设备上的元素宽度 37.5px;
      • 2、通过 【设备宽度 * 设备的像素密度 / 10(淘宝rem划分原理) = 1rem ?】计算出 1rem 等于 75px {未经过scale缩放}
      • 3、通过 【设备上的元素宽度 * 设备的像素密度 / 1rem = 设备上的元素宽度(单位rem)?】的到 1rem {未经过scale缩放}
      • 4、html根元素rem处理和meta代码如下:
      remJsTD () {
          let dpi = window.devicePixelRatio
          let html = document.documentElement
          // 设备尺寸
          let deviceWidth = window.screen.width
          // 划分份数 【FIX】
          let fen = 10;
          (function () {
              function onWindowResize () {
              // 1rem ? = 设备宽度【FIX】 / 划分份数【FIX】 * dpi
              html.style.fontSize = deviceWidth / fen * dpi + 'px'
              }
              window.addEventListener('resize', onWindowResize)
              onWindowResize()
          })()
          // meta 配合dpi进行倍数换算(将虚拟窗口按照设备dpi进行缩放)
          const scale = 1 / dpi
          const oMeta = document.createElement('meta')
          oMeta.content = `width=device-width, initial-scale=${scale}, maximum-scale=${scale},minimum-scale=${scale}, user-scalable=0`
          oMeta.name = 'viewport'
          document.getElementsByTagName('head')[0].appendChild(oMeta)
      },
      复制代码
文章分类
前端
文章标签