1. 固定寬度(320)作法:這樣前端卻是爽了,但是大頁面兩邊有留白,小頁面圖標文字又會縮的很小,用戶體驗極其很差。css
2. 流式佈局:其實就是用%,這樣寬度倒還差很少,高度怎麼搞?因此這種佈局通常都是寬度自適應高度寫死,顯的很不協調,另外對設計也有很大的限制,另外還有兼容性方面的問題。html
3. 響應式佈局:說白了就是利用CSS3中的Media Query(媒介查詢),喊的很火,誰用誰知道,簡直累死人不要命。前端
4. 設置viewport進行縮放:以320寬度爲基準,進行縮放,最大縮放爲320*1.3 = 416,基本縮放到416都就能夠兼容iphone6 plus的屏幕了。<meta name="viewport" content="width=320,maximum-scale=1.3,user-scalable=no">git
5. 利用vh、vw適配:兼容性太差。github
rem是一個相對根元素html字體大小的單位,因此它的大小是由html的fontSize大小決定的,假如我把html的fontSize設置爲10px,此時的1rem就等於10px,假如我把html的fontSize設置爲100px,此時的1rem就等於100px,這也正是咱們能用rem作移動端適配的根本緣由,就是經過不一樣屏幕下改變根元素fontSize的大小,從而讓以rem爲單位的各類元素自動隨着改變。web
經過下面這句話得到理想視口(ideal viewport):chrome
<meta name="viewport" content="width=device-width">
既然要適配,就要選一個理想視口作基準,而後才能在此基礎上等比縮放(這裏等比縮放最好不包括文字,後面講緣由),咱們通常選擇iphone6的375,爲何選它呢?瀏覽器
由於市場上的Android機五花八門(理想視口寬通常在320-480之間),且沒有任何一款的佔有率能和iphone相比,選取iphone中的iphone6能更好的向下適配iphone5和向上適配iphone6 plus等,關於各機型的理想視口(ideal viewport)詳見VIEWPORT SIZESsass
上面說了咱們要以iphone6爲基準,那麼設計圖咱們作成多大呢?dom
設計圖作成750px寬,由於iphone6的物理像素是750(上面咱們說的375是它的設備獨立像素,又是理想視口),咱們要想作到高清就要1個設計像素對應一個物理像素才成,他們之間的關係見下表:
iPhone6 plus | iPhone6 | iPhone5 | |
物理像素(physical pixel) | 看公式 | 看公式 | 看公式 |
設備獨立像素(density-independent pixel) | 414x736 | 375×667 | 320x568 |
設備像素比(device pixel ratio ) | 3 | 2 | 2 |
設備像素比(dpr),咱們能夠經過JavaScript獲取的辦法是:window.devicePixelRatio
;用CSS獲取的辦法是-webkit-device-pixel-ratio
。咱們能夠用-webkit-min-device-pixel-ratio
和-webkit-max-device-pixel-ratio
進行媒體查詢,以達到適配不一樣dpr的需求。
原理:用媒體查詢理想視口(上面咱們把width=device-width了,因此查詢width便可),不一樣理想視口設置不一樣的根元素fontSize。
一張750的設計稿,假如其根元素爲100px(爲何是100px而不是其餘的呢?),此時我想表示一個750px*100px的div,我只須要寫成:
div{width:7.5rem; height:1rem;}
那麼問題來了,我在iphone6下把根元素字體設爲多大才能讓這個div等比顯示呢?要想等比顯示那麼他們之間有這樣一個關係:
100px / 750 = iphone6 根元素fontSize / iphone6理想視寬(375)
根據上面公式算出iphone6 根元素fontSize = 50px,也就是在iphone6下咱們只須要改變根元素fontSize爲50px就能夠作到等比縮放啦~~
那麼問題又來了,手機那麼多,各類機型的理想寬度也數不勝數(其實大多都在320到480之間,上面有說),那麼其對應根元素fontSize我該怎麼寫呢?
做爲一個CSSer,咱們最早想到的是媒體斷點查詢,例如像下面這樣:
@media screen and (min-width:321px) and (max-width:375px){ html{font-size:42px} } @media screen and (min-width:376px) and (max-width:414px){ html{font-size:50px} } @media screen and (min-width:415px) and (max-width:639px){ html{font-size:55px} } @media screen and (min-width:640px) and (max-width:719px){ html{font-size:85px} } @media screen and (min-width:720px) and (max-width:749px){ html{font-size:95x} } @media screen and (min-width:750px) and (max-width:800px){ html{font-size:100px} }
上面的缺點一目瞭然,就是不夠精細嘛,例如415-639理想視寬的手機顯示的東西倒是同樣大,對於像素級要求的咱們這怎麼能成呢?
因而乎我用sass把從320到750所有算一遍不就能夠啦,就像下面這樣:
@media (max-width: 320px){ html{ font-size: 266.66667%; } } @for $i from 320 through 750 {@media (width:#{$i}px){ html{font-size: $i/1.2 * 1%}} } @media (min-width: 750px){ html{ font-size: 625%; } }
Sass生成結果(景象過於壯觀慎入),大功告成,這樣咱們不用JavaScript也能實現和其同樣的精細效果了。使用時只需在頭部引用這樣一個CSS文件便可,假如750上你量出的div大小爲width:85px;height:100px;
,寫的時候只需除以100便可,即width:.85rem;height:1rem;
你要嫌除的麻煩sublime中能夠裝這麼一個轉換插件。
這時確定會有人吐槽性能問題洛,壓縮後的media100px.css大概10幾kb的樣子,我看了下我們移動網站的一個普通商品圖大概是它的2倍,固然拿兩個東西進行比較是有點不太穩當,具體增長這麼些樣式會影響多大性能暫未驗證。
之因此在750下把根元素設爲100而不是其餘,是由於方便計算嘛,1rem等於100px,.2rem就等與20px這樣多好算啊,有人會問你丫設爲10不同好算啊,話說通常瀏覽器顯示的最小字號是12px,因此就100啦,固然數學好的你用其餘值也是能夠的。
上面用Sass生成的css根元素字體大小我是用%號表示的,就是100px,我寫的是625%,有人可能會問你這幹嗎畫蛇添足呢,625%不就是100px嘛,有人給出了下面幾個理由,我抄下來共你們參考:
上面直接引用直接media100px.css的確不是最好的方案,你知道我要說什麼啦,那就是用JavaScript適配,其實咱們把上面的Sass循環改爲用JS寫就行了,就像下面這樣:
!(function(doc, win) { var docEle = doc.documentElement, evt = "onorientationchange" in window ? "orientationchange" : "resize",//區分Mobile和PC以加載不一樣的事件 fn = function() { var width = docEle.clientWidth; if( width < 320 ) { docEle.style.fontSize = 42.6667 + "px"; } else if( width > 750 ) { docEle.style.fontSize = 100 + "px"; } else { //以750設計稿寬度爲基準設置fontSize:100px;這樣保證iPhone6如下是高清 docEle.style.fontSize = 100 * (width / 750) + "px"; } }; win.addEventListener(evt, fn, false); //load事件是在頁面全部元素都加載完後觸發; //DOMContentLoaded,它是指dom tree加載完就觸發,頁面引用的樣式表和圖像文件可能尚未加載完成 doc.addEventListener("DOMContentLoaded", fn, false); }(document, window));
在使用的時候你能夠單獨引用這樣一段JS (看上面我又不用%而用px啦,測試(chrome模擬手機測試的)後發現%和px最終造成網頁效果並沒有差異),不使用不引用便可;或者把這段JS放在公共JS文件裏,而對於不想使用rem的同窗只需覆蓋JS設置的樣式便可,例如像下面這樣:
html{font-size:20px!important;}//這裏移動端默認字體大小根據狀況本身設置
1.文字最好不要用rem表示,由於:
其一:設計師通常但願是文字在移動設備上的顯示大小是同樣的,也就是咱們所說的等比適配(注意是等比適配不包括,不是適配)是不該包括文字的;
其二:咱們用rem後文字會很小(雖然這正是等比縮放的結果),固然這也和設計有關(理論上字體須要等比適配的話750px設計圖上是不該該有小於24px字體出現的,既然有也說明字體不該該等比適配),例如我在設計圖上量取的文字大小是24px,那麼其iphone6下的顯示大小就是.24rem*50=12px,而設計圖上哪些24如下的字體此時也會顯示12px(假如最小字體是12的話),這也會有另一個問題,就是設計圖上明明是不一樣字體大小表示的文案,在手機上顯示的大小倒是同樣的,起不到設計師想要表達的區分或者強調的做用;
其三:網上有說會變模糊之類的,我暫時未發現(暴漏了我依然表示字體用rem表示的...)。
解決辦法:能夠分斷點區間,設置不一樣的fontSize大小,能夠參考點我
2.1px和2px不要寫成.01rem和.02rem,由於:
以750適配的方案爲例,當理想視口爲320時,其對應font-size: 266.66667%; 而後乘以默認字體大小16px,最後爲42.6666672px,也就是43px,若寫爲.01rem或.02rem表示分別對應.42px或.96px,在直接取整的瀏覽器下是顯示不出來的。因此對於1像素邊框的就不要寫.01rem啦。
3.當咱們寫1px時,實際在dpr爲2的手機下顯示的是2個物理像素,看起來會粗一點,解決方案能夠參照淘寶的flexible,其原理是根據dpr的不一樣動態設置initial-scale的值,也能夠用下面方法實現:
.scale { position: relative; height: 50px; line-height: 50px; background-color: #ccc;
} .scale:after { position: absolute; content: ''; width: 100%; left: 0; bottom: 0; height: 1px; background-color: red; -webkit-transform: scale(1,.5); transform: scale(1,.5); -webkit-transform-origin: center bottom; transform-origin: center bottom;
}
注:JavaScript適配方案是一種思路或者中心思想,在實際使用中會有其餘一些問題須要注意,例如JS的加載時機以及其餘有一些安卓機的奇怪問題,具體能夠參考淘寶的flexible解決方法,或者參考咱們目前在用的方案:flexible精簡版下載。
以上文字友好閱讀方式:點我下載