移動端高清適配方案(解決圖片模糊問題、1px細線問題)

來源:互聯網
上載者:User

標籤:nap   origin   ica   部分   螢幕尺寸   除了   width   attr   而在   

  本文介紹了移動端適配的3種方法,以及移動端圖片模糊問題和1px細線問題的解決方案。當然了,在這之前先整理了與這些方法相關的知識:物理像素、裝置獨立像素、裝置像素比和viewport。

>>>>物理像素、裝置獨立像素和裝置像素比

  在CSS中我們一般使用px作為單位,需要注意的是,CSS樣式裡面的px和物理像素並不是相等的。CSS中的像素只是一個抽象的單位,在不同的裝置或不同的環境中,CSS中的1px所代表的物理像素是不同的。在PC端,CSS的1px一般對應著電腦螢幕的1個物理像素,但在移動端,CSS的1px等於幾個物理像素是和螢幕像素密度有關的。

物理像素(physical pixel)

  物理像素又被稱為裝置像素、裝置物理像素,它是顯示器(電腦、手機螢幕)最小的物理顯示單位,每個物理像素由顏色值和亮度值組成。所謂的一倍屏、二倍屏(Retina)、三倍屏,指的是裝置以多少物理像素來顯示一個CSS像素,也就是說,多倍屏以更多更精細的物理像素點來顯示一個CSS像素點,在普通螢幕下1個CSS像素對應1個物理像素,而在Retina螢幕下,1個CSS像素對應的卻是4個物理像素(參照下文田字理解)。

裝置獨立像素(device-independent pixel)

  裝置獨立像素又被稱為CSS像素,是我們寫CSS時所用的像素,它是一個抽像的單位,主要使用在瀏覽器上,用來精確度量Web頁面上的內容。

裝置像素比(device pixel ratio)

  裝置像素比簡稱為dpr,定義了物理像素和裝置獨立像素的對應關係:裝置像素比 = 物理像素 / 裝置獨立像素。

  CSS的1px等於幾個物理像素,除了和螢幕像素密度dpr有關,還和使用者縮放有關係。例如,當使用者把頁面放大一倍,那麼CSS中1px所代表的物理像素也會增加一倍;反之把頁面縮小一倍,CSS中1px所代表的物理像素也會減少一倍。關於這點,在文章後面的1px細線問題部分還會講到。

>>>>viewport

  viewport就是裝置上用來顯示網頁的那一塊地區,但viewport又不局限於瀏覽器可視地區的大小,它可能比瀏覽器的可視地區要大,也可能比瀏覽器的可視地區要小。在預設情況下,一般來講,行動裝置上的viewport都是要大於瀏覽器可視地區的,這是因為考慮到行動裝置的解析度相對於案頭電腦來說都比較小,所以為了能在行動裝置上正常顯示那些傳統的為案頭瀏覽器設計的網站,行動裝置上的瀏覽器都會把自己預設的viewport設為980px或1024px(也可能是其它值,這個是由裝置自己決定的),但帶來的後果就是瀏覽器會出現橫向捲軸,因為瀏覽器可視地區的寬度是比這個預設的viewport的寬度要小的。

明確三種不同的viewport視口:

  visual viewport 可見視口,指螢幕寬度

  layout viewport 布局視口,指DOM寬度

  ideal viewport 理想適口,使布局視口就是可見視口即為理想適口

擷取螢幕寬度(visual viewport)的尺寸:

window. innerWidth/Height

擷取DOM寬度(layout viewport)的尺寸:

document. documentElement. clientWidth/Height

設定理想視口ideal viewport:

<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

該meta標籤的作用是讓layout viewport的寬度等於visual viewport的寬度,同時不允許使用者手動縮放,從而達到理想視口。

  meta[name="viewport"]裡各參數的含義為:

  width: 設定layout viewport 的寬度,為一個正整數,或字串”width-device”。

  initial-scale: 設定頁面的初始縮放值,為一個數字,可以帶小數。

  minimum-scale: 允許使用者的最小縮放值,為一個數字,可以帶小數。

  maximum-scale: 允許使用者的最大縮放值,為一個數字,可以帶小數。

  height: 設定layout viewport 的高度,這個屬性對我們並不重要,很少使用。

  user-scalable: 是否允許使用者進行縮放,值為“no”或“yes”。


