postcss-px-to-viewport 移動端適配

孙凯亮發表於2024-11-11

以前做移動端專案的時候都是用rem來做適配,現在基本上都是透過viewport單位來做。 postcss-px-to-viewport就是一個將px單位轉換為視口單位的 (vw, vh, vmin, vmax) 的 PostCSS 外掛,它可以將你CSS中的px單位轉化為vw,1vw等於1/100視口寬度。

1.安裝

javascript
程式碼解讀
複製程式碼
$ npm install postcss-px-to-viewport --save-dev

2.配置引數

在專案根目錄建立postcss.config.js檔案,新增如下配置。

javascript
程式碼解讀
複製程式碼
module.exports = ({ webpack }) => {
  return {
    plugins: {
      autoprefixer: {},
      "postcss-px-to-viewport": {
        unitToConvert: "px", // 要轉化的單位
        viewportWidth: 750, // UI設計稿的寬度
        unitPrecision: 6, // 轉換後的精度,即小數點位數
        propList: ["*"], // 指定轉換的css屬性的單位,*代表全部css屬性的單位都進行轉換
        viewportUnit: "vw", // 指定需要轉換成的視窗單位,預設vw
        fontViewportUnit: "vw", // 指定字型需要轉換成的視窗單位,預設vw
        selectorBlackList: [], // 指定不轉換為視窗單位的類名,
        minPixelValue: 1, // 預設值1,小於或等於1px則不進行轉換
        mediaQuery: true, // 是否在媒體查詢的css程式碼中也進行轉換,預設false
        // replace: true, // 是否轉換後直接更換屬性值
        exclude: [/node_modules/], // 設定忽略檔案,用正則做目錄名匹配
        landscape: false // 是否處理橫屏情況
      }
    }
  }
}

啟動專案,此時已經自動進行了轉換,會根據postcss.config.js檔案中的viewportWidth的值將px轉換為vw,比如說設定div寬度為750px,轉換後就是100vw。此時的樣式如下:

輸入

css
程式碼解讀
複製程式碼
.class {
  margin: -10px .5vh;
  padding: 5vmin 9.5px 1px;
  border: 3px solid black;
  border-bottom-width: 1px;
  font-size: 14px;
  line-height: 20px;
}

輸出

css
程式碼解讀
複製程式碼
.class {
  margin: -3.125vw .5vh;
  padding: 5vmin 2.96875vw 1px;
  border: 0.9375vw solid black;
  border-bottom-width: 1px;
  font-size: 4.375vw;
  line-height: 6.25vw;
}

3.vant

(1).問題1 vant中元件的css單位沒有轉換

將所有的配置好之後,啟動專案,新增了vant的元件後,開啟檢查,發現仍然是px單位,沒有進行轉換。

postcss-px-to-viewport 移動端適配

因為postcss.config.js檔案中的exclude引數將整個node_modules資料夾中的元件都給排除掉了,安裝的外掛會使用它預設的單位,將exclude改為[]

(2).問題2 轉換後的vant元件特別小

此時vant元件的單位也進行了轉換,但是展示會特別的小。

postcss-px-to-viewport 移動端適配

透過排查,在github上找到vant的官方demo,發現vant設定視口寬度是375,而我們設定的寬度為750,所以vant元件在轉換之後會寬高都變為原來的一半大小。

postcss-px-to-viewport 移動端適配

所以我們要設定當轉換到vant元件樣式的單位時,將視口寬度設定為375,透過百度(cv工程師),將postcss.config.js配置修改如下:

javascript
程式碼解讀
複製程式碼
const path = require("path")
module.exports = ({ webpack }) => {
  const designWidth = webpack.resourcePath.includes(path.join("node_modules", "vant")) ? 375 : 750

  return {
    plugins: {
      autoprefixer: {},
      "postcss-px-to-viewport": {
        unitToConvert: "px", // 要轉化的單位
        viewportWidth: designWidth,
        unitPrecision: 6, // 轉換後的精度,即小數點位數
        propList: ["*"], // 指定轉換的css屬性的單位,*代表全部css屬性的單位都進行轉換
        viewportUnit: "vw", // 指定需要轉換成的視窗單位,預設vw
        fontViewportUnit: "vw", // 指定字型需要轉換成的視窗單位,預設vw
        selectorBlackList: [], // 指定不轉換為視窗單位的類名,
        minPixelValue: 1, // 預設值1,小於或等於1px則不進行轉換
        mediaQuery: true, // 是否在媒體查詢的css程式碼中也進行轉換,預設false
        // replace: true, // 是否轉換後直接更換屬性值
        exclude: [], // 設定忽略檔案,用正則做目錄名匹配 /node_modules/
        landscape: false // 是否處理橫屏情況
      }
    }
  }
}

此時頁面已經恢復了正常。

postcss-px-to-viewport 移動端適配

4.行內樣式

後續在使用vant的image元件的時候發現,在傳入width和height750之後,圖片超出了頁面,開啟檢查發現仍然是px單位,沒有轉化為vw,傳入的width和height是加到了img標籤父元素的行內樣式上,建立一個div實驗了一下,postcss-px-to-viewport不會對行內樣式進行轉換,只會轉換解除安裝style標籤中的樣式。給image元件新增了class,展示正常。

使用width和height傳入:

postcss-px-to-viewport 移動端適配

使用class控制樣式:

postcss-px-to-viewport 移動端適配

至此,結束

相關文章