[TOC]
身為一個移動web網站的設計師,除非你只是針對某種特定的設備設計,否則你應該會常常碰到這樣的問題:如何清楚地了解網站運行設備的屏幕尺寸大小?這個問題一直困擾著移動設備上的設計師。
當然我們需要知道一些概念,了解就行,不至于被這樣PPPPPP~~~~弄得頭暈:
# 必須
移動端Web頁面,即常說的H5頁面、手機頁面、webview頁面等。
手機設備屏幕尺寸不一,這里總結的是針對移動端設備的頁面,設計與前端實現怎樣做能更好地適配不同屏幕寬度的移動設備。
可以看到經過幾年的迭代,iPhone現在也有了多種不同尺寸的屏幕,分辨率也不盡相同,所以對我們做移動端的頁面也有了很大的適配要求。
安卓手機屏幕更加多樣,并且現在移動端頁面設計更加的酷炫,更加多樣性,越來越與app頁面相似,所以單純的媒體查詢已經很難完成移動端頁面的適配,而且媒體查詢開發起來也較為麻煩,除非你的移動端的頁面較為簡單。
所以需要一個更加方便,更加準確兼容不同尺寸的適配方案。
# orientation(設備的方向)
**landscape是橫向,portrait是縱向。**
# 此像素非彼像素
實際上像素分為兩種:設備像素和CSS像素
## 物理像素(physical pixel)
設備屏幕的物理像素,也叫作設備像素(device pixel),任何設備的物理像素的數量都是固定的。比如iPhone 5的分辨率640 x 1136px。
一個物理像素是顯示器(手機屏幕)上最小的物理顯示單元,在操作系統的調度下,每一個設備像素都有自己的顏色值和亮度值。
## 設備獨立像素(density-independent pixel)
dip和dp是一個意思,都是Density Independent Pixels的縮寫,也叫作密度無關像素,可以認為是計算機坐標系統中的一個點,這個點代表一個可以由程序使用的**虛擬像素**(例如**CSS像素**),然后由相關系統轉換為物理像素。
### 邏輯像素,又稱為CSS像素
CSS 像素是Web編程的概念,指的是CSS樣式代碼中使用的邏輯像素。是為 web 開發者創造的,在 CSS 和 javascript 中使用的一個抽象的層。
每一個 CSS 聲明和幾乎所有的 javascript 屬性都使用CSS像素,因此實際上從來用不上物理像素 ,唯一的例外是`screen.width/height`。
~~~
//我們通過CSS和javascript代碼設置的像素都是邏輯像素
width:300px;
font-size:16px;
~~~
在CSS規范中,長度單位可以分為兩類,絕對(absolute)單位以及相對(relative)單位。px是一個相對單位,相對的是物理像素(physical pixel) 。
所以說,物理像素和設備獨立像素之間存在著一定的對應關系,這就是我們接下來要說的設備像素比。
## 設備像素比(device pixel ratio)
在早先的移動設備中,并沒有DPR的概念。隨著技術的發展,移動設備的屏幕像素密度越來越高。**從iphone4開始,蘋果公司推出了所謂的retina視網膜屏幕**。之所以叫做視網膜屏幕,是因為屏幕的PPI(屏幕像素密度)太高,人的視網膜無法分辨出屏幕上的像素點。iphone4的分辨率提高了一倍,但屏幕尺寸卻沒有變化,這意味著同樣大小的屏幕上,像素多了一倍,于是`DPR = 2`。其他品牌的移動設備也是這個道理。
設備像素比(簡稱dpr)定義了物理像素和設備獨立像素的對應關系,它的值可以通過如下公式得到:
~~~
設備像素比 (dpr)=物理像素(pp) / 設備獨立像素(dip); /*在某一方向上,x方向或者y方向*/
~~~
*在Web編程中,即:*
~~~
設備像素比(dpr)= 屏幕物理像素(dp)/ CSS像素 /*在某一方向上,x方向或者y方向*/
~~~
**該值和當前的縮放狀態有關**。(通過控制整個值,可以控制頁面的放大,快捷鍵`Ctrl +`的原理就是這個,下面會介紹)
所以通過 設備像素比,我們可以知道該設備上一個css像素代表多少個物理像素。例如,在Retina屏的iphone上,devicePixelRatio的值為2,也就是說1個css像素相當于2個物理像素。
例如iPhone4S,分辨率為:`640×960`,取屏幕寬度計算,物理像素640px,設備獨立像素320px,那么,`devicePixelRatio` 值為 `640px / 320px = 2`,又如iPhone3,計算出來的 devicePixelRatio 值為 `320px / 320px = 1`,那么iphone 3就是非retina顯示屏。
### 獲取dpr
在js中,我們可以通過`window.devicePixelRatio`獲取當前設備的`dpr`。
在css中,可以通過`-webkit-device-pixel-ratio`,`-webkit-min-device-pixel-ratio`和`-webkit-max-device-pixel-ratio`進行媒體查詢,對不同dpr的設備,做一些樣式適配,這里我們只針對 webkit 內核的瀏覽器和 webview。
>查看更多設備像素比:
http://screensiz.es/
http://devicepixelratio.com/
### 縮放 (設備像素比的體現)
在桌面端,css的1個像素往往都是對應著電腦屏幕的1個物理像素。
一個CSS像素完全覆蓋了一個設備像素:

