一些常見的移動端適配方案,你瞭解嗎?

前言

移動端設備的尺寸很多,而 UI 設計稿一般只會基於一個尺寸(一般是 375px 或 750px )進行設計。

目前移動端適配方案有多種,本文將介紹一些具有代表性的適配方案。

媒體查詢 @media

CSS3 中的媒體查詢屬性 @media 分別爲不同屏幕尺寸的移動設備編寫不同尺寸的 css 屬性,示例如下所示:

/* <375px */
@media screen and (max-width:375px) { 
  .box {
    width: 100%;
  }
}
/* >=375px and <450px */
@media screen and (min-width:375px) and (max-width:450px) {
  .box {
    width: 90%;
  }
}
/* >=450px */
@media screen and (min-width:450px) {
  .col{
    width: 80%;
  }
}
複製代碼

缺點:

  1. 頁面上所有的元素都得在不同的 @media 中定義一遍不同的尺寸,代價有點高。

  2. 如果再多一種屏幕尺寸,就得多寫一個 @media 查詢塊。

rem 適配方案

remCSS3 新增的一個相對單位,它是一個相對於頁面根元素 htmlfont-size 的一個單位。

假如設置了根元素 htmlfont-size18px,那麼 1rem 等於 18pxrem 的大小會隨着根元素 htmlfont-size 的改變而改變。rem 方案就是利用了這一點,根據不同的屏幕尺寸,來設置不同的根元素 htmlfont-size 的大小,以此來達到適配不同屏幕尺寸的目的。

目前,除了 IE8 及更早版本外,所有瀏覽器均已支持 rem

1. 使用 flexible

flexible 方案是阿里早期開源的一個移動端適配解決方案,引用 flexible 後,我們在頁面上統一使用 rem 來佈局。我們創建一個 rem.js 文件:

// 封裝一個根據屏幕尺寸自動改變 html 的 font-size 大小的函數
const init = function () {
  let clientWidth =
    document.documentElement.clientWidth || document.body.clientWidth;
  // 設計圖尺寸是 750px,這樣 *20 之後,1rem 就等於 20px;
  const fontSize = (clientWidth / 750 * 20);
  document.documentElement.style.fontSize = fontSize + "px";
};

init();

window.addEventListener("resize", init);
export default init;
複製代碼

mian.js 中引入就能夠使用了,需要自己手動將 px 轉換爲 rem

2. postcss-pxtorem 插件

參考:通過插件 postcss-pxtorem 輕鬆實現 px 到 rem 轉換,完成移動端適配 [2]

viewport 適配方案

viewport 是指視窗、視口,即瀏覽器用來顯示網頁的那部分區域。

viewport 方案使用 vw/vh 作爲樣式單位。vw/vh 將 viewport 分成了一百等份,1vw 等於視口 1% 的寬度,1vh 等於視口 1% 的高度。當我們的設計稿寬度是 750px 時,1vw 就等於 7.5px

1. 設置 meta 標籤

對於手機瀏覽器瀏覽頁面,常對 viewport 進行如下設置即可:

<meta >
複製代碼

initial-scale:初始縮放比例,即當瀏覽器第一次加載頁面時的縮放比例。maximum-scale:允許瀏覽者縮放到的最大比例,一般設爲 1.0。user-scalable:瀏覽者是否可以手動縮放,yes 或 no。

2. px 自動轉換爲 vw

使用插件 postcss-px-to-viewport[3] 進行相關配置,就可以幫助我們將 px 自動轉化爲 vw,提高開發效率。

使用 npm 或 yarn 安裝:

npm install postcss-px-to-viewport --save-dev
複製代碼

或者

yarn add -D postcss-px-to-viewport
複製代碼

webpack 配置:

module.exports = {
  plugins: {
    // ...
    'postcss-px-to-viewport'{
      // options
      unitToConvert: 'px',    // 需要轉換的單位,默認爲"px"
      viewportWidth: 750,     // 設計稿的視窗寬度
      unitPrecision: 4,       // 單位轉換後保留的精度
      propList: ['*''!font-size'],        // 能轉化爲 vw 的屬性列表
      viewportUnit: 'vw',     // 希望使用的視窗單位
      fontViewportUnit: 'vw', // 字體使用的視窗單位
      selectorBlackList: [],  // 需要忽略的 CSS 選擇器,不會轉爲視窗單位,使用原有的 px 等單位
      minPixelValue: 1,       // 設置最小的轉換數值,如果爲 1 的話,只有大於 1 的值會被轉換
      mediaQuery: false,      // 媒體查詢裏的單位是否需要轉換單位
      replace: true,          // 是否直接更換屬性值,而不添加備用屬性
      exclude: undefined,     // 忽略某些文件夾下的文件或特定文件,例如 'node_modules' 下的文件
      include: /\/src\//,     // 如果設置了include,那將只有匹配到的文件纔會被轉換
      landscape: false,       // 是否添加根據 landscapeWidth 生成的媒體查詢條件
      landscapeUnit: 'vw',    // 橫屏時使用的單位
      landscapeWidth: 1125,   // 橫屏時使用的視窗寬度
    },
  },
};
複製代碼

3. 標註不需要轉換的屬性

在項目中,如果設計師要求某一場景不做適配,需爲固定的寬高或大小,這時我們就需要利用 postcss-px-to-viewport 插件的 ignoring 特性,對不需要轉換的屬性進行標註,如下所示:

/* example input: */
.box {
  /* px-to-viewport-ignore-next */
  width: 100px;
  padding: 20px;
  height: 100px; /* px-to-viewport-ignore */
}

/* example output: */
.box {
  width: 100px; 
  padding: 2.6667vw;
  height: 100px;
}
複製代碼

當然,viewport 適配方案也有一定的缺陷:px 轉換成 vw 不一定能完全整除,因此有一定的像素差。

最後

目前比較推薦的移動適配方案是 rem&vw,瞭解其中的適配原理對於前端而言是非常重要的,相關問題也經常出現在面試題中。熟練使用插件也能給我們的工作帶來很大的幫助。

以上就是筆者對移動端適配方案的一些見解,以及在使用移動端適配時遇到的一些坑,如有不足歡迎大家指正~,謝謝!

關於本文

作者:codinglin

https://juejin.cn/post/7172952008029110285

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/wrmr3QOH4XM4B4Pnjw-mJw