從一個祖傳項目談移動端vw適配

引言

最近接手了一個一年前的H5項目, 用的rem適配方案, 可是當我看到cssjavascript

img.user-avatar
            position: absolute
            left: 50%
            top: -5.4rem
            border: .125rem solid #FFAB74
            width: 4.3125rem
            height: 4.3125rem
            transform: translateX(-50%)
            border-radius: 50%

        p.name
            margin-top: 0.1rem
            line-height: 0.4rem
            font-size: 0.28rem
            text-align: center
            color: #333333
複製代碼

個人感覺是這樣的css

深呼吸一口氣, 數了數桌上剛掉落的幾根頭髮, 我想到何不用大漠老師的vw適配方案來帶我出坑呢, 此篇文章即該方案的講解html

經過閱讀此篇文章, 你將有以下收穫前端

  1. 什麼是vw適配
  2. vw適配的兼容性
  3. 如何在移動端H5項目webpack構建中引入vw適配
  4. 大漠老師vw適配方案中依賴安裝的注(pa)意(keng)事(zi)項(shi)
  5. vw適配的坑以及爬坑姿式
  6. 實際開發中vw適配的應用
  7. 我爲小夥伴們準備的福利: 開箱即用的vw配置webpack構建

一. 什麼是vw適配

1.1 vw 相對於視窗的寬度:視窗寬度是100vw, 即window.innerWidth大小,不包含任務欄標題欄以及底部工具欄的瀏覽器區域大小

1.2 <<CSS世界>>做者張鑫旭老師的視區相關單位vw, vh..簡介以及可實際應用場景

二. vw適配的兼容性

2.1 可以使用viewport的polyfill方案來完美解決:postcss-viewport-units與它的好基友viewport-units-buggyfill

2.1.1 原理

postcss-viewport-units自動添加content, viewport-units-buggyfill再把根據content裏的數據把vw單位轉爲px單位, 以下圖vue

2.1.2 如何使用

$ npm i -S viewport-units-buggyfill
複製代碼
const vub = require('viewport-units-buggyfill')

window.addEventListener('load', () => {
  vub.init({ hacks: window.viewportUnitsBuggyfillHacks })
})
複製代碼
/* 對圖片的特殊處理 */
img { 
  content: normal !important; 
}
複製代碼

2.2 兼容的範圍

2.3 測試用例

三. 如何在移動端H5項目webpack構建中引入vw適配

3.1 大漠老師的原文連接

如何在Vue項目中使用vw實現移動端適配(請戳)java

3.2 大漠老師所用postcss plugins和配置的說明

3.2.1 插一嘴, 什麼是postcss

       postcss是一個平臺,其自己不對 CSS進行處理,可是經過在該平臺上集成插件,能夠實現對CSS的操做。webpack

3.2.2 核心postcss plugins: postcss-px-to-viewport

       把px單位轉換爲vwvhvmin或者vmax這樣的視窗單位ios

// your-project/.postcssrc.js

module.exports = {
  "plugins": {
    // ...
    "postcss-px-to-viewport": {
    viewportWidth: 375,      // 視窗的寬度,對應的是咱們設計稿的寬度,通常是375
    viewportHeight: 667,    // 視窗的高度,根據750設備的寬度來指定,通常指定667,也能夠不配置
    unitPrecision: 3,        // 指定`px`轉換爲視窗單位值的小數位數(不少時候沒法整除)
    viewportUnit: 'vw',      // 指定須要轉換成的視窗單位,建議使用vw
    selectorBlackList: ['.ignore', '.hairlines'],  // 指定不轉換爲視窗單位的類,能夠自定義,能夠無限添加,建議定義一至兩個通用的類名
    minPixelValue: 1,       // 小於或等於`1px`不轉換爲視窗單位,你也能夠設置爲你想要的值
    mediaQuery: false       // 容許在媒體查詢中轉換`px`
}
    // ...
  }
}
複製代碼

3.2.2 postcss-import

解決@import引入路徑問題, 配合postcss-url讓你引入文件變得更輕鬆git

3.2.3 postcss-url

處理文件,好比圖片文件、字體文件等引用路徑github

3.2.4 autoprefixer

讓你在編碼時再也不須要考慮任何瀏覽器前綴的問題,能夠專心擼碼

3.2.5 postcss-cssnext

該插件可讓咱們使用CSS將來的特性,其會對這些特性作相關的兼容性處理

3.2.6 cssnano

壓縮和清理CSS代碼。在webpack中,cssnanocss-loader捆綁在一塊兒,因此不須要本身加載它. 記得將postcss-zindex設置爲false, 不然z-index的值就會重置爲1

3.2.7 postcss-aspect-ratio-mini