而在手機端,由于屏幕尺寸的限制,縮放是經常性的操作。
設備物理像素(深藍色背景)、CSS像素(半透明背景)
當用戶進行縮小操作時,一個設備像素覆蓋了多個CSS像素:

當用戶進行放大操作時,一個CSS像素覆蓋了多個物理像素:

不論我們進行縮小或放大操作,元素設置的CSS像素(如width:300px)是始終不變的,而一個CSS像素對應多少個設備像素是根據當前的縮放比例(devicePixelRatio)來決定的。
(<span style="color:red;font-weight:700">Xee:</span>用鼠標放大瀏覽器,測試window.devicePixelRatio,為什么有變化?有變化才正常啊!,記住取值時,我們四舍五入,可能就像上面說的一樣)
# 屏幕三要素
個人總結的:包括屏幕尺寸、屏幕分辨率和屏幕像素密度。
## 屏幕尺寸(screen size)
我們常常聽說5.5英寸大屏幕手機,實際上屏幕尺寸是指屏幕的對角線長度,一般講的大小單位都是英寸。
比如iPhone5S的屏幕尺寸是4英寸。Samsung Note3是5.7英寸。
對于英寸沒有什么概念,可以通過轉換公式轉換成常用的厘米
~~~
1英寸 = 2.54厘米
3.5in = 3.5*2.54cm = 8.89cm
4.0in = 4.0*2.54cm = 10.16cm
4.3in = 4.3*2.54cm = 10.922cm
4.8in = 4.8*2.54cm = 12.192cm
~~~

## 屏幕分辨率
在講解分辨率之前,我們要明白一個概念。在我們手機上呈現的一條線,一個面,一張圖像都是由最小的單位像素來表示的,你也可以簡單理解為是由一個個小方塊組成的。看看下面這張圖你就明白了。

屏幕分辨率是指屏幕的像素點數,一般以 `縱向像素×橫向像素` 來表示分辨率。顯示常用分辨率有如800×600、1024×768、1280×720、1600×900、1920×1080,單位是px。
通常,“分辨率”被表示成每一個方向上的像素數量,比如640×480等。某些情況下也可以同時表示成“每英寸像素”(ppi)以及圖形的長度和寬度。比如72ppi,和8×6英寸。
若存在retina視網膜屏幕,要注意的是**屏幕分辨率指的是物理像素,而不是理想視口**。
分辨率越高代表系統的運行壓力就越大,需要平衡一下。
## 屏幕像素密度 PPI(Pixels Per Inch)
過去 iPhone 3GS 的時候,和平時電腦屏幕一樣,在縮放比為100%的情況下,`1px` CSS像素對應著1px物理像素。
開發者在開發網頁的時候只需要寫上CSS像素 `width:320px,height:480px`。但是同樣都是3.5英寸的屏幕尺寸的iPhone 3GS的屏幕和iPhone 4/4s,分辨率提升到了`640x960`,比3GS的分辨率大了一倍。**在相同的屏幕尺寸下塞入更多的像素點,這需要引入另一個重要的概念:屏幕像素密度**
計算機顯示設備從打印機中借鑒了DPI的概念,由于計算機顯示設備中的原子單位不是墨汁點而是像素,所以就創造了 PPI(Pixels Per Inch),這個值是**屏幕每英寸的像素數量,即像素密度(Screen density)**。
這個每英寸跟之前手機屏幕的尺寸一樣,也是對角線的長度。所以,可以這么理解屏幕像素密度,即**在一個對角線長度為1英寸的正方形內所擁有的像素數**。
由于各種原因,目前**PPI**(主要是iOS)和**DPI**(比如在Android中)都會用在計算機顯示設備的參數描述中,不過二者的意思是一樣的,都是代表屏幕像素密度。

