Web頁面做移動端適配,就是在不同尺寸的手機裝置上,頁面“相對性的達到合理的展示(自適應)”或者“保持統一效果的等比縮放(看起來差不多)”。有幾個要點必須要掌握,一個是不同尺寸,一個是清晰,還有一個是合理。為什麼強調這幾個詞當然是有原因的。
一、目標
1. 頁面配置總是按照一定規則來進行的。但是行動裝置卻是多種多樣的,螢幕尺寸大小不同,解析度不同,像素比不同,寬高也不同(相應的概念會在後面介紹)。所以要讓一套代碼適應所有裝置,是最棘手的。、
2. 要保證清晰度,小屏手機和大屏手機用同樣的圖片,通過縮放效果顯示的大小比例是一致的,但是圖片放大會失真,高清圖縮小預覽又浪費。這就需要綜合考慮情況了。
3. 所謂合理展示,指的是不論什麼裝置都能有原設計稿一樣的視覺和體驗效果。如果單純的按照固定的像素px來設定寬高,結果會怎樣。要麼小屏手機出現捲軸,要麼大屏手機有留白。雖說是原樣輸出,但這並不是設計稿的效果。人家設計稿是全屏完美展示,不能到手機上變成半屏或兩屏了。所以說還原設計稿可以理解成等比例縮放。
二、思考
我們的目的搞清楚了,但是還是不得不先潑一潑冷水。首先,沒有絕對完美的適配方案。不可能讓所有裝置真正100%還原設計稿。因為裝置的寬高比例就不盡相同五花八門,光這一點就沒辦法解決,比如說你想用同一張圖片給正方形和長方形做壁紙,總有一個會被展開或是留白。所以目前通用的原則是文字流式,控制項彈性,圖片等比縮放。借用萬能網路片展示下效果。
有了目標和大致想法接下來差不多上方案了,為了更好講解,還得科普幾個知識點。
三、基本概念
螢幕尺寸(inch):手機裝置的對角線長度,比如iphone5為4英寸。
螢幕寬高比:手機的高度與寬度的比例 為16:9
物理像素(px): 顯示器(手機螢幕)上最小的物理顯示單元,比如iphone5的物理像素是640*1136
像素密度(PPI): 表示沿著對角線,每英寸所擁有的物理像素(Pixel)數目,值越低顆粒感越強,超過300人眼很難分辨
裝置獨立像素|密度無關像素|邏輯像素(px): 可以認為是電腦座標系統中得一個點,這個點代表一個可以由程式使用的虛擬像素(比如: css像素),然後由相關係統轉換為物理像素。比如iphone5的物理像素是320*568
像素比(pdr): 物理像素和裝置獨立像素的對應關係,裝置像素比 = 物理像素 / 裝置獨立像素,比如iphone5的像素比是2。
以上概念如果一下接受不了自行百度吧。在這裡主要解釋下pdr,原來的顯示裝置的pdr都是1,後來引入了高清屏有了retina,這個pdr就出現了。當然是值越高,顯示效果越清楚,同時意味著用css控制某個像素的時候,實際上控制的是成倍的物理像素。最簡單的例子是用Iphone5截個圖,雖然css下最寬只有320px,但是把圖片放到電腦上就成了640px了。
四,深入瞭解適配下的高清問題
用多大的圖片才能清晰?
如果在pdr為1的情況下,要顯示100*100的圖片,用50*50,100*100還是200*200的圖片。當然我們都能理解50*50肯定是要排除的。不過,原因是什麼我們還需要討論一下。換個更形象的說法,要用要求的紅黃顏料填滿2個坑,是要用一種顏料還是2種還是4種。如果用一種顏料同時顯示紅與黃的效果,那麼只能把兩種顏料先混合再倒入,結果肯定會失真;如果用兩種,分別用紅和黃倒入,那麼就涇渭分明;如果用4種呢,就得壓縮一半塞進去,也就是說紅和黃已經被壓縮了一半,還會滲進其它顏色才填滿。這個時侯,顯示效果會失去銳度。所以不論給的圖片大了還是小了都不會模糊。
但是好多裝置不是單單的pdr為1,如果等於2的時候,要顯示100*100的圖片,就需要200*200的圖片;如果pdr為3,就要引入300*300的圖片,同樣有更多像素比的裝置,不可能一一滿足,因此普通做法是提供2x,3x圖片。
五、適配方案
終於要講到方案了,上面也講到了要實現自適應就是等比例縮放。因此我們想到三種方案。
一,按百分比設定寬高。可能實現適配效果,缺點是會出現展開,模糊,因為裝置寬高比不同,高度很難用百分比控制。
二,viewport縮放
在頁面內可以設定viewport的scale
屬性來控制頁面顯示比例。類似於放大縮小圖片,通過計算裝置寬度與設計稿的比例來得出縮放的倍數,最終實現適配效果。為了適配大多數裝置並保證清晰度要採用更大解析度的設計稿,感覺有些浪費資源。
三、rem相對單位
因為rem是相對單位,它會以Htm的font-size的大小為基數來計量長度。所以計算裝置螢幕寬度與設計稿的比例來動態裝置html的font-size,。這樣就能在不同裝置上等比例來顯示。相當於先把螢幕寬度等分成固定的份數,然後再以份數作為單位計量。
其實現在的適配方案不外乎這麼幾種,尤其第三種操作起來很方便(後面會附上代碼)。不過,阿里團隊為了追求清晰度和解決1px的問題又推出了高清適配方案,主要是把像素比考慮進去,結合第二種第三種方案來實現。方法是先用裝置寬度與pdr相乘然後取到與設計稿的比例,動態設定html的font-size,最後再根據pdr的值動態設定scale來實現縮放。
備忘:1px問題指的是在使用rem後,會出現像素值為小數的情況,小數位可能會被系統直接忽略掉,出現寬窄不同的現象。
附普通適配方案(代碼摘自網路):
1 <script type="text/javascript"> 2 new function (){ 3 var _self = this; 4 _self.width =1080;//設定UI提供的基準尺寸 5 _self.fontSize = 200;//預設字型大小,使用時除以此參數作為rem,建議取10或100容易計算。為保證Google良好適配,320/_self.width*_self.fontSize>12 6 _self.widthProportion = function(){ 7 var p = (document.body&& 8 document.body.clientWidth || 9 document.getElementsByTagName("html")[0].offsetWidth)/_self.width;10 11 return p>0.71?0.71:(p<0.3?0.3:p); //設定安全尺寸最寬768px,最小320px12 };13 console.log(_self.widthProportion());14 _self.changePage = function(){15 document.getElementsByTagName("html")[0].setAttribute("style","font-size:"+_self.widthProportion()*_self.fontSize+"px !important");16 }17 _self.changePage();18 window.addEventListener("resize",function(){_self.changePage();},false);19 };20 21 </script>
高清適配方案(代碼摘自網路):
1 <script> 2 (function(doc, win, designSize) { //designSize為設計稿的尺寸(寬) 3 var docEl = document.documentElement, 4 devWidth = docEl.clientWidth > 1080 ? 1080 : docEl.clientWidth, 5 dpr = devicePixelRatio || 1, 6 scale = 1 / dpr, 7 width = dpr * devWidth, 8 resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'onresize', //判斷橫屏和視窗重設 9 recalc = function() { 10 var clientWidth = docEl.clientWidth; 11 if (!clientWidth) return; 12 document.querySelector('meta[name="viewport"]') .setAttribute('content','width=' + width + ', 13 initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no'); 14 docEl.style.fontSize = devWidth / (designSize / 100) * dpr + 'px'; 15 }; 16 if (!doc.addEventListener) return; 17 win.addEventListener(resizeEvt, recalc, false); 18 doc.addEventListener('DOMContentLoaded', recalc, false); 19 })(document, window, 750);20 </script>
參考文章:
1190000008767416
http://www.aliued.com/?p=3166
www.jianshu.com/p/07669cb3e7c5