為什么說移動端該放棄rem適配方案了?
作者:去偽存真
原文:https://juejin.cn/post/7084926646033055752
1.背景
在做移動端各種尺寸屏幕的適配時,用的最多的就是rem方案。我們都寫過這樣的代碼,來設置根字體大小。這個計算公式中設備寬度,UI設計稿尺寸這兩個參數(shù)比較好理解,可是為什么要除以100呢,為什么不是10,50或者其它的數(shù)值呢。
const?setRem?=?()?=>?{
??const?deviceWidth?=?document.documentElement.clientWidth;
??//?獲取相對UI稿,屏幕的縮放比例
??const?rem?=?(deviceWidth?*100)?/?750;
??//?動態(tài)設置html的font-size
??document.querySelector('html').style.fontSize?=??rem?+?'px';
};
查了一番資料才得知,rem方案是viewport的過渡方案,將設計稿除以100,等分為7.5份來實現(xiàn)移動端不同屏幕尺寸適配的原理,與viewport中vw單位的定義,設計思想與想要解決的問題,是相同的。當時瀏覽器對viewport的支持性不好,而現(xiàn)在已經(jīng)是2022年了,可以看到,各大瀏覽器廠商,對viewport的支持率已經(jīng)很高了??梢苑判氖褂谩?/p>
2. 相對于rem的優(yōu)勢
語義化更好, rem從本義上來說,是一種字體單位,不是用來做布局和各種屏幕尺寸大小適配的,如上面的示例,用rem做適配單位,計算根字體的時候,計算公式中的100這個參數(shù)讓人感覺很費解,viewport詞更達意。
可以直接在代碼中書寫px,借助postcss-px-to-viewport插件轉(zhuǎn)換成vw單位,完美適配移動端各種屏幕尺寸。不用像之前那樣,一是要在藍湖上設置根字體基準尺寸,將設計稿標注的px單位轉(zhuǎn)換成rem單位,然后摘抄到代碼中。二是需要用js計算設置根字體大小。前端開發(fā)天然喜歡px單位,像rem,em,vw,vh這些單位,一般都不是UI設計稿標注的尺寸,開發(fā)時需要轉(zhuǎn)換成本。不如直接在代碼中寫px直觀高效。
3. postcss-px-to-viewport方案正確的使用姿勢
看到網(wǎng)上的教程都是說要在項目中安裝postcss-px-to-viewport工具包,然而安裝和配置完postcss-px-to-viewport之后,運行項目,發(fā)現(xiàn)命令行出現(xiàn)如下報錯:
postcss-px-to-viewport:?postcss.plugin?was?deprecated.?Migration?guide:?https://evilmartians.com/chronicles/postcss-8-plugin-migration
說安裝的postcss-px-to-viewport已經(jīng)過時了,遷移指南參考evilmartians.com/chronicles/…[1]
點進入一看,根本找不到配置px轉(zhuǎn)vw單位的方法。后面經(jīng)過一番嘗試之后,最終找到了正確的使用方法。
3.1 安裝postcss-px-to-viewport-8-plugin
yarn?add?-D?postcss-px-to-viewport-8-plugin
3.2 在項目下創(chuàng)建postcss.config.js
module.exports?=?{
??plugins:?{
????'postcss-px-to-viewport-8-plugin':?{
??????unitToConvert:?'px',?//?需要轉(zhuǎn)換的單位,默認為"px"
??????viewportWidth:?750,?//?設計稿的視口寬度
??????unitPrecision:?5,?//?單位轉(zhuǎn)換后保留的精度
??????propList:?['*','!font-size'],?//?能轉(zhuǎn)化為vw的屬性列表,!font-size表示font-size后面的單位不會被轉(zhuǎn)換
??????viewportUnit:?'vw',?//?希望使用的視口單位
??????fontViewportUnit:?'vw',?//?字體使用的視口單位
??????//?需要忽略的CSS選擇器,不會轉(zhuǎn)為視口單位,使用原有的px等單位。
??????//?下面配置表示類名中含有'keep-px'都不會被轉(zhuǎn)換
??????selectorBlackList:?['keep-px'],
??????minPixelValue:?1,?//?設置最小的轉(zhuǎn)換數(shù)值,如果為1的話,只有大于1的值會被轉(zhuǎn)換
??????mediaQuery:?false,?//?媒體查詢里的單位是否需要轉(zhuǎn)換單位
??????replace:?true,?//??是否直接更換屬性值,而不添加備用屬性
??????exclude:?[/node_modules/],?//?忽略某些文件夾下的文件或特定文件,例如?'node_modules'?下的文件
??????include:?[/src/],?//?如果設置了include,那將只有匹配到的文件才會被轉(zhuǎn)換
??????landscape:?false,?//?是否添加根據(jù)?landscapeWidth?生成的媒體查詢條件?@media?(orientation:?landscape)
??????landscapeUnit:?'vw',?//?橫屏時使用的單位
??????landscapeWidth:?1338,?//?橫屏時使用的視口寬度
????},
??},
};
4 效果演示
在項目中直接寫px,運行項目之后,可以看到px已經(jīng)轉(zhuǎn)換成vw單位了
#app{
??width:100px
}

需要注意的是:
1.postcss-px-to-viewport 對內(nèi)聯(lián)css樣式,外聯(lián)css樣式,內(nèi)嵌css樣式有效,對js動態(tài)css無效。所以要動態(tài)改變css展示效果的話,要使用靜態(tài)的class定義變化樣式,通過js改變dom元素的class實現(xiàn)樣式變化。 2.Vant組件的設計稿尺寸是375px,可用通過覆蓋:root下的Vant的css變量中px單位的方式,對Vant組件做適配
3.vue模板中的px單位不會被轉(zhuǎn)換,如需轉(zhuǎn)換請使用postcss-style-px-to-viewport[2]工具
本文僅代表個人觀點,非喜勿噴。
參考資料
https://evilmartians.com/chronicles/postcss-8-plugin-migration: https://link.juejin.cn?target=https%3A%2F%2Fevilmartians.com%2Fchronicles%2Fpostcss-8-plugin-migration
[2]https://www.npmjs.com/package/postcss-style-px-to-viewport: https://link.juejin.cn?target=https%3A%2F%2Fwww.npmjs.com%2Fpackage%2Fpostcss-style-px-to-viewport
最后
如果你覺得這篇內(nèi)容對你挺有啟發(fā),我想邀請你幫我個小忙:
點個「喜歡」或「在看」,讓更多的人也能看到這篇內(nèi)容
我組建了個氛圍非常好的前端群,里面有很多前端小伙伴,歡迎加我微信「sherlocked_93」拉你加群,一起交流和學習
關注公眾號「前端下午茶」,持續(xù)為你推送精選好文,也可以加我為好友,隨時聊騷。

