1、引言html
1px 到底是多大?這應該是一道很不錯的面試題。且看:html5
一、iphone6s 的分辨率是1920px * 1080px面試
二、iphone6s 全屏截圖文件的尺寸是1242px * 2208px瀏覽器
三、iphone6s 的寬度是414pxiphone
四、iphone6s 不加 viewport 的狀況下,window.innerWidth = 980pxflex
五、iphone6s 加 viewport 且 scale 都爲1的狀況下,window.innerWidth = 414pxspa
六、iphone6s 加 viewport 且 scale 都爲.5的狀況下,window.innerWidth = 829px設計
這些 px 單位都是啥?代理
2、幾個關鍵概念orm
設備像素:設備的物理像素,其尺寸大小是絕對的
邏輯像素:CSS 的像素單位,其尺寸大小是相對的,也稱爲獨立像素
分辨率:屏長的設備像素 × 屏寬的設備像素
dpi(dots per inch):像素密度,表示水平或垂直方向每英寸長度的像素數目
ppi(pixels per inch):像素密度,表示沿對角線每英寸長度的像素數目
(dpi 和 ppi 其實不就是一回事嗎,呵呵)
縮放因子(Scale Factor):邏輯像素相對於設備像素的放大比例,可經過 window.devicePixelRatio 得到,但兩者並不徹底等同
關係一:
設備尺寸 × 像素密度 = 分辨率(設備像素)
舉例:
iphone6s 對角線長度爲5.5 inches,像素密度401 ppi,分辨率 1920 * 1080,計算可得對角線的設備像素爲2205.5。
5.5 * 401 = 2205.5
關係二:
邏輯像素 = 設備像素 × 縮放因子
舉例:
iphone6邏輯像素爲375 * 667,分辨率爲750 * 1334,縮放因子爲2
1個邏輯像素 = 設備寬度的1/375
1個設備像素 = 設備寬度的1/750
1/375 = 1/750 * 2
3、糾結的縮放
設備像素都是固定的,因此邏輯像素大小由縮放因子決定,那麼縮放因子由什麼決定?到底放多大才合適?
對於桌面設備,邏輯像素一般就等同於物理像素,原本是不用考慮縮放問題的。一切問題的根源就在於:屏幕變得愈來愈高清,ppi 愈來愈大。好比我如今用的 PC 是1920px的高清屏,若是沒有縮放,全部的東西看起來都會比較小,所以須要放大:
因此決定縮放因子大小的,就是像素密度,密度越大、越高清的屏幕,須要的縮放比例就越大。
PC 上的縮放比例是自定義的。那麼移動端的縮放比例是怎麼肯定的呢?
答案是 viewport。
viewport 就是屏幕那塊兒固定的可視區面積。默認狀況下,移動端瀏覽器會將 viewport 寬度設爲980px(也有多是1024px 或其它值),也就是說1px = 設備屏幕寬度的1/980。這跟縮放因子沒有任何關係。
這時的1px 很是小,全部的元素都變得很是小,移動端瀏覽器之因此這麼作,是爲了儘量完整的顯示 PC 端的網頁,而後容許用戶經過縮放來查看細節。
若是咱們不但願採用默認的設置,就須要人工設置 viewport:
<meta name="viewport" content="width=device-width">
將 viewport 寬度設爲設備寬度,那麼這裏的設備寬度究竟是什麼呢?這就跟縮放因子有關係了。iphone4 ~ iphone6的 ppi 都是326,縮放因子都是2,因此1個邏輯像素的大小等於2個設備像素。
設備 |
設備分辨率 |
縮放因子 |
邏輯分辨率 |
ppi |
4s |
640 * 960 |
2 |
320 * 480 |
326 |
5s |
640 * 1136 |
2 |
320 * 568 |
326 |
6 |
750 * 1334 |
2 |
375 * 667 |
326 |
對於 iphone6,1px = 屏幕寬度的1/375,相比1/980放大了很多,而這時候的1px 就是一個比較理想的大小,即比較符合咱們在 PC 端使用 px 時的感覺。也就是說326的 ppi對應的放大比例是2,326 : 2是一個經驗比率(1px = 1/163inch),實踐檢驗比較妥,蘋果就這麼幹的,因此就這麼定了。因此若是是652的 ppi,則理想的放大比例爲4。
實際上在 CSS2.1 中有這麼一條:若是顯示設備的像素密度與典型的電腦顯示器差別明顯,用戶代理應當從新調整像素值。建議以閱讀者在一臂距離處觀察到的像素密度爲96 dpi 的設備上的一個設備像素做爲參考像素,大約爲1/96 inch,0.26mm。
可是這條建議實在是跟不上屏幕進化的速度,因此在 PC 端都沒有獲得執行,更況且移動端。你能夠在 PC 上畫一個100px 的正方形,按照上述標準,這個100px 的正方形應該和一個一元硬幣(直徑25mm)差很少大小。你比較一下,若是正方形比硬幣大,就說明你的屏幕 ppi 有些低。(分辨率調得過低或者是放大比例調得過高除外)。
我算了下,我電腦上一個邏輯像素大約爲1/113 inch,那麼移動端將1/163 inch 做爲邏輯像素的參考大小,就說明我電腦上一個16px 的字,在手機上會縮小到大約三分之二,這是符合個人使用經驗的。
4、iphone6 plus
iphone6s的 ppi 達到了401,按照比率,它的縮放因子應該等於2.6。
設備 |
設備分辨率 |
縮放因子 |
邏輯分辨率 |
ppi |
6s |
1080* 1920 |
3 |
414 * 736 |
401 |
可是2.6這一奇葩的比例不太方便切圖,因此 iphone6s 就直接改爲了3,而後再總體壓縮87%(2.6 / 3)。這也是爲啥iphone6s 全屏截圖的尺寸是1242 * 2208。
5、三種場景
一、ppi 適配
ppi 適配要解決的問題是:在最小基本單位尺寸不固定的狀況下,如何找到一個固定大小的尺寸單位。
對於文字,咱們但願16px 的文字不管在什麼樣的屏幕下看起來都是同樣大的。也就是說咱們但願這裏的 px 是一個實際物理尺寸固定的單位。
設置 viewport 就能夠實現這個目的:
<meta name="viewport" content="width=device-width">
1個邏輯像素的尺寸 = 1 / ppi * 縮放因子 = 1/163 inch
因此說設置 viewport 本質上是把 px 變成了一個「絕對單位」。
那麼用 cm 或 mm 做爲尺寸單位行不行呢?我認爲是符合此場景的,只不過有些反人類。
二、resolution 適配
分辨率適配要解決的問題是:找到一個相對單位,使得同一尺寸在不一樣大小的屏幕上看上去相對大小一致。
好比一張寬100%,高100unit 的 banner 圖,咱們但願它在任何大小的屏幕上可以等比例縮放,所以咱們須要這裏的 unit 是一個相對單位。
vw 和 vh 就是很好的相對單位,但考慮到兼容性,只有用 js 實現一個 vw,具體可參見文末連接。
三、dpr 適配
devicePixelRatio 適配要解決的問題是:在設置了 viewport,width=device-width 的狀況下,如何畫出1px(設備像素)的問題。
dpr=2意味着 CSS 中的1px 會用兩個設備像素來渲染,在 iphone6s 上更會用3個設備像素來渲染。
解決的方案大體有:用小數、用圖片、用漸變、用陰影、用 transform 縮放。手機淘寶的作法是使用 js 動態設置 viewport 的 initial-scale。
設備 |
1px大小 |
devicePixelRatio |
縮放因子 |
邏輯分辨率 |
initial-scale |
iphone6s
|
3個設備像素 1/414屏寬 |
3 |
3 |
414 * 736 |
1 |
1.5個設備像素 1/828屏寬 |
3 |
1.5 |
828 * 1472 |
.5 |
|
6個設備像素 1/207屏寬 |
3 |
6 |
207 * 368 |
2 |
以上三類問題能夠總結爲:絕對單位問題、相對單位問題、最小單位問題。
參考:
《手機淘寶的 flexible 設計與實現》
http://www.html-js.com/article/2402
《7種方法解決移動端 Retina 屏幕1px 邊框問題》
http://www.jianshu.com/p/7e63f5a32636
《使用 flexible 實現手淘 H5 多終端適配》
http://www.w3cplus.com/mobile/lib-flexible-for-html5-layout.html