處理元素容器寬高比

3.2.8 postcss-write-svg

處理移動端1px的解決方案,該插件主要使用的是border-imagebackground來作1px的相關處理

3.2.9 postcss-viewport-units

CSS的屬性添加content的屬性,配合viewport-units-buggyfill庫給vwvhvminvmax作適配的操做, 這是一個前面提到的解決兼容性的核心插件

四. 大漠老師vw適配方案中依賴安裝的注(pa)意(keng)事(zi)項(shi)

npm i -D postcss-aspect-ratio-mini postcss-px-to-viewport postcss-write-svg postcss-cssnext postcss-viewport-units cssnano
複製代碼
// your-project/.postcssrc.js
module.exports = {
    "plugins": {
        "postcss-import": {},
        "postcss-url": {},
        "postcss-aspect-ratio-mini": {}, 
        "postcss-write-svg": {
            utf8: false
        },
        "postcss-cssnext": {},
        "postcss-px-to-viewport": {
            viewportWidth: 375,     // (Number) The width of the viewport.
            viewportHeight: 667,    // (Number) The height of the viewport.
            unitPrecision: 3,       // (Number) The decimal numbers to allow the REM units to grow to.
            viewportUnit: 'vw',     // (String) Expected units.
            selectorBlackList: ['.ignore', '.hairlines'],  // (Array) The selectors to ignore and leave as px.
            minPixelValue: 1,       // (Number) Set the minimum pixel value to replace.
            mediaQuery: false       // (Boolean) Allow px to be converted in media queries.
        }, 
        "postcss-viewport-units":{},
        "cssnano": {
            preset: "advanced",
            autoprefixer: false,
            "postcss-zindex": false
        }
    }
}
複製代碼

       若是你跟着大漠老師一頓猛操做, 安裝依賴時你會發現可能會出現如下問題:

4.1 postcss-cssnext插件被廢棄, 推薦用postcss-preset-env

問題:

解決:

$ npm un -D postcss-cssnext
$ npm i -D postcss-preset-env
複製代碼
// your-project/.postcssrc.js

module.exports = {
  "plugins": {
    // ...
    - "postcss-cssnext": {},
    + "postcss-preset-env": {},
    // ...
  }
}
複製代碼

4.2 若是你用vue cli3會缺乏部分依賴

問題:

解決:

$ npm i -D postcss-import postcss-url
複製代碼

4.3 cssnanopreset使用了advanced, 須要安裝對應依賴

問題:

解決:

$ npm i -D cssnano-preset-advanced
複製代碼

五. 實際開發中vw適配的應用

5.1 在css中寫樣式

在實際擼碼過程,不須要進行任何的計算,直接在代碼中根據UI稿寫px, 如

.test {
    border: .5px solid black;
    border-bottom-width: 4px;
    font-size: 14px;
    line-height: 20px;
    position: relative;
}
複製代碼

編譯出來的CSS:

.test {
    border: .5px solid #000;
    border-bottom-width: 1.667vw;
    font-size: 3.733vw;
    line-height: 5.333vw;
    position: relative;
}
複製代碼

5.2 在jstemplate中寫樣式, 咱們定義一個轉換數字爲vw的工具類

// your project/src/shared/utils.js
const toVw = (num) => {
  return ((window.Number(num).toFixed(5) / 375) * 100).toFixed(5) + 'vw'
}
const UTILS = { toVw }
export default UTILS

// your project/src/components/test.vue
<template>
  <div
    :style="{
        width: toVw(size),
        height: toVw(size)
      }"
  >
  </div>
</template>


<script type="text/ecmascript-6">
import UTILS from 'shared/utils'

export default {
  props: {
    size: {
      default: 15
    }
  },
  methods: {
    toVw (num) {
      return UTILS.toVw(num)
    }
  }
}
</script>
複製代碼

六. vw適配的坑以及爬坑姿式

6.1 注意viewport的變化

若是你在樣式中使用了vh單位, 請注意某些webView裏鍵盤彈出時, 100vh對應的實際高度會變小

6.2 html2canvas

若是你有在前端截屏的需求, 恰好你用到了html2canvas插件, 並且恰好要適配ios低版本機型, 請使用0.5.0-beta4版本, 而且把加了css-content的標籤的內容置空

.target-el {
  content: "";
}

複製代碼

6.3若是你項目裏既有rem適配的組件, 又有vw的組件, 請根據需求配置webpackloaderexcludeinclude

七. 說好的福利, 開箱即用的H5開發VW適配方案的webpack項目構建, 歡迎點擊Star小星星

github.com/atbulbs/all…

happy hacking~!

相關文章
相關標籤/搜索