Google Android官方指定按照下列標準區分不同設備的dpi

蘋果的區分則更為簡單:非高清屏、高清屏、超高清屏


從數值上看,蘋果和安卓有這樣的對應關系:

### ppi 和 dpi 經常都會出現混用現象
從技術角度說,“像素”(P)只存在于計算機顯示領域,而“點”(d)只出現于打印或印刷領域。
分辨率和圖像的像素有直接關系。我們來算一算,一張分辨率為640 x 480的圖片,那它的分辨率就達到了307200像素,也就是我們常說的30萬像素,而一張分辨率為1600 x 1200的圖片,它的像素就是200萬。
**當DPI的概念用在計算機屏幕上時,就應稱之為PPI(Pixels Per Inch)。**
同理: PPI就是計算機屏幕上每英寸可以顯示的像素點的數量。你說 DPI大伙也能理解。
Windows系統默認PPI 為96, Mac OS系統默認PPI 為72。

PPI 計算公式:

(這里注意:顯示屏不是模擬設備,是數字設備,因此不可能出現半個像素點的情況,肯定是px換算為dip產生的誤差,**因此應該四舍五入取值**。<span style="color:red;font-weight:700">Xee:</span>:好像是這個道理。)
公式中的**屏幕尺寸**指顯示屏對角線的尺寸,一般用英寸來表示。
可測量顯示器對角線長度轉換為英寸即可!`1英寸=2.54厘米`。

一個顯示屏的**PPI**越高,說明在同一大小的屏幕上能顯示更多物理像素,能給圖像提供更多細節。
如小米3的高清顯示屏,5英尺的屏幕下**分辨率(resolution)**高達1920*1080:

現在我們來根據公式計算一下,上圖中的`$ PPI = 441 $`:
`$ \frac{\sqrt{1920^2 + 1080^2}}{5} = 440.5814341809 \approx 441 $`
---------
# 常見現象
## retina下圖片的展示情況
一個位圖像素是柵格圖像(如: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 ),肉眼看上去雖然圖片不會模糊,但是會覺得圖片缺少一些銳利度,或者是有點色差(但還是可以接受的)。
用一張圖片來表示:

## 為什么元素變得非常小

(縮小時,一個設備像素覆蓋了多個CSS像素)
作為Web開發者我們整天在CSS里用`px`作為長度單位。這里的`px`指的是**CSS像素**,瀏覽器里的一切長度都是以CSS像素為單位的。**在非高清屏幕以及未縮放瀏覽器的情況下,一個CSS像素等于一個物理像素**;而在搭載了蘋果公司的視網膜顯示屏等高清屏幕(PPI特別高,一個屏幕上的物理像素點非常多)的設備上,如果一個CSS像素仍等于一個物理像素,那么網頁上的各種元素就變得非常小,用戶很難看清,因此高PPI的設備中,一個CSS像素通常等于兩個甚至三個物理像素(瀏覽器自動設定,不同瀏覽器設定的會不一樣)。
**簡單整理下高清顯示屏原理如下:**
1、一種具備超高像素密度的液晶屏
2、同樣大小的屏幕上顯示的像素點由1個變為多個
**所謂的一倍屏、二倍屏(Retina)、三倍屏,指的是設備以多少物理像素來顯示一個 CSS 像素,也就是說,多倍屏以更多更精細的物理像素點來顯示一個 CSS 像素點,在普通屏幕下 1 個CSS像素對應 1 個物理像素,而在 Retina 屏幕下,1個CSS像素對應的卻是4個物理像素。**
**********
# 附錄
## Retina顯示屏

看上圖,是可以區分普通顯示屏和高清顯示屏(起源于retina),當devicePixelRatio值等于1時(也就是最小值),那么它是普通顯示屏,iphone 3就是非retina顯示屏,當devicePixelRatio值大于1(通常是1.5、2.0),那么它就是高清顯示屏。
其中,**PPI在120-160之間的手機被歸為低密度手機,160-240被歸為中密度,240-320被歸為高密度,320以上被歸為超高密度**(Apple給了它一個上流的名字——retina)。


*Non-Retina_Display(非retina顯示屏)*
**Retina顯示屏**,它是一種由蘋果公司設計和委托制造的顯示屏,具備足夠高像素密度而使得人體肉眼無法分辨其中單獨像素點的液晶屏。
retina顯示屏,就是高清顯示屏的一種!現在的手機基本上都是高清顯示屏了!
## PPI和DPI
**PPI和DPI都可以是指像素密度、屏幕(像素)密度。**
**PPI**(Pixel Per Inch)是圖像分辨率所使用的單位,意思是:在圖像中每英寸所擁有的像素數目。從輸出設備(如打印機)的角度來說,圖像的分辨率越高,所打印出來的圖像也就越細致與精密。

同樣的分辨率,屏幕越大,像素點之間的距離越大,屏幕就越粗糙。所以大屏幕也不一定能帶來良好的視覺感受。
實踐證明,ppi低于240的讓人的視覺可以察覺明顯顆粒感。行動電話顯示器的像素密度達到或高于300ppi就不會再出現顆粒感;手持平板類電器顯示器的像素密度達到或高于260ppi就不會再出現顆粒感,而蘋果電腦的Retina顯示器像素密度只要超過200ppi就無法區分出單獨的像素。比如iPhone4,3.5寸960×640,330ppi,屏幕的清晰程度其實是分辨率和尺寸大小共同決定,用ppi指數衡量屏幕清晰程度更加準確。
**DPI**(Dots Per Inch)最初用于衡量打印物上每英寸的點數密度,就是說你的打印機可以在一英寸內打多少個點,即打印機每英寸可以噴的墨汁點數。
DPI值越小圖片越不精細。
### ppi是每英寸像素,dpi是每英寸點。
科學的含義,ppi通常是衡量掃描儀、數碼相機的參數,既每英寸的像素數。而dpi是衡量打印機的指標,既每英寸的點數。在實際應用中,經常有人會搞混這兩個指標,其中甚至不乏專業的媒體。另外,這2個指標如果按不同的角度看,很多情況下可以是通用的。比如,同一個圖片,如果我認為它是掃描或者拍攝的照片,那么分辨率是ppi,但如果我認為這個是將要打印的圖片,那么分辨率可以是dpi。
因此,我們可以姑且將ppi等同于dpi(真實的區別是ppi是實際采樣到的像素,這個真實很重要,它表示的就是數碼相機、掃描儀真實采樣出來的結果。而dpi是需要打印或者輸出的分辨率,這個分辨率可能是在真實采樣結果的基礎上差值增加了像素的,也有可能是縮小了像素數的)。
## dip/dp(設備獨立像素)
dip和dp是一個意思,都是Density Independent Pixels的縮寫,即密度無關像素,上面我們說過,dpi是屏幕像素密度,假如一英寸里面有160個像素,這個屏幕的像素密度就是160dpi,那么在這種情況下,dp和px如何換算呢?**在Android中,規定以160dpi為基準,1dip=1px,如果密度是320dpi,則1dip=2px,以此類推。**
通過px來定義不同設備的元素大小是不靠譜的,于是安卓和蘋果分別定義了dp和pt這兩個概念。
dp到屏幕(物理)像素的**轉換公式**:Physical Pixels = dip * (ppi / 160)。
iphone 6,PPI就是326,所以取值,四舍五入為2。
舉例來說, 在 240 dpi 的屏幕上, 1dp 等于 1.5**物理(屏幕)像素**。
1. dip或dp,(device-independent pixels,device pixels,設備無關像素),android開發單位,虛擬像素單位, 用于定義應用的UI, 以密度無關的方式表達布局尺寸或位置。
2. 1dip等價于160dpi屏幕下的一個物理像素點,dp是絕對單位,當指定一個元素為30dp后,不管在多大的屏幕中,元素的大小都是固定的30dip,也可以說:3/16(十六分之三)英寸。
3. 在運行時, android根據使用中的屏幕的實際密度, 透明地處理任何所需dp單位的縮放。
應用場景是開發人員計算渲染像素的:
若套用此套轉換公式,開發人員寫一個高度為48dip的控件:
在小米2S上的渲染像素為:48* 320/160 = 96px
在Sony Z2上的渲染像素為:48* 480/160 = 144px
在華為 Mate 7上的渲染像素為:48* 480/160 = 144px
>參考:[Android設備上的dp](https://www.zhihu.com/question/20697111)
### 相關關系
dp和css px是幾乎完全對應的。傳統上我們把css px叫做相對單位,這確實有點令人困惑,所以現在css規范也改了說法。在現代css中px被定義為96px = 1in,也就和in/pt/mm一樣成了絕對單位,但是css規范要求對于非典型視距設備要根據參考像素進行錨定,而手機相對電腦屏幕來說就是非典型視距,因此所有現代手機瀏覽器里都設為160px = 1in,或者對于Android來說就是1px = 1dp。不過dp和css px只是通過轉換來達到160dp = 1in,而真實設備被歸類為ldpi/mdpi/hdpi/xhdpi...只是依據最接近的dpi密度,不太可能是正好120/160/240/320,因此真實設備上160dp與物理長度1in肯定是有偏差的。
(同理,現在的css規范中的1in因為已經跟px綁定,所以在幾乎所有設備上也無法確保真的是物理長度1in,而只是接近而已。并且會隨著縮放而縮放。)
## 其它概念:
描述分辨率的單位有:dpi(點每英寸)、lpi(線每英寸)和ppi(像素 每英寸)。從技術角度說,“像素”只存在于電腦、手機顯示領域,而“點”只出現于打印或印刷領域。對于web開發者,我們需要清楚ppi( pixel per inch)
sp:與縮放無關的抽象像素(Scale-independent Pixel)。sp和dp很類似但唯一的區別是,Android系統允許用戶自定義文字尺寸大小(小、正常、大、超大等等),當文字尺寸是“正常”時1sp=1dp=0.00625英寸,而當文字尺寸是“大”或“超大”時,1sp>1dp=0.00625英寸。類似我們在windows里調整字體尺寸以后的效果——窗口大小不變,只有文字大小改變。
pt:point,來源于印刷業,IOS開發單位,絕對長度,是一個標準的長度單位,`1pt=1/72`英寸,px=`pt*ppi/72`,道理和dp一樣。
## HD和4K
現在移動設備、智能電視宣傳最多的兩個關鍵詞估計就是HD、4K,這二者都是用來描述顯示設備分辨率的標準,到底二者之間有什么區別?
HD:沒有固定的標準,基本上只要寬度為720px的都算是HD
full HD(全高清): 1920×1080分辨率
4K: 4k也叫QHD或UHD(超高清),最小分辨率是3840×2160,主要是現在高端電視的分辨率;其還有一個更高的4096×2160的標準,主要用于電影放映機或者專業相機。

## 關于相機像素
我們常常聽過相機支持1000萬像素。相機所說的像素,其實是最大像素的意思,像素是分辨率的單位,這個像素值僅僅是相機所支持的有效最大分辨率。
~~~
640*480 = 307200 = 30萬像素
1600*1200 = 1920000 = 200萬像素
3264*2488 = 8120832 = 800萬像素
4536*3024 = 13716864 = 1400萬像素
~~~
## 放棄的target-densitydpi
是這樣的,在安卓中WebKit內核默認按照160的DPI/ppi來排版。假如設備真實DPI是480,寬度是1080,在WebKit會按160DPI,360寬度來排版。排版結束后在放大到1080寬。
target-densitydpi=device-dpi可以強制內核以480DPI排版,使畫面更精細,window.innerwidth也將為屏幕寬度1080.
**但WebKit從去年開始取消了對target-densitydpi的支持。**
想實現target-densitydpi=device-dpi的效果有什么方法?提交此次補丁的WebKit開發者說可以用responsive images 和 CSS device units來替代。
> [target-densitydpi](http://www.cnblogs.com/Limo-Pond/p/5291402.html)
# 參考
> [PM關于設計那些事兒(一)](http://mp.weixin.qq.com/s?__biz=MzI5NDQxMjE5Mg==&mid=2247483670&idx=1&sn=b7da0134d88c06c6526b6cd4b9b89543&scene=4#wechat_redirect)
[dpi 、 dip 、分辨率、屏幕尺寸、px、density 關系以及換算](http://www.cnblogs.com/yaozhongxiao/archive/2014/07/14/3842908.html)
- 前言
- 中文字體
- 移動Web適配方案
- !移動Web基礎!
- 詳解適配相關概念
- 移動開發之設計稿
- 移動適配方案(一)
- 移動適配方案(二)
- vw+rem 實現移動端布局
- 移動端適配之雪碧圖(sprite)背景圖片定位
- 適配 iPhoneX
- 前端開發實戰
- 打造自己的前端開發流程(Gulp)
- flexible.js案例講解
- viewport 與 flexible.js解讀
- 圖片與字體
- 踩過的坑
- 瀏覽器默認樣式
- 300ms點擊延遲和點擊穿透
- ios css
- CSS 常見問題
- Ionic v1混合開發
- Native App、Web App 、Hybrid App?
- ionic項目結構
- 混淆加密
- 解決問題
- cordova
- 環境配置
- 打包發布
- 問題
- 移動前端開發優化
- Web開發之抓包
- ===web移動開發資源===
- H5組件框架
- 調試集合
- 簡單h5調試
- whistle
- devtools-pro