更新!移動(dòng)端最佳適配解決方案出爐

前言
前段時(shí)間我的移動(dòng)端適配解決方案[2]一文在評(píng)論區(qū)引發(fā)了激烈的討論。其中討論最多的就是,移動(dòng)端rem的適配已經(jīng)淘汰了,目前大家使用的都是viewport。lib-flexible作者也在github明確的表示lib-flexible這個(gè)解決方案可以放棄使用了。
由于
viewport單位得到眾多瀏覽器的兼容,lib-flexible這個(gè)過(guò)渡方案已經(jīng)可以放棄使用,不管是現(xiàn)在的版本還是以前的版本,都存有一定的問(wèn)題。建議大家開(kāi)始使用viewport來(lái)替代此方案。
看到大家的討論,我受益匪淺。在這里也向那些閱讀過(guò)我之前那篇移動(dòng)端適配解決方案[3]文章的同行們說(shuō)一聲對(duì)不起。rem適配方案確實(shí)是已經(jīng)淘汰了。
本文帶大家一起來(lái)看看評(píng)論區(qū)所說(shuō)的viewport適配解決方案。
什么是viewport
viewport翻譯成中文的意思大致是視圖、視窗。在移動(dòng)端設(shè)備中,整塊顯示屏就相當(dāng)于視圖、視窗。但這種說(shuō)法也并不完全正確。因?yàn)樵谝苿?dòng)端設(shè)備中,瀏覽器視圖并不是整個(gè)屏幕。因此viewport又被分為了3種 layout viewport、visual viewport、ideal viewport
為了能夠適配到pc端開(kāi)發(fā)頁(yè)面中,大部分瀏覽器把viewport的寬度設(shè)為了980px 這個(gè)瀏覽器默認(rèn)設(shè)置的視圖被稱(chēng)為 layout viewport。我們可以使用document.documentElement.clientWidth 來(lái)獲取。
由于 layout viewport的寬度是遠(yuǎn)大于瀏覽器寬度的,因此我們需要一個(gè)新的viewport來(lái)代表瀏覽器的可視區(qū)域?qū)挾龋@個(gè)視圖則被成為visual viewport我們可以使用window.innerWidth來(lái)獲取。
現(xiàn)在我們已經(jīng)有兩個(gè)viewport了,layout viewport 和 visual viewport。但瀏覽器覺(jué)得還不夠,因?yàn)楝F(xiàn)在越來(lái)越多的網(wǎng)站都會(huì)為移動(dòng)設(shè)備進(jìn)行單獨(dú)的設(shè)計(jì),所以必須還要有一個(gè)能完美適配移動(dòng)設(shè)備的ideal viewport。
ideal viewport 并沒(méi)有一個(gè)固定的尺寸,不同的設(shè)備擁有有不同的 ideal viewport。比如iphone5的 ideal viewport是 320px 而 iphone6s的 ideal viewport卻是 375px
viewport的單位vw、vh
vw、vh將viewport分成了一百份。vw即 viewport width vh即viewport height
1vw等于視圖單位的1%的寬度 1vh等于視圖單位的1%的高度
如果設(shè)計(jì)稿的視圖為375px 那么1vw 等于 3.75px
在配置開(kāi)始之前 我們依然需要一個(gè)vue-cli項(xiàng)目 在項(xiàng)目的index.html 我們需要在head標(biāo)簽中添加如下代碼
"viewport"?content="width=device-width,initial-scale=1.0,user-scalable=no">
復(fù)制代碼
viewport適配解決方案
之前的文章,我們用到了阿里巴巴手淘團(tuán)隊(duì)出品的amfe-flexible這個(gè)庫(kù)。目的是為了獲取到不同移動(dòng)端設(shè)備下的像素比。對(duì)于rem的適配該庫(kù)是至關(guān)重要的。本篇文章使用viewport適配則不再需要。
要使用viewport適配 我們必須安裝postcss-px-to-viewport這個(gè)包。這包名是不是有一種似曾相識(shí)的感覺(jué)。
沒(méi)錯(cuò),上篇文章中我們使用過(guò)postcss-pxtorem。這兩個(gè)包不僅名字相似,功能也有相似的地方。postcss-pxtorem是將 px單位轉(zhuǎn)換為rem單位。postcss-px-to-viewport則是將px單位轉(zhuǎn)換為vw、vh
//引入?postcss-px-to-viewport
?npm?install?postcss-px-to-viewport?--save-dev
復(fù)制代碼
安裝完成后 我們需要進(jìn)行postcss插件相關(guān)的配置 在根目錄新建一個(gè)名為postcss.config.js的文件,如果項(xiàng)目中已包含該文件則無(wú)需新建。在文件中寫(xiě)入如下代碼:
//postcss.config.js
module.exports?=?{
??plugins:?{
????'postcss-px-to-viewport':?{
?????unitToConvert:?"px",?//?要轉(zhuǎn)化的單位???????
?????viewportWidth:?375,?//?UI設(shè)計(jì)稿的寬度???????
?????unitPrecision:?6,?//?轉(zhuǎn)換后的精度,即小數(shù)點(diǎn)位數(shù)???????
?????propList:?["*"],?//?指定轉(zhuǎn)換的css屬性的單位,*代表全部css屬性的單位都進(jìn)行轉(zhuǎn)換?????
?????viewportUnit:?"vw",?//?指定需要轉(zhuǎn)換成的視窗單位,默認(rèn)vw???????
?????fontViewportUnit:?"vw",?//?指定字體需要轉(zhuǎn)換成的視窗單位,默認(rèn)vw??????selectorBlackList:?["wrap"],?//?指定不轉(zhuǎn)換為視窗單位的類(lèi)名,???????
?????minPixelValue:?1,?//?默認(rèn)值1,小于或等于1px則不進(jìn)行轉(zhuǎn)換???????
?????mediaQuery:?true,?//?是否在媒體查詢(xún)的css代碼中也進(jìn)行轉(zhuǎn)換,默認(rèn)false??????
?????replace:?true,?//?是否轉(zhuǎn)換后直接更換屬性值???????
?????exclude:?[/node_modules/],?//?設(shè)置忽略文件,用正則做目錄名匹配???????
????}
??}
}
復(fù)制代碼
在配置上這兩個(gè)包也有相似的功能。大家可以去參考一下postcss-px-to-viewport作者的github[4]
值得注意的是:postcss-px-to-viewport?同樣存在第三方組件庫(kù)兼容性的問(wèn)題。比如在設(shè)計(jì)稿為750px時(shí)使用vant組件庫(kù)會(huì)將vant組件的樣式縮小。
解決第三方組件庫(kù)兼容問(wèn)題
vant組件庫(kù)的設(shè)計(jì)稿是按照375px來(lái)開(kāi)發(fā)的。因此在viewportWidth為750px時(shí)會(huì)出現(xiàn)轉(zhuǎn)換問(wèn)題。
//?postcss.config.js
const?path?=?require('path');
module.exports?=?({?webpack?})?=>?{
??const?viewWidth?=?webpack.resourcePath.includes(path.join('node_modules',?'vant'))???375?:?750;
??return?{
????plugins:?{
??????autoprefixer:?{},
??????"postcss-px-to-viewport":?{
????????unitToConvert:?"px",
????????viewportWidth:?viewWidth,
????????unitPrecision:?6,
????????propList:?["*"],
????????viewportUnit:?"vw",
????????fontViewportUnit:?"vw",
????????selectorBlackList:?[],
????????minPixelValue:?1,
????????mediaQuery:?true,
????????exclude:?[],
????????landscape:?false
??????}
????}
??}
}
復(fù)制代碼
如果讀取的node_modules中的文件是vant,那么就將設(shè)計(jì)稿變?yōu)?75px。如果讀取的文件不是vant的文件,那么就將設(shè)計(jì)稿變?yōu)?50px。這樣就可以避免vant組件在750px下出現(xiàn)樣式縮小的問(wèn)題了。
同理 這對(duì)于其他的移動(dòng)端UI組件庫(kù)同樣有效果。我們只需要改動(dòng)這行代碼即可
const?viewWidth?=?webpack.resourcePath.includes(path.join('node_modules',?'vant'))???375?:?750;?
復(fù)制代碼
至此,我們的viewport的適配就做好了,只需要按照設(shè)計(jì)稿的比例進(jìn)行開(kāi)發(fā)就可以了。
最后
文章若有不足之處,還請(qǐng)大家批評(píng)指出。
感謝您觀看此篇文章 希望能給個(gè)??評(píng)論收藏三連!你的點(diǎn)贊就是我寫(xiě)作的動(dòng)力。
作者:李知恩
點(diǎn)贊和在看就是最大的支持??