>>>>rem適配方案

  適配是為了使頁面在不同手機裝置上,相對保持統一的效果。移動端自適應方案很多,有百分比布局,彈性盒模型布局等,但是最好用的要數rem布局了。

rem是相對於根項目的字型大小的單位,我們可以根據裝置寬度動態設定根項目的font-size,使得以rem為單位的元素在不同終端上以相對一致的視覺效果呈現。下面介紹3種根據螢幕寬度設定rem基準值的方法。(註:為了換算方便,以下三種方法都用1:100的比例,即1rem=100px。)

用JS設定rem基準值

/* 設計稿是750,採用1:100的比例,用1rem表示100px,font-size為100 * (clientWidth / 750) */(function(doc, win) {    var docEl = doc.documentElement,        resizeEvt = ‘orientationchange‘ in window ? ‘orientationchange‘ : ‘resize‘,        recalc = function() {            var clientWidth = docEl.clientWidth;            if (!clientWidth) return;            docEl.style.fontSize = 100 * (clientWidth / 750) + ‘px‘;        };    if (!doc.addEventListener) return;    win.addEventListener(resizeEvt, recalc, false);    doc.addEventListener(‘DOMContentLoaded‘, recalc, false);})(document, window); 

用密集的媒體查詢設定font-size

/* 設計稿是750,採用1:100的比例,用1rem表示100px,100*(100/750)=13.333 以min-width: 750px時font-size: 100px為基準,min-width每縮小100px,font-size就縮小13.3333px,如需更密集的媒體查詢可以按照這個對照關係設定。*/@media screen and (min-width: 320px) {    html {        font-size: 42.6667px;    }}@media screen and (min-width: 375px) {    html {        font-size: 50px;    }}@media screen and (min-width: 425px) {    html {        font-size: 56.6667px;    }}@media screen and (min-width: 768px) {    html {        font-size: 102.4px;    }}

用單位vw設定font-size

  1vw等於螢幕可視區寬度(的可視地區的百分之一。

/* 設計稿是750,採用1:100的比例,用1rem表示100px,font-size為100*(100vw/750) */html {    font-size: 13.3334vw;}

注:相容性不是很好。

  瞭解了物理像素、裝置獨立像素、裝置像素比和viewport這幾個重要概念後,來看一下移動端開發中,由於螢幕解析度導致的兩個經典問題:圖片模糊問題和1px細線問題。(註:為了敘述簡潔,以下多倍屏均只敘述2倍Retina屏,其它螢幕同理。)

>>>>圖片模糊問題

  一個位元影像像素是柵格映像(如:png, jpg, gif等)最小的資料單元。每一個位元影像像素都包含著一些自身的顯示資訊(如:顯示位置,顏色值,透明度等)。理論上,1個位元影像像素對應於1個物理像素,圖片才能得到完美清晰的展示。對於dpr=2的Retina螢幕而言,1個位元影像像素對應於4個物理像素,由於單個位元影像像素不可以再進一步分割,所以只能就近取色,導致圖片看起來比較模糊,如。

  對於圖片模糊問題,比較好的方案就是用多倍圖片(@2x)。如:一個200×300(CSS pixel)的img標籤,對於dpr=2的螢幕,用400×600的圖片,如此一來,位元影像像素點個數就是原來的4倍,在Retina螢幕下,位元影像像素點個數就可以跟物理像素點個數形成 1 : 1的比例,圖片自然就清晰了。

  如果普通螢幕下,也用了兩倍圖片,會怎樣呢?

  在普通螢幕下,200×300(CSS pixel)img標籤,所對應的物理像素個數就是200×300個,而兩倍圖片的位元影像像素個數是200×300×4個,所以就出現一個物理像素點對應4個位元影像像素點,但它的取色也只能通過一定的演算法取某一個位元影像像素點上的色值,這個過程叫做(downsampling),肉眼看上去雖然圖片不會模糊,但是會覺得圖片缺少一些銳利度,或者是有點色差,如。

  所以最好的解決辦法是:不同的dpr下,載入不同的尺寸的圖片。不管是通過CSS媒體查詢,還是通過JS條件判斷都是可以的。

>>>>1px細線問題

  在上文我們已經知道,CSS像素為1px寬的直線,對應的物理像素是不同的,可能是2px或者3px,而設計師想要的1px寬的直線,其實就是1物理像素寬,如。

  對於CSS而言,可以認為是border: 0.5px;,這是多倍屏下能顯示的最小單位。然而,並不是所有手機瀏覽器都能識別border: 0.5px,有的系統裡,0.5px會被當成為0px處理,那麼如何?這0.5px呢?網上有很多解決方案,比如border-image 圖片、background-image 漸層、box-shadow 等,因為這些方案不太好,所以不做贅述了,我推薦兩種方法:用媒體查詢根據dpr用“虛擬元素+transform”對邊框進行縮放;用JS根據螢幕尺寸和dpr精確地設定不同螢幕所應有的rem基準值和initial-scale縮放值。

虛擬元素+transform

構建1個虛擬元素, border為1px, 再以transform縮放到50%。

/* 設計稿是750,採用1:100的比例,font-size為100*(100vw/750) */.border-1px {    position: relative;}@media screen and (-webkit-min-device-pixel-ratio: 2) {    .border-1px:before {        content: " ";        position: absolute;        left: 0;        top: 0;        width: 100%;        height: 1px;        border-top: 1px solid #D9D9D9;        color: #D9D9D9;        -webkit-transform-origin: 0 0;        transform-origin: 0 0;        -webkit-transform: scaleY(0.5);        transform: scaleY(0.5);    }}

用JS計算rem基準值和viewport縮放值

/* 設計稿是750,採用1:100的比例,font-size為100 * (docEl.clientWidth * dpr / 750) */var dpr, rem, scale;var docEl = document.documentElement;var fontEl = document.createElement(‘style‘);var metaEl = document.querySelector(‘meta[name="viewport"]‘);dpr = window.devicePixelRatio || 1;rem = 100 * (docEl.clientWidth * dpr / 750);scale = 1 / dpr;// 設定viewport,進行縮放,達到高清效果metaEl.setAttribute(‘content‘, ‘width=‘ + dpr * docEl.clientWidth + ‘,initial-scale=‘ + scale + ‘,maximum-scale=‘ + scale + ‘, minimum-scale=‘ + scale + ‘,user-scalable=no‘);// 設定data-dpr屬性,留作的css hack之用,解決圖片模糊問題和1px細線問題docEl.setAttribute(‘data-dpr‘, dpr);// 動態寫入樣式docEl.firstElementChild.appendChild(fontEl);fontEl.innerHTML = ‘html{font-size:‘ + rem + ‘px!important;}‘;

  相較與於上文rem適配方案裡“用JS計算rem基準值”的方案,這個“用JS計算rem基準值和viewport縮放值”的方案可以解決1px細線問題。表格以2倍Retina屏做比較,其他多倍屏同理。

  用JS根據螢幕尺寸和dpr精確地設定不同螢幕所應有的rem基準值和initial-scale縮放值,這個JS方案已經在完美解決了1px細線問題,我們不需要再做任何事情,至於圖片模糊問題,只需要根據data-dpr的值動態載入不同尺寸的圖就可以了。

 

 

 

分享一個公眾號-----前端麻辣燙 ,一個專註於前端技術學習與交流的公眾號~

 

搜尋“WebSnacks”,或者掃描下方二維碼。

 

移動端高清適配方案(解決圖片模糊問題、1px細線問題)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.