在前端開發以前,視覺MM會給咱們一個psd文件,稱之爲視覺稿
。javascript
對於移動端開發而言,爲了作到頁面高清的效果,視覺稿的規範每每會遵循如下兩點:css
屏幕寬高
做爲基準
(之前是iphone4的320×480
,如今更多的是iphone6的375×667
)。基準
的2倍
,也就是說像素點個數是原來的4倍
(對iphone6而言:原先的375×667,就會變成750×1334)。問題:前端
×2
,就能夠解決高清問題?真實寬高
(也就是佈局問題)?帶着問題,往下看…java
在進行具體的分析以前,首先得知道下面這些關鍵性基本概念(術語)。web
一個物理像素是顯示器(手機屏幕)上最小的物理顯示單元,在操做系統的調度下,每個設備像素都有本身的顏色值和亮度值。算法
設備獨立像素(也叫密度無關像素),能夠認爲是計算機座標系統中得一個點,這個點表明一個能夠由程序使用的虛擬像素(好比: css像素),而後由相關係統轉換爲物理像素。瀏覽器
因此說,物理像素和設備獨立像素之間存在着必定的對應關係
,這就是接下來要說的設備像素比
。iphone
設備像素比(簡稱dpr)定義了物理像素和設備獨立像素的對應關係,它的值能夠按以下的公式的獲得:佈局
設備像素比 = 物理像素 / 設備獨立像素 // 在某一方向上,x方向或者y方向
在javascript中,能夠經過window.devicePixelRatio
獲取到當前設備的dpr。編碼
在css中,能夠經過-webkit-device-pixel-ratio
,-webkit-min-device-pixel-ratio
和 -webkit-max-device-pixel-ratio
進行媒體查詢,對不一樣dpr的設備,作一些樣式適配(這裏只針對webkit內核的瀏覽器和webview)。
綜合上面幾個概念,一塊兒舉例說明下:
以iphone6
爲例:
375×667
,能夠理解爲設備獨立像素(或css像素)。×2
,爲750×1334
。用一張圖來表現,就是這樣(原諒個人盜圖):
上圖中能夠看出,對於這樣的css樣式:
width: 2px; height: 2px;
在不一樣的屏幕上(普通屏幕 vs retina屏幕),css像素所呈現的大小(物理尺寸)是一致的,不一樣的是1個css像素所對應的物理像素個數是不一致的。
在普通屏幕下,1個css像素 對應 1個物理像素(1:1
)。 在retina 屏幕下,1個css像素對應 4個物理像素(1:4
)。
一個位圖像素是柵格圖像(如:png, jpg, gif等)最小的數據單元。每個位圖像素都包含着一些自身的顯示信息(如:顯示位置,顏色值,透明度等)。
談到這裏,就得說一下,retina下圖片的展現狀況?
理論上,1個位圖像素對應於1個物理像素,圖片才能獲得完美清晰的展現。
在普通屏幕下是沒有問題的,可是在retina屏幕下就會出現位圖像素點不夠,從而致使圖片模糊的狀況。
用一張圖來表示:
如上圖:對於dpr=2的retina屏幕而言,1個位圖像素對應於4個物理像素,因爲單個位圖像素不能夠再進一步分割,因此只能就近取色,從而致使圖片模糊(注意上述的幾個顏色值)。
因此,對於圖片高清問題,比較好的方案就是兩倍圖片
(@2x)。
如:200×300(css pixel)img標籤,就須要提供400×600的圖片。
如此一來,位圖像素點個數就是原來的4
倍,在retina屏幕下,位圖像素點個數
就能夠跟物理像素點個數
造成 1 : 1
的比例,圖片天然就清晰了(這也解釋了以前留下的一個問題,爲啥視覺稿的畫布大小要×2
?)。
這裏就還有另外一個問題,若是普通屏幕下,也用了兩倍圖片
,會怎樣呢?
很明顯,在普通屏幕下,200×300(css pixel)img標籤,所對應的物理像素個數就是200×300
個,而兩倍圖片
的位圖像素個數則是200×300*4
,因此就出現一個物理像素點對應4個位圖像素點,因此它的取色也只能經過必定的算法(顯示結果就是一張只有原圖像素總數四分之一,咱們稱這個過程叫作downsampling
),肉眼看上去雖然圖片不會模糊,可是會以爲圖片缺乏一些銳利度,或者是有點色差(但仍是能夠接受的)。
用一張圖片來表示:
demo中,100×100的圖片,分別放在100×100,50×50,25×25的img容器中,在retina屏幕下的顯示效果。
條形圖
,經過放大鏡其實能夠看出邊界像素點取值的不一樣:
愛字圖
,能夠經過看文字」愛」來區分圖片模糊仍是清晰。