移動端適配方案進階

來源:互聯網
上載者:User

         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

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.