屏幕適配是一個很容易被忽略的問題,但對於精益求精的產品而言,是必不可少的。對於Web開發的求職者而言,也是一個必須要理解清楚的經典問題javascript
文 | 啃先生 Mar,1st,2016css
移動端適配的是什麼?
咱們討論的是網頁適配多種尺寸屏幕,讓網頁效果看起來和設計師的設計稿同樣。說白了就是同一套代碼在不一樣分辨率的手機上跑時,頁面元素間的間距,留白,以及圖片大小會隨着變化,在比例上跟設計稿一致。html
舉個例子吧前端
圖1. 260*400的屏幕java
圖2. 380*400的屏幕git
上邊的頁面在不一樣大小屏幕上的展示,咋一看沒什麼問題,通常的工程師會認爲已經OK了,因此前端工程師很容易忽略屏幕適配。可是對於一些精益求精的產品而言,這還達不到要求。例若有如下問題:github
圖1的屏幕的尺寸較小,所以頭像應該小些,話題左邊的空白也應該小一些。算法
圖片應該保持正方形,並且兩張圖之間的邊距應該隨屏幕變化而變化瀏覽器
明白了,因此padding,margin,圖片等的大小基本都要作適配前端工程師
那有什麼方法能夠作到這種適配?
關鍵要找到一種長度單位,使得同樣的取值,在不一樣尺寸的屏幕上的大小按比例縮放。
長度單位我只知道px ?
我將在下一期的文章裏推有關viewport和css像素px中的細節,這篇文章只關注如何適配,因此先只談結論:
網頁在viewport中佈局,viewport被分紅一個個小方塊,一個CSS像素佔一個方塊
在設置了viewport寬度等於設備寬度的狀況下,經過某種算法,在不一樣大小的屏幕上,1個CSS像素所佔屏幕的物理尺寸是同樣大的
既然1個CSS像素在不一樣屏幕上物理尺寸同樣大,那px確定不能作爲適配的方法了
長度單位rem是相對於html標籤的font-size來計算的。例如html標籤設置font-size:36px,同時div設置width:1.2rem。那麼這個div的寬度就是1.2rem=36px*1.2=43.2px
如上面的例子,若是加載頁面的時候,使用JS根據屏幕的大小動態設置html標籤的font-size,隨着html標籤font-size的值變化,div的1.2rem換算成px的值 也跟着變化,即實現了div隨屏幕大小變化而變化,而CSS代碼始終是width:1.2rem。以此類推到頁面全部的元素。
明白了,奧祕就在於結合px的固定尺寸和rem的相對尺寸!
原理我明白了,你有沒有可執行的具體方案 ??
業內比較流行的作法(參考阿里的flexible),有如下要點:
設置viewport爲設備寬度(這裏不必定,但目前先這樣足矣)
將viewport分紅10rem,並計算出1rem在當前瀏覽器的像素值,把它賦予html標籤的font-size(分紅10rem只是爲了方便計算而已)
寫CSS代碼時,遇到要適配的地方,好比width,margin,padding等,就不要再用px了,改爲用rem
JS和Html代碼以下:
<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, height=device-height"> <title>啃先生的網</title> <script type="text/javascript"> var cssEl = document.createElement('style'); document.documentElement.firstElementChild.appendChild(cssEl); function setPxPerRem(){ var dpr = 1; //把viewport分紅10份的rem,html標籤的font-size設置爲1rem的大小; var pxPerRem = document.documentElement.clientWidth * dpr / 10; cssEl.innerHTML = 'html{font-size:' + pxPerRem + 'px!important;}'; } setPxPerRem(); </script> </head> <body> </body> </html>
CSS代碼作了相似以下的修改:
運行結果以下:邊距和頭像圖片都隨屏幕變化而變化了
代碼量不多,就是要理解消化。有一個問題,設計師給的設計稿尺寸單位都是用px,可是剛剛說的第3步,寫CSS的時候要用rem,這個怎麼換算?會很麻煩
現有設計師提供寬度爲400px的設計稿,其中某個圖片的寬度設計爲20px,那麼,CSS的寫法就是img{width: 0.5rem;},怎麼得出這個結果的呢?
設計稿的寬度視同手機寬度,即假設有一個viewport爲400px的手機
將它分紅10rem,每一個rem爲40px;
那麼圖片寬度20px天然就是0.5rem;
且慢,豈不是意味着,每次寫到尺寸的地方,我都要先在草稿紙上把設計師給的px換算成rem?別急,sublime text 3有一款插件能夠幫助你進行這個換算,你只須要輸入20px,它會自動幫你換算成 0.5rem,看如下圖就秒懂了
使用Flexible實現手淘H5頁面的終端適配(https://github.com/amfe/article/issues/17)
移動端高清、多屏適配方案(http://www.html-js.com/article/Mobile-terminal-H5-mobile-terminal-HD-multi-screen-adaptation-scheme%203041)
A tale of two viewports(http://www.quirksmode.org/mobile/viewports.html)
移動適配這個會做爲一個小系列來寫,下期寫瀏覽器是怎麼計算CSS像素的,它在不一樣屏幕上的差別。
啃先生 開始碼字才知道碼字不易,堅持碼字更不易。轉載請聲明來源