自適應(yīng)布局方案[轉(zhuǎn)]

自適應(yīng)布局方案

一套代碼對(duì)應(yīng)一份設(shè)計(jì)稿,實(shí)現(xiàn)向上/向下兼容自適應(yīng)布局方案對(duì)比

這里只做最表面的使用方法。不對(duì),不進(jìn)行多種環(huán)境(復(fù)雜布局等)的測(cè)試,內(nèi)容僅供參考。

后續(xù)會(huì)對(duì)每一個(gè)方案做進(jìn)一步的研究。你問(wèn)我什么時(shí)候?下次一定!??

起步

rem 是什么

rem(font size of the root element)是指相對(duì)于根元素<html>來(lái)做計(jì)算的字體大小單位。

e.g. 設(shè)置html { font-size: 75px }時(shí),其他元素1rem = 75px4rem = 300px

vw 是什么

vw是基于viewport視窗的長(zhǎng)度單位。1vw等于window.innerWidth1%

e.g. 設(shè)備物理寬度為375px時(shí),1vw = 3.75px

dpr 是什么

設(shè)備像素比device pixel ratio簡(jiǎn)稱dpr,即物理像素和設(shè)備獨(dú)立像素的比值。

web中,瀏覽器為我們提供了window.devicePixelRatio來(lái)幫助我們獲取dpr。

iPhone 6、7、8的實(shí)際物理像素是750 x 1334,在開(kāi)發(fā)者工具中我們可以看到:它的設(shè)備獨(dú)立像素是375 x 667,設(shè)備像素比dpr2

e.g. 如果給定一個(gè)元素的高度為200px(這里的px指物理像素,非CSS像素),iphone6的設(shè)備像素比dpr = 2,我們給定的height應(yīng)為200px/2=100dp

postcss-px-to-viewport(餓了么移動(dòng)端做法)

postcss-px-to-viewport的做法其實(shí)沒(méi)多大不同,它直接計(jì)算每個(gè)像素在設(shè)計(jì)稿中占據(jù)的%來(lái)輸出vwrem

設(shè)計(jì)稿 = 375px 時(shí)

1. 轉(zhuǎn)換 VW 方案

'postcss-px-to-viewport': {
    unitToConvert: 'px', // 需要轉(zhuǎn)換的單位,默認(rèn)為"px"
    viewportWidth: 375, // 視窗的寬度,對(duì)應(yīng)設(shè)計(jì)稿的寬度
    viewportUnit: 'vw', // 指定需要轉(zhuǎn)
    fontViewportUnit: 'vw', // 字體使用的視口單位
    unitPrecision: 13 // 指定`px`轉(zhuǎn)換為視窗單位值的小數(shù)后 x位數(shù)
    ...
}
復(fù)制代碼

計(jì)算 1px 在設(shè)計(jì)稿中的占比,再換算成 vw

1px = 1 / 375 = 0.2666666666666%100px = 26.6666666666666% = 26.6666666666666vw

實(shí)際渲染時(shí)(375px 的屏幕),26.6666666666666vw = 26.6666666666% * 375 = 100px

[圖片上傳失敗...(image-193cc1-1649317373021)]

在 轉(zhuǎn)換成vw的方案設(shè)置媒體查詢超出寬度范圍后固定body寬度,內(nèi)容居中時(shí),會(huì)出現(xiàn)樣式過(guò)大影響查看的問(wèn)題。

@media screen and (min-width: 1024px) {
  html {
    max-width: 1024px;
  }
}
復(fù)制代碼

[圖片上傳失敗...(image-7e7cf0-1649317373021)]

2.轉(zhuǎn)換 REM 方案

避免不同瀏覽器的默認(rèn)字體大小不一樣導(dǎo)致大小不一致的問(wèn)題,我們需要固定好root元素 htmlfont-size

恰好我們可以利用postcss-px-viewport不支持內(nèi)聯(lián)樣式的轉(zhuǎn)換。來(lái)設(shè)置root元素 html的內(nèi)聯(lián)font-size: 16px;來(lái)固定root的字體大小以適配轉(zhuǎn)換成rem的方案。

1px = 1 / 375 = 0.2666666666666%100px = 26.6666666666666% = 26.6666666666666rem

由于我們?cè)O(shè)置了root元素 html的內(nèi)聯(lián)font-size: 16px;來(lái)固定root的字體大小。因此,實(shí)際渲染時(shí)(375px 的屏幕),容器26.6666666666666rem = 26.6666666666666 * 16 = 426.6666666666656px

也就是說(shuō),我們需要更改viewportWidth的大小來(lái)和設(shè)計(jì)圖適配。直接推導(dǎo)一下設(shè)計(jì)圖與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;
  }
}
復(fù)制代碼

[圖片上傳失敗...(image-fb041b-1649317373021)]

rem + vw(網(wǎng)易移動(dòng)端做法)

原則上也需要一個(gè)參考的設(shè)計(jì)圖,這邊假設(shè)為375px寬設(shè)計(jì)圖。計(jì)算方法與postcss-px-to-viewport rem方案一至。

計(jì)算公式 :1vw = 3.75px 1px = 0.2666666666666667vw 100px = 26.6666666666666667vw

1rem = 26.6666666666666667vw = 100px

但需要注意的是,設(shè)置時(shí)需要把1rem設(shè)置成100px 對(duì)應(yīng)的 vw值的值(防止小于瀏覽器最小字體),編寫(xiě)時(shí)根據(jù)設(shè)計(jì)圖px / 100來(lái)編寫(xiě)。

當(dāng)需要向上兼容自適應(yīng)的時(shí)候,設(shè)置好@media對(duì)應(yīng)不同的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;
  }
}
復(fù)制代碼

[圖片上傳失敗...(image-970363-1649317373019)]

Flexible(前手淘做法)

js 獲取clientWidth,分成十份。再設(shè)置rem。字體大小則是12 * dpr

引用大漠老師的話:

由于viewport單位得到眾多瀏覽器的兼容,lib-flexible這個(gè)過(guò)渡方案已經(jīng)可以放棄使用,不管是現(xiàn)在的版本還是以前的版本,都存有一定的問(wèn)題。建議大家開(kāi)始使用viewport來(lái)替代此方案。vw的兼容方案可以參閱《如何在Vue項(xiàng)目中使用vw實(shí)現(xiàn)移動(dòng)端適配》一文。

原理放到現(xiàn)在也很好理解。根據(jù)設(shè)備屏幕的DPR,自動(dòng)設(shè)置最合適的高清縮放(body的字體大小,重置根目錄的字體大小)。width=設(shè)備獨(dú)立像素的寬度,初始/最大/最小縮放=1。通過(guò) js計(jì)算root fontSize的值,使1rem = 設(shè)計(jì)稿 / 10。

既然都說(shuō)可以放棄使用,那就不展示了。

源碼地址github.com/amfe/lib-fl…

總結(jié)

Flexible在當(dāng)今已經(jīng)可以放棄掉,轉(zhuǎn)用 CSS的方法解放因使用JS動(dòng)態(tài)修改fontsize所消耗的性能

只做移動(dòng)端

postcss-px-to-viewport -- vw方法

一把梭,什么都不用考慮。且是最真實(shí)的按照屏幕大小的比例來(lái)放大縮小。

小屏設(shè)計(jì)圖向上兼容自適應(yīng)大屏幕

當(dāng)需要從移動(dòng)端設(shè)計(jì)圖適配到平板、PC屏幕

(最方便)postcss-px-to-viewport -- rem

優(yōu)點(diǎn)

  1. 自動(dòng)轉(zhuǎn)換 UI框架中的單位。
  2. 配合media媒體查詢設(shè)置root fontSize適配不同分辨率的大小以及限制最大寬度。

缺點(diǎn)

  1. 所有設(shè)置轉(zhuǎn)換的單位都會(huì)被轉(zhuǎn)換掉,無(wú)法設(shè)置某些樣式的單位不被轉(zhuǎn)換。

(最靈活)rem + vw

優(yōu)點(diǎn)

  1. 配合media媒體查詢設(shè)置root fontSize適配不同分辨率的大小以及限制最大寬度。
  2. 高度自定義,誰(shuí)需要轉(zhuǎn)換誰(shuí)轉(zhuǎn)換成rem。

缺點(diǎn)

  1. 當(dāng)需要把 UI框架中的單位也轉(zhuǎn)換時(shí),會(huì)非常的頭大。需要一個(gè)一個(gè)覆蓋。

(不適合)postcss-px-to-viewport -- vw

該方案在限制最大寬度的時(shí)候,由于大小都是更具 viewport來(lái)決定的。所以限制了最大寬度時(shí)里面的內(nèi)容依舊會(huì)隨viewport變大而變大。故不合適

大屏設(shè)計(jì)圖向下兼容自適應(yīng)小屏幕

(建議)postcss-px-to-viewport -- rem

優(yōu)點(diǎn)

  1. 自動(dòng)轉(zhuǎn)換 UI框架中的單位,省事。
  2. 設(shè)置最小寬度居中,超出部分滾動(dòng)條。
  3. 適配比設(shè)計(jì)稿更大的屏幕時(shí)把root fontSize設(shè)置為更大即可。

缺點(diǎn)

  1. 所有設(shè)置轉(zhuǎn)換的單位都會(huì)被轉(zhuǎn)換掉,無(wú)法設(shè)置某些樣式的單位不被轉(zhuǎn)換。

(一般) rem + vw

假設(shè)屏幕 1024px

計(jì)算公式 :1vw = 10.24px 1px = 0.09765625vw 100px = 9.765625vw

1rem = 9.765625vw = 100px

優(yōu)點(diǎn)

  1. 設(shè)置時(shí)需要把1rem設(shè)置成100px 對(duì)應(yīng)的 vw值的值(防止小于瀏覽器最小字體),編寫(xiě)時(shí)根據(jù)設(shè)計(jì)圖px / 100來(lái)編寫(xiě)。

缺點(diǎn)

  1. 需要寫(xiě)多個(gè)媒體查詢更改root fontSize(因?yàn)榇嬖谧煮w太大導(dǎo)致一屏內(nèi)容顯示太少問(wèn)題)。
  2. 當(dāng)需要把 UI框架中的單位也轉(zhuǎn)換時(shí),會(huì)非常的頭大。需要一個(gè)一個(gè)覆蓋。
  3. 無(wú)法設(shè)置最小寬度居中內(nèi)容。

(不適合)postcss-px-to-viewport -- vw

由于國(guó)產(chǎn)瀏覽器中的root fontSize小于默認(rèn)最小字體(一般是 12px)時(shí),會(huì)強(qiáng)制保持root fontSize = 12px ,因此該方法并不適合。

demo倉(cāng)庫(kù)地址

博客鏈接: github gitee

作者:Mirai白
鏈接:https://juejin.cn/post/6867874227832225805
來(lái)源:稀土掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容