自適應布局方案
一套代碼對應一份設(shè)計稿,實現(xiàn)向上/向下兼容自適應布局方案對比
這里只做最表面的使用方法。不對,不進行多種環(huán)境(復雜布局等)的測試,內(nèi)容僅供參考。
后續(xù)會對每一個方案做進一步的研究。你問我什么時候?下次一定!??
起步
rem 是什么
rem
(font size of the root element)是指相對于根元素<html>
來做計算的字體大小單位。
e.g. 設(shè)置html { font-size: 75px }
時,其他元素1rem = 75px
,4rem = 300px
vw 是什么
vw
是基于viewport
視窗的長度單位。1vw
等于window.innerWidth
的1%
e.g. 設(shè)備物理寬度為375px
時,1vw = 3.75px
dpr 是什么
設(shè)備像素比device pixel ratio
簡稱dpr
,即物理像素和設(shè)備獨立像素的比值。
在web
中,瀏覽器為我們提供了window.devicePixelRatio
來幫助我們獲取dpr
。
iPhone 6、7、8
的實際物理像素是750 x 1334
,在開發(fā)者工具中我們可以看到:它的設(shè)備獨立像素是375 x 667
,設(shè)備像素比dpr
為2
e.g. 如果給定一個元素的高度為200px
(這里的px
指物理像素,非CSS
像素),iphone6
的設(shè)備像素比dpr = 2
,我們給定的height
應為200px/2=100dp
。
postcss-px-to-viewport(餓了么移動端做法)
postcss-px-to-viewport
的做法其實沒多大不同,它直接計算每個像素在設(shè)計稿中占據(jù)的%
來輸出vw
,rem
設(shè)計稿 = 375px 時
1. 轉(zhuǎn)換 VW 方案
'postcss-px-to-viewport': {
unitToConvert: 'px', // 需要轉(zhuǎn)換的單位,默認為"px"
viewportWidth: 375, // 視窗的寬度,對應設(shè)計稿的寬度
viewportUnit: 'vw', // 指定需要轉(zhuǎn)
fontViewportUnit: 'vw', // 字體使用的視口單位
unitPrecision: 13 // 指定`px`轉(zhuǎn)換為視窗單位值的小數(shù)后 x位數(shù)
...
}
復制代碼
計算 1px 在設(shè)計稿中的占比,再換算成 vw
1px = 1 / 375 = 0.2666666666666%
即 100px = 26.6666666666666% = 26.6666666666666vw
實際渲染時(375px 的屏幕),26.6666666666666vw = 26.6666666666% * 375 = 100px
[圖片上傳失敗...(image-193cc1-1649317373021)]
在 轉(zhuǎn)換成vw
的方案設(shè)置媒體查詢超出寬度范圍后固定body
寬度,內(nèi)容居中時,會出現(xiàn)樣式過大影響查看的問題。
@media screen and (min-width: 1024px) {
html {
max-width: 1024px;
}
}
復制代碼
[圖片上傳失敗...(image-7e7cf0-1649317373021)]
2.轉(zhuǎn)換 REM 方案
避免不同瀏覽器的默認字體大小不一樣導致大小不一致的問題,我們需要固定好root元素 html
的font-size
恰好我們可以利用postcss-px-viewport
不支持內(nèi)聯(lián)樣式的轉(zhuǎn)換。來設(shè)置root元素 html
的內(nèi)聯(lián)font-size: 16px;
來固定root
的字體大小以適配轉(zhuǎn)換成rem
的方案。
1px = 1 / 375 = 0.2666666666666%
即 100px = 26.6666666666666% = 26.6666666666666rem
由于我們設(shè)置了root元素 html
的內(nèi)聯(lián)font-size: 16px;
來固定root
的字體大小。因此,實際渲染時(375px 的屏幕),容器26.6666666666666rem = 26.6666666666666 * 16 = 426.6666666666656px
也就是說,我們需要更改viewportWidth
的大小來和設(shè)計圖適配。直接推導一下設(shè)計圖與viewportWidth
的倍數(shù)關(guān)系 = 426.6666666666656 / 100 = 4.26656
倍。設(shè)置viewportWidth: 1599.96
(375 * 4.26656 = 1599.96)
[圖片上傳失敗...(image-f17b5b-1649317373021)]
同樣設(shè)置媒體查詢超出寬度范圍后固定body
寬度,內(nèi)容居中
@media screen and (min-width: 1024px) {
html {
max-width: 1024px;
}
}
復制代碼
[圖片上傳失敗...(image-fb041b-1649317373021)]
rem + vw(網(wǎng)易移動端做法)
原則上也需要一個參考的設(shè)計圖,這邊假設(shè)為375px
寬設(shè)計圖。計算方法與postcss-px-to-viewport rem
方案一至。
計算公式 :
1vw = 3.75px
1px = 0.2666666666666667vw
100px = 26.6666666666666667vw
1rem = 26.6666666666666667vw = 100px
但需要注意的是,設(shè)置時需要把1rem
設(shè)置成100px 對應的 vw值
的值(防止小于瀏覽器最小字體),編寫時根據(jù)設(shè)計圖px / 100
來編寫。
當需要向上兼容
自適應的時候,設(shè)置好@media
對應不同的font-size
即可。
同樣設(shè)置媒體查詢超出寬度范圍后固定body
寬度,內(nèi)容居中。
html {
font-size: 26.6666666666666667vw;
margin: 0 auto;
body {
// 重置字體大小
font-size: 0.14rem;
}
}
@media screen and (min-width: 768px) {
html {
font-size: 9vw;
max-width: 768px;
}
}
復制代碼
[圖片上傳失敗...(image-970363-1649317373019)]
Flexible(前手淘做法)
js 獲取clientWidth
,分成十份。再設(shè)置rem
。字體大小則是12 * dpr
引用大漠老師的話:
由于
viewport
單位得到眾多瀏覽器的兼容,lib-flexible
這個過渡方案已經(jīng)可以放棄使用,不管是現(xiàn)在的版本還是以前的版本,都存有一定的問題。建議大家開始使用viewport
來替代此方案。vw
的兼容方案可以參閱《如何在Vue項目中使用vw實現(xiàn)移動端適配》一文。
原理放到現(xiàn)在也很好理解。根據(jù)設(shè)備屏幕的DPR,自動設(shè)置最合適的高清縮放(body的字體大小,重置根目錄的字體大小)。width
=設(shè)備獨立像素的寬度,初始/最大/最小縮放=1。通過 js計算root fontSize
的值,使1rem
= 設(shè)計稿 / 10。
既然都說可以放棄使用,那就不展示了。
總結(jié)
Flexible
在當今已經(jīng)可以放棄掉,轉(zhuǎn)用 CSS的方法解放因使用JS
動態(tài)修改fontsize
所消耗的性能
只做移動端
postcss-px-to-viewport -- vw
方法
一把梭,什么都不用考慮。且是最真實的按照屏幕大小的比例來放大縮小。
小屏設(shè)計圖向上兼容自適應大屏幕
當需要從移動端設(shè)計圖適配到
平板
、PC屏幕
(最方便)postcss-px-to-viewport -- rem
優(yōu)點
- 自動轉(zhuǎn)換 UI框架中的單位。
- 配合
media媒體查詢
設(shè)置root fontSize
適配不同分辨率的大小以及限制最大寬度
。
缺點
- 所有設(shè)置轉(zhuǎn)換的單位都會被轉(zhuǎn)換掉,無法設(shè)置某些樣式的單位不被轉(zhuǎn)換。
(最靈活)rem + vw
優(yōu)點
- 配合
media媒體查詢
設(shè)置root fontSize
適配不同分辨率的大小以及限制最大寬度。
- 高度自定義,誰需要轉(zhuǎn)換誰轉(zhuǎn)換成
rem
。
缺點
- 當需要把 UI框架中的單位也轉(zhuǎn)換時,會非常的頭大。需要一個一個覆蓋。
(不適合)postcss-px-to-viewport -- vw
該方案在限制最大寬度的時候,由于大小都是更具 viewport
來決定的。所以限制了最大寬度時里面的內(nèi)容依舊會隨viewport
變大而變大。故不合適
大屏設(shè)計圖向下兼容自適應小屏幕
(建議)postcss-px-to-viewport -- rem
優(yōu)點
- 自動轉(zhuǎn)換 UI框架中的單位,省事。
- 設(shè)置最小寬度居中,超出部分滾動條。
- 適配比設(shè)計稿更大的屏幕時把
root fontSize
設(shè)置為更大即可。
缺點
- 所有設(shè)置轉(zhuǎn)換的單位都會被轉(zhuǎn)換掉,無法設(shè)置某些樣式的單位不被轉(zhuǎn)換。
(一般) rem + vw
假設(shè)屏幕 1024px
計算公式 :
1vw = 10.24px
1px = 0.09765625vw
100px = 9.765625vw
1rem = 9.765625vw = 100px
優(yōu)點
- 設(shè)置時需要把
1rem
設(shè)置成100px 對應的 vw值
的值(防止小于瀏覽器最小字體),編寫時根據(jù)設(shè)計圖px / 100
來編寫。
缺點
- 需要寫多個媒體查詢更改
root fontSize
(因為存在字體太大導致一屏內(nèi)容顯示太少問題)。 - 當需要把 UI框架中的單位也轉(zhuǎn)換時,會非常的頭大。需要一個一個覆蓋。
- 無法設(shè)置最小寬度居中內(nèi)容。
(不適合)postcss-px-to-viewport -- vw
由于國產(chǎn)瀏覽器中的root fontSize
小于默認最小字體(一般是 12px)時,會強制保持root fontSize = 12px
,因此該方法并不適合。
作者:Mirai白
鏈接:https://juejin.cn/post/6867874227832225805
來源:稀土掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。