rem自適應移動端佈局
現在的移動終端(手機,pad)螢幕大小各不一樣,為了適應每一種螢幕寬度而設計多款樣式明顯是不科學的,所以就有了自適應佈局的概念。
以前,實現自適應佈局的時候,我使用了CSS3 @media 監測視口寬度,根據不同寬度實現不同的佈局,從而實現一套CSS適配所有終端(PC,移動)。雖說聽起來很方便,但實際上也是在儘量重用的前提下針對螢幕寬度調整部分樣式而已,那有什麼方法可以更簡單地去適配移動端呢?rem佈局給了我一個新的思路。
rem是一個相對長度單位,跟em類似,不過rem參照的是頁面根元素,em參照的是當前父元素。rem佈局的思路其實很簡單,在編寫樣式的時候,在需要實現自適應的長度屬性使用rem單位,然後,使用js監測螢幕的寬度,在根元素(html)上設定font-size(px絕對值),這樣,用了rem長度單位的屬性就會根據這個設定值變動,實現自適應。
實現起來非常簡單,但原理卻關係到很多方面的東西,以某寶移動端網頁為例子,我用chrome開發工具得到了一些資料:
終端 | 螢幕寬度 | dpr | 初始scale | html font-size | 元素line-height | 元素font-size |
---|---|---|---|---|---|---|
水果6p | 414 | 3 | 0.333333 | 124.2px | 0.688rem(85px) | 36px |
水果6 | 375 | 2 | 0.5 | 75px | 0.688rem(51.3px) | 24px |
水果5 | 320 | 2 | 0.5 | 64px | 0.688rem(44px) | 24px |
上面分別是三款水果手機上某寶網頁的資料,其中挑選了某個頁面自適應元素,記錄了它的行高(括號中是實際高度),和字型大小。
在分析資料之前,我們先了解一下dpr是什麼東西:
我們都知道畫素,裝置上能顯示的畫素數量稱為物理畫素,每臺裝置的物理畫素都是固定的;而我們在開發頁面的時候使用的畫素稱為裝置獨立畫素(dips),是人為設定的。然後就有這麼一個公式:dpr=物理畫素/dips (單個方向上)
以前顯示技術不發達的時候,裝置螢幕有多大,能顯示多少畫素,那開發者就做多少畫素的網頁,比例為1:1,那dpr就是1。後來水果推出了一款螢幕,可以在同樣大小的螢幕上顯示多一倍的畫素(單個方向上),也就是說裝置畫素*2,dpr=2,dpr為2的螢幕在放大一倍後依然能保持原來的清晰度,為了適應這種螢幕,網頁開發人員就必須設計比以前高寬大一倍的網頁,然後在初始顯示的時候縮小一倍,以適應使用者的放大操作。(dpr為3同理)
理解了dpr後應該就有點眉目了,我們以水果6為基礎,這個終端的dpr是2,那麼UI設計師先做出一份寬度為375*2=750px的設計稿,前端按照750px寬度進行重構,設定某元素的font-size為24px,行高為51.3px。那麼我們為了實現rem佈局,要給這個頁面的根元素設定一個font-size初始值,某寶設定為75px(設定為100px是最簡單的,那麼24px就等於0.24rem了,但別的螢幕依然不好算,算),那這個元素的line-height就是:51.3/75=0.684,約等於0.688(因為資料都沒有精確,所以會算不準),按照這個方法給整個頁面需要自適應的地方去設定,因為設計稿是放大一倍的,所以最後還要在viewport上面設定scale為0.5。(要注意的一點是某寶沒有用rem給元素設定font-size,它是根據dpr設定的固定值,目的是把字型大小定義到12獨立畫素)
那麼我們的初始頁面已經OK了,接下來可以根據上面的規則來計算別的終端。
我們來看一下水果5的設定,換了個終端,dpr沒變,變的只是螢幕的寬度,那麼為了實現rem自適應,等比縮放,螢幕寬度縮小了一定比例,html font-size也要縮小一定比例,那麼就有:375/75=320/64=5,也就是說水果5的html font-size應該設定為64px,那麼剛才那個元素的行高就變成了64*0.688=44(跟表上一樣)。
來看看水果6p,這裡dpr變了,也就是說裝置畫素變成了三倍,所以我們的scale也要變成0.3333,設計稿也要變成原來的3倍,與dpr為2的情況對比的話就是1.5倍。那麼html font-size就要設定為375/75=(414*1.5)/fs,fs=124.2,初始scale=1/3=0.33333,元素font-size=24*1.5=36。
其他的螢幕也以此類推就好。
PS:rem佈局是以動態改變長度來進行頁面自適應,只能處理簡單的頁面縮放,假如想要實現PC移動端通用的動態佈局的話還是需要使用CSS3的@media來進行詳細的佈局。