本文所說devicePixelRatio
其實指的是window.devicePixelRatio
, 被所有WebKit瀏覽器以及Opera所支持,隨着顯示器的發展,這個屬性也慢慢登上了前端技術的舞台。
本文內容大部分屬於翻譯性質內容,因此,會不那么通俗易懂。不過,你是做手機開發的,或是有意向的,本文的內容如果細細讀來,還是有些收獲的。
一、定義
定義如下:
window.devicePixelRatio是設備上物理像素和設備獨立像素(device-independent pixels (dips))的比例。
公式表示就是:window.devicePixelRatio = 物理像素 / dips
dip或dp,(device independent pixels,設備獨立像素)與屏幕密度有關。dip可以用來輔助區分視網膜設備還是非視網膜設備。
所有非視網膜屏幕的iphone在垂直的時候,寬度為320物理像素。當你使用<meta name="viewport" content="width=device-width">
的時候,會設置視窗布局寬度(不同於視覺區域寬度,不放大顯示情況下,兩者大小一致,見下圖)為320px, 於是,頁面很自然地覆蓋在屏幕上。
這樣,非視網膜屏幕的iphone上,屏幕物理像素320像素,獨立像素也是320像素,因此,window.devicePixelRatio
等於1
.
而對於視網膜屏幕的iphone,如iphone4s, 縱向顯示的時候,屏幕物理像素640像素。同樣,當用戶設置<meta name="viewport" content="width=device-width">
的時候,其視區寬度並不是640像素,而是320像素,這是為了有更好的閱讀體驗 – 更合適的文字大小。
這樣,在視網膜屏幕的iphone上,屏幕物理像素640像素,獨立像素還是320像素,因此,window.devicePixelRatio
等於2
.
二、瀏覽器支持
- IE以及FireFox壓根不支持。可能接下來的版本會支持。
- Opera桌面瀏覽器時,即使是視網膜設備,返回的值也是1而不是2. 不過,這個bug在后續的版本中會修復的。
- Opera Mobile 10不支持,不過Opera Mobile 12正確支持。
- UC總是顯示1,不過其viewport屬性有些讓人費解。
- 只有最近的Chrome瀏覽器才能正確實現該屬性。Chrome19返回不准確的1, Chrome22可以正確返回2.
- MeeGo WebKit (Nokia N9/N950)就嚇人了:當你應用了meta viewport時候(類似
<meta name="viewport" content="width=device-width">
),值會從1變成1.5!
真是喜憂參半。好的是Safari, Android WebKit, Chrome 22+(Android), Opera Mobile, BlackBerry WebKit, QQ, Palm WebKit, 及Dolfin都能正確實現該屬性。
當然,大部分這些瀏覽器仍然運行在devicePixelRatio
值應該為1
的系統上,當它們移動到視網膜類似設備時候,可能就會遇到問題。
兩個注意事項:
MeeGo WebKit meta viewport
應用時改變值的做法是大錯特錯的。設備像素比應該是不變的,不僅物理像素值,設備獨立像素也是如此。
二是,一些瀏覽器習慣在meta viewport
應用時改變各種東西(三星的Dolfin就是代表),這完全就是在瞎搞。唯一的變化應該是布局視圖的尺寸。如果瀏覽器變了其他什么都是,那都是很挫的。
實際測試
您可以狠狠地點擊這里:window.devicePixelRatio值支持與否測試demo
例如,我現在的FireFox桌面版(14.0.1)彈出的就是undefined
, 如下圖:
Chrome下是認識這個屬性的,在我機子上彈出的是1
, 如下圖:
其他一些系統、設備
1. iOS
類似的,無視網膜設備devicePixelRatio
值為1
,視網膜設備為2
. 因為實際的像素個數是雙倍。不過,iphone似乎不願意改變大家都熟知習慣的320像素寬度布局,沒有把設備寬度一下子變成640像素,因此,dips寬度依然是320, 於是devicePixelRatio
就是640/320 = 2
.
iOS上的情況要相對簡單些,除了1
就是2
. 在其他平台也基本上很簡單,因為一般分辨率都比較挫,devicePixelRatio
都是1
.
2. Android
據我所知,谷歌的Nexus One是第一個使用dips的,比iphone還早。同時Galaxy Nexus以及Galaxy Note都是類運動視網膜顯示器。近距離探究這三個設備應該會有所收獲。
Nexus One分辨率是480*800, 為了最優的頁面瀏覽,Android WebKit團隊決定縱向手持時候的寬度依然是320像素,因此,devicePixelRatio
值為480/320 = 1.5
.
在同一手機上,Opera Mobile有相同的結論,dips為320寬,devicePixelRatio
也是1.5
.
順便提一下,BlackBerry Torch 9810(OS7)物理像素同樣480像素,BlackBerry WebKit團隊決定堅持devicePixelRatio
為1
. 這可能是更不錯的做法,在Torch顯示器上480px寬度站點或多或少有些難以閱讀。
Galaxy Nexus有像素的提升,為720×1200. Android團隊決定提高dips層的寬度到360像素。從而使devicePixelRatio
為720/360 = 2
. Chrome團隊決定跟進,就如騰訊QQ瀏覽器所做的那樣。
然而,Opera,堅持自我,dips寬度為320px, 於是devicePixelRatio
為720/320 = 2.25
. 不過似乎還與zoom縮放層級有關。
Galaxy Note物理像素為800×1200. 這里所有瀏覽器都決定使用與Galaxy Nexus一樣的比率:Android WebKit, Chrome, 以及QQ都是2
,也就意味着其dips寬度為400px. 然而,Opera依然一意孤行2.25
, 於是其dips寬度值有些怪怪的: 356px.
Android標准似乎不嚴格,於是自家人玩自家人的游戲,對於開發者而言,可能又會面臨苦逼~~
3. 視網膜MacBook
新的MacBook采用視網膜顯示屏,其devicePixelRatio
是(如果不出意外)2
. 視網膜MacBook的物理像素是2800×1800,而顯示出分辨率為1400×900,如果把分辨率作為dips層,則devicePixelRatio
為2
應該是無誤的。
需要指出的是,如果你把分辨率改成1920×1200,devicePixelRatio
依然是2
. 嚴格來講,這是不准確的,應該是1.5
, 然而你也可以說MacBook的分辨率不同於dips層,這種情況下devicePixelRatio
在台式機/筆記本下的定義就不一樣(哪一個?不知道。)。
在任何情況下,根據蘋果的規范做法,devicePixelRatio
值只可能是1
或者2
. 如果你看到2
,你要提供視網膜優化顯示圖片,如果是1
,使用正常的圖片——(這里內容其實屬於視網膜站點的開發內容)。
四、其他相關屬性
當頁面設置了<meta name="viewport" content="width=device-width">
時候,document.documentElement.clientWidth
在大部分瀏覽器下,得到的是布局視區的寬度,等同於dips的寬度。
對於screen.width
的值:
- 在iOS視網膜設備上,
screen.width
返回dips寬。因此,在豎着顯示的時候,視網膜顯示屏的ipad和非視網膜顯示屏的ipad返回的都是768. - 在上面提到的三個Android設備上,
screen.width
返回的是物理像素寬度,分別480, 720, 和800. 該設備上的所有瀏覽器都是該值。
Vasilis有一個很好的理論:蘋果像素,因為它想使顯示更清晰,更流暢,而Android廠商增加的像素在屏幕上塞進更多的東西。它解釋了為什么蘋果強調非視網膜視網膜的連續性,而Android集中在原始像素數。
Nokia Lumia Windows Phone上的IE9 screen.width
的值與Android設備一樣,返回的是物理像素。而且其不支持devicePixelRatio
. 因此,我們無法從中看出其對待像素的態度是如何的。
小小結論
devicePixelRatio
在大多數瀏覽器是值得信賴的。- 在iOS設備,
screen.width
乘以devicePixelRatio
得到的是物理像素值。 - 在Android以及Windows Phone設備,
screen.width
除以devicePixelRatio
得到的是設備獨立像素(dips)值。
注:本文的DIPs切勿和DPI搞混了!DPI指每英寸點的個數,本文的DIPs指設備獨立像素。
參考文章:
devicePixelRatio
More about devicePixelRatio
原創文章,轉載請注明來自張鑫旭-鑫空間-鑫生活[http://www.zhangxinxu.com]
本文地址:http://www.zhangxinxu.com/wordpress/?p=2568