最近接手了一個一年前的
H5
項目, 用的rem
適配方案, 可是當我看到css
javascript
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
經過閱讀此篇文章, 你將有以下收穫前端
vw
適配vw
適配的兼容性webpack
構建中引入vw
適配vw
適配方案中依賴安裝的注(pa)意(keng)事(zi)項(shi)vw
適配的坑以及爬坑姿式vw
適配的應用vw
配置webpack
構建vw
適配vw
相對於視窗的寬度:視窗寬度是100vw
, 即window.innerWidth
大小,不包含任務欄標題欄以及底部工具欄的瀏覽器區域大小vw
適配的兼容性viewport
的polyfill方案來完美解決:postcss-viewport-units與它的好基友viewport-units-buggyfillpostcss-viewport-units
自動添加content
, viewport-units-buggyfill
再把根據content
裏的數據把vw
單位轉爲px
單位, 以下圖vue
$ npm i -S viewport-units-buggyfill
複製代碼
const vub = require('viewport-units-buggyfill')
window.addEventListener('load', () => {
vub.init({ hacks: window.viewportUnitsBuggyfillHacks })
})
複製代碼
/* 對圖片的特殊處理 */
img {
content: normal !important;
}
複製代碼
webpack
構建中引入vw
適配postcss plugins
和配置的說明postcss
postcss
是一個平臺,其自己不對 CSS
進行處理,可是經過在該平臺上集成插件,能夠實現對CSS
的操做。webpack
postcss plugins
: postcss-px-to-viewport
把px
單位轉換爲vw
、vh
、vmin
或者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`
}
// ...
}
}
複製代碼
postcss-import
解決@import
引入路徑問題, 配合postcss-url
讓你引入文件變得更輕鬆git
postcss-url
處理文件,好比圖片文件、字體文件等引用路徑github
autoprefixer
讓你在編碼時再也不須要考慮任何瀏覽器前綴的問題,能夠專心擼碼
postcss-cssnext
該插件可讓咱們使用CSS
將來的特性,其會對這些特性作相關的兼容性處理
cssnano
壓縮和清理CSS
代碼。在webpack
中,cssnano
和css-loader
捆綁在一塊兒,因此不須要本身加載它. 記得將postcss-zindex
設置爲false
, 不然z-index
的值就會重置爲1
postcss-aspect-ratio-mini
處理元素容器寬高比
postcss-write-svg
處理移動端1px
的解決方案,該插件主要使用的是border-image
和background
來作1px
的相關處理
postcss-viewport-units
給CSS
的屬性添加content
的屬性,配合viewport-units-buggyfill
庫給vw
、vh
、vmin
和vmax
作適配的操做, 這是一個前面提到的解決兼容性的核心插件
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
}
}
}
複製代碼
若是你跟着大漠老師一頓猛操做, 安裝依賴時你會發現可能會出現如下問題:
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": {},
// ...
}
}
複製代碼
vue cli3
會缺乏部分依賴問題:
解決:
$ npm i -D postcss-import postcss-url
複製代碼
cssnano
的preset
使用了advanced
, 須要安裝對應依賴問題:
解決:
$ npm i -D cssnano-preset-advanced
複製代碼
vw
適配的應用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;
}
複製代碼
js
和template
中寫樣式, 咱們定義一個轉換數字爲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
適配的坑以及爬坑姿式viewport
的變化若是你在樣式中使用了vh
單位, 請注意某些webView
裏鍵盤彈出時, 100vh
對應的實際高度會變小
html2canvas
若是你有在前端截屏的需求, 恰好你用到了html2canvas
插件, 並且恰好要適配ios
低版本機型, 請使用0.5.0-beta4
版本, 而且把加了css-content
的標籤的內容置空
.target-el {
content: "";
}
複製代碼
rem
適配的組件, 又有vw
的組件, 請根據需求配置webpack
的loader
的exclude
和include
H5
開發VW
適配方案的webpack
項目構建, 歡迎點擊Star小星星