今天抽空再寫一篇~之前已經做了兩個Demo,主要是運用CSS+Html完成的,今天還是來完成一個Demo,搭建一個關於寵物的網站。在開始之前我們先介紹一個知識點,關於適配的。
其實對於學習前端來說,H5手機適配也是一個老生常談的問題了,當然網上也有大牛給瞭解決方案,這裡我就結合自己的實際情況分析一下這個適配問題。 基礎:
1.viewport
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />
這是加在<head></head>之間的,用來縮放螢幕內容的。 GIF => viewport
控制initial-scale這個參數就可以控制縮放比例,同時注意數值必須在maximum-scale和minimum-scale之間;user-scalable是用來禁止使用者放大縮小螢幕的。
2.dpr(裝置像素比)
dpr=物理像素/裝置獨立像素;在頁面上可以通過window.devicePixelRatio得到。
裝置獨立像素就是螢幕的寬度,比如iphone6為365px,iphone為320px.
物理像素就是螢幕上的像素點數。
上圖是dpr=2的樣子,例如就是一個手機螢幕寬度是360px,但是水平方向上的像素個數達到了720個,像素是顯示顏色的最小單位,也就是一個1px裡面水平方向塞了兩個像素。
3.rem
rem是css的一個單位,html的style中font-size的值為1rem,我們一般把螢幕寬度的1/10作為1rem, 例如螢幕寬度為375px,那麼1rem=37.5px; 開始:
現在我們就來試一試,根據UI給我們的圖,看如何來適配的。 => rem適配
就像畫畫要先開始描邊一樣,一拿到設計稿,我們就要先把大概的結構和架構給弄出來,這要用到上面講到的rem知識點。
上面講到了1rem=螢幕寬度的1/10,但是這個值是要我們自己去設定的,設定代碼如下:
document.addEventListener('DOMContentLoaded', function() { //設定rem,1rem=螢幕寬度的1/10; var rem = document.body.clientWidth / 10; document.querySelector('html').style.fontSize = rem + 'px';});
我們看設計稿上可以看到圖片的大小為176*176,那麼我們在頁面裡面該設定多少呢。
原理是這樣的:我們先假設設計稿是一個手機螢幕,螢幕的寬度=750,那麼對於設計稿來說,1rem=75px;所以176px=176/75=2.34rem;所以,在頁面上,我們需要寫的是2.34rem而不是176px;
同理,可以把所有有寬度的標註轉換成rem,這樣就可以把大概的架構給搭建起來。當然也有一些工具之類的,可以自動轉換px成rem,感興趣的話可以自己去找找。 適配方案:
其實只要會上面基本上就完成一大部分了,那為什麼要來一個適配方案呢?
不知道大家有沒有發現,上面的例子中viewport我用的是initial-scale=1.0,這樣本來是沒有什麼問題的,但是上面我們還講到了一點,叫做dpr,主要針對例如iphone的高清retina螢幕,它們的dpr比較高,這樣就會有一個顯示1px的問題。
上圖是在dpr=2(例如iphone6)裡面顯示1px的情況,因為1px有兩個像素點,所以沒有充分利用到高dpr的特性,而有些設計師希望的1是一個像素點,而不是1px,就是下圖的樣子。
所以就會有比較出名的flexible.js,這個是淘寶用到的螢幕適配方案,用到的就是這個。原理也很簡單,就是通過window.devicePixelRatio擷取dpr,然後將initial-scale設定為1/dpr,就是將螢幕整體縮小dpr倍。 => flexible.js方案
1.想用flexible這套方案注意不能加<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />這句話,因為它的代碼裡面會檢測你是否加了這句話,如果加了,它就不控制了。
2.還要注意的是字型,因為螢幕縮小之後,字型也縮小了,所以要把字型放大,如下:
html[data-dpr='1'] body{ font-size:12px;} html[data-dpr='2'] body{ font-size: 24px;} html[data-dpr='3'] body{ font-size: 36px;}
當然這樣添加如果比較麻煩的話,我們也可以用sass之類的工具後期批量修改。(這裡要注意,字型不能用rem控制,等下會講到。) 方案選擇:
上面的方案很完美啊,很好啊,而且是淘寶用的,那還選擇什麼呢,用flexible.js方案不就好了。。。
其實我開始也是用flexible.js方案的,但是這個方案是有問題的,問題的關鍵也是1px問題。
上面左邊是flexible.js方案的(字型沒做適配,不考慮字型問題),右邊是沒有用flexible.js的方案。
雖然是滿足的設計師的刁鑽眼睛,做到了1像素的邊框,但是這樣的體驗真的好嗎,使用者幾乎看不到邊框,太細了,看起來很費勁。
所以這個時候,一般的方案反而佔了優勢。
這個時候有人會說,flexible.js方案採用縮小方式可以提高圖片的真實度,不失真。
但實際上不是的這樣的,因為我們顯示的圖片都是用rem或者百分比來表示寬度或者高度的,而決定圖片顯示真實度的是這一片地區內顯示屏的像素的點數,縮放不縮放並不影響這一片地區的像素點,因為地區大小沒變。
所以基本上來說,用flexible.js方案的基本上是因為UI設計師對1px問題有強迫症導致的...
但是flexible.js也做了一些其他的事情,比如適配ipad,不能讓螢幕的寬度超過540px(因為無限放大會導致比例錯亂),如下圖。
綜上所述,我們不採用flexible.js縮小螢幕的方案,採用1:1螢幕方案,同時採用flexible.js的其他方案。 => 綜合方案
綜合方案相比flexible.js方案添加了<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />,因為flexible.js檢測到你用了scale,就用你的scale,而不會根據dpr去縮小螢幕;同時去掉了字型放大的css,實際上變簡單了。 字型適配:
其實如果字型用rem適配是可以保證設計稿完美縮放的,但是你想象一下,如果字型用rem之後,在pad上雖然整體不變,但是字就變得巨大無比,看起來是非常嚇人的。
(左邊是字型rem在pad上效果,右邊是字型px在pad上的效果)
那字型又不能用rem,可是我又覺得字型在pad上比較小怎麼辦。其實一般而言,淘寶,天貓都沒有對字型做什麼動作,它們的字在大屏手機上是比較小的,但是確實會有一些特殊情況,比如我們就是,我們的使用者是年紀偏大的,所以我們的字在大屏手機上是要稍微放大一些的。
這個時候就要用輪到@media登場了。
媒體查詢一般是用來做pc和手機端螢幕內容自適應的,這裡我們用來做字型縮放。
其實媒體查詢的痛點就是如何劃分螢幕寬度,從300-540,如何劃分,如何歸類,這個也是要根據具體情況具體分析的。
我這裡就簡單的按照400,500來劃分了,iphone5,iphone6,iphone6s採用<400方案,plus採用400,500之間的方案,ipad採用>500方案
@media (max-width: 400px) {}@media (min-width: 400px) and (max-width: 500px) {}@media (min-width: 500px) {}
=> 字型適配
(左邊是px正常在pad上的顯示,右邊是px媒體查詢在pad上的顯示)。
是不是稍微比正常的大了些。如果你覺得大了或者小了,可以通過調整媒體查詢來達到你的效果。
當然,寫這個媒體查詢其實也是比較麻煩的,這個你可以通過sass或者less去寫一些通用模版,這個就等你們自己去摸索了,這裡只是給你們提供一個思路。
對於字型的line-height,這個使用rem還是px。其實都可以,看實際情況,比如一個div高度為1rem,你完全可以設定line-height:1rem來達到垂直垂直置中的效果。 那麼對於在移動端顯示,怎麼才能做到完美適配呢。
這套基礎庫的移動端適配方案,使用的是手機淘寶團隊的flexible.js,具體可以查看大漠老師的文章:使用Flexible實現手淘H5頁面的終端適配,在這裡我簡單的介紹它的工作原理。
首先要瞭解的是rem,rem指相對於根項目的字型大小的單位。簡單的說它就是一個相對單位,當然這可能讓你想到em,但是em相對於父元素,而rem是相對於根項目。
舉個例子,讓我們瞭解em與rem的區別。
/* html元素 */ html { font-size: 100px; } /* html的子項目 */ body { font-size: 0.8em; // 100px * 0.8 = 80px font-size: 0.8rem; // 100px * 0.8 = 80px } /* body的子項目 */ div { font-size: 0.8em; // 100px * 0.8 * 0.8 = 64px font-size: 0.8rem; // 100px * 0.8 = 80px }
接著讓我們看看flexible.js的原理。
flexible.js的原理就是根據螢幕的寬度設定html元素的font-size,具體做法是計算出螢幕的寬度然後除以10,賦給html標籤的font-size屬性。
舉個例子:
如果螢幕的寬度是750px,flexible.js就會設定html的font-size為75px。
然後我們在寫所有元素的屬性時(margin, padding, width, height等)都以rem為單位,
同樣舉個例子:
如果螢幕的寬度是750px,flexible.js設定html的font-size為75px,一個按鈕在750px的設計稿下width為150px,我們就會把這個按鈕的樣式寫成:
.btn { width: 2rem; // 150px / 75px = 2rem;}
假設現在螢幕寬度切換到了640px, flexible.js設定html的font-size為64px,這個按鈕的width在640px下的大小其實相當於 2rem * 64px = 128px
讓我們來看一下:
150px / 750px = 128px / 640px = 1 / 5
我們會發現在不同的螢幕大小下,這個按鈕的寬度相對於螢幕的比例是不變的,這樣就可以實現UI元素跟隨螢幕大小而變化,從而實現適配。
最後要說明一下,以上只是舉例,實際情況稍有不同:
以上這種演算法只在螢幕寬度小於540px的情況下發生,這是為了避免在寬屏時,UI元素過大的情況,在大於540px的時候,html的font-size一直保持54px不變。
先說到這吧,下一篇會做個Demo來實際使用下。