移動端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;
      • 一、經過 【設計圖上的元素寬度 / 設計圖尺寸 = 設備上的元素寬度? / 設備寬度】計算出設備上的元素寬度 37.5px;
      • 二、經過 【設備寬度 / 100(vw原理)= 1vw ?】計算出 1vw 等於 3.75px
      • 三、經過 【設備上的元素寬度 / 1vw = 設備上的元素寬度(單位vw)?】的到 10vw
    • rem的適配原理(網易)
      將設計圖劃分紅6.4份,假設設計圖尺寸是640px,那麼每份就是100px,也就是根元素html的font-size的大小,也就是1rem的大小;不考慮dpi影響和meta上標籤的scale變化。 至關於淘寶適配方案忽略dpi的變化運算而且將設計圖劃分爲6.4份的狀況。
      換算舉例:例如設計圖尺寸640px,設備尺寸是320px,那麼若是設計圖上一個元素的寬度是100px,那麼換算到設備上面的寬度尺寸就是 50px也就是1rem;
      • 一、經過 【設計圖上的元素寬度 / 設計圖尺寸 = 設備上的元素寬度? / 設備寬度】計算出設備上的元素寬度 50px;
      • 二、經過 【設備寬度 / 6.4(網易rem劃分原理)= 1rem ?】計算出 1rem 等於 50px
      • 三、經過 【設備上的元素寬度 / 1rem = 設備上的元素寬度(單位rem)?】的到 1rem
      • 四、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;
      • 一、經過 【設計圖上的元素寬度 / 設計圖尺寸 = 設備上的元素寬度? / 設備寬度】計算出設備上的元素寬度 37.5px;
      • 二、經過 【設備寬度 * 設備的像素密度 / 10(淘寶rem劃分原理) = 1rem ?】計算出 1rem 等於 75px {未通過scale縮放}
      • 三、經過 【設備上的元素寬度 * 設備的像素密度 / 1rem = 設備上的元素寬度(單位rem)?】的到 1rem {未通過scale縮放}
      • 四、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)
      },
      複製代碼
相關文章
相關標籤/搜索