首先了解下什麼是CSS pixels/ 'pɪks(ə)l; -sel /,什麼是device pixels;css
1. CSS pixels能夠理解爲css像素,是瀏覽器使用的抽象單位,主要用來在網頁上繪製內容。也能夠說css px是專門爲web開發者提出的一個抽象概念,也只跟咱們平時寫的css樣式有關,與分辨率(好比720px*1280px)裏的px不要緊。html
2. device pixels能夠理解爲是設備像素,官方的解釋是:顯示屏幕的最小物理單位,每一個dp包含本身的顏色、高寬等。web
對於咱們作web開發的人來講,咱們用到的最多的地方是「css像素」,即相似width:300px;font-size:14px;這類的css語句裏用到的。它跟設備自身的px是不要緊的。也就是說1個CSS 像素佔多少個物理像素是不肯定的,這個問題經過頁面的放縮比較容易理解。好比一個普通的html頁面上,有一個300px的元素;若是咱們放大頁面,元素會佔據更多的設備像素(即device pixels),但它的CSS pixels不變,依然是300px;縮小頁面也是一樣的道理,佔據了更少的device pixels,但它的CSS pixels不變。也就是說,元素佔據了多少device pixels,是由當前頁面的放縮比例而定的。瀏覽器
不過,頁面的縮放對咱們web開發來講是好像沒有任何意義的。但有一個問題,咱們開發出來的頁面是想要在各個屏幕個以最佳的樣式展現出來的,咱們不能讓頁面裏存在不能控制的元素。因此就出現了它:<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0" /> 也就是咱們在進行web開發的時候常常用到的viewport。那麼viewport究竟是個什麼玩意兒呢,並且content裏面width爲何要等於device-width呢,device-width又是個什麼概念呢?下面咱們來看看它們哥倆兒是什麼。app
在解釋這兩個概念以前,先說一個你們都知道,但不明白爲何的狀況:把一個普通的在PC上開發的HTML頁面直接放手機上,你會發現無論多大的頁面均可以在小小的手機屏幕上顯示,可是圖文都會顯示的特別小;若是你用JAVASCRIPT獲取下頁面寬度,你會發現,大多數的頁面寬度都是980px的,這個就跟viewport有關。webapp
Viewport起源於蘋果,但如今已經被大多數瀏覽器支持。關於viewport有兩個概念visual viewport跟layout viewport。這裏visual viewport也就是視覺上的窗口,能夠理解爲設備本身的寬度。這時,若是你有一個長960的頁面,有一個元素是20%(實際解析出來就是192px)。但若是我用寬爲320px的屏幕打開呢,這個元素就成了64px,可是這個時候我設置的字體大小是12px,在320px的屏幕上就只能顯示64/12個字了~iphone
鑑於這個問題,蘋果找到一種解決方法,在移動版的safari中定義了viewport meta標籤,它的做用就是建立一個虛擬的窗口(viewport),這個虛擬的窗口就是layout viewport分辨率接近桌面顯示器,apple將其定位爲980px。在手機上,能夠經過document.documentElement.clientWidth來獲取。佈局
其餘瀏覽器廠商也有不一樣的解決辦法,例如UCweb是使用的中間技術。post
另外聽說,不一樣瀏覽器廠商對於layout viewport的大小都有本身的定義。可是,我用手上很少的幾個手機(小米2s、SONY、金立、ipad)測試的結果,都是980px。其中在小米2s上測試了小米自帶瀏覽器、QQ瀏覽器、UC瀏覽器、谷歌瀏覽器,還有opera瀏覽器,結果都同樣;其餘的手機上面無論裝了什麼瀏覽器,都測試了,結果都是980px。可是這個值對於咱們web開發來講,好像也沒有什麼用處。測試
由於大多數狀況下,<meta name="viewport" content="width=device-width" /> 這個標籤對咱們來講是最給力的,可讓咱們的頁面裏的圖文顯示的是正常的,很大程度上提升了頁面的可讀性。而這一meta標籤的功能就是設置layout viewport爲device-width的寬度。可是device-width具體是什麼呢?
第一代iphone的時候,分辨率爲320*480,屏幕尺寸爲3.5寸(注意,這個3.5寸說的是屏幕的對角線寬),這時候device-width就是320px,也是手機的分辨率寬,此時device-width就是設備寬。但第二代的iphone分辨率提升爲了480*960,屏幕尺寸爲依然爲3.5寸,若是device-width仍是設備寬,那麼一樣是320px的頁面放480*960的手機屏上,圖文就會變得比較小,又會影響其可讀性。所以iphone的device-width一直維持在320px,ipad一直維持在1024px。這個時候,device-width就不是設備寬了(也就不是分辨率的寬了),是一箇中間層。Android採用的也是這一律念,其device-width值以360居多,但也不乏有像540px和600px這樣的奇葩。在設置了<meta />標籤之後,device-width值能夠用window.innerWidth來獲取device-width值。
dpi(Dots Per Inch),有時也叫作ppi(Point Per Inch),翻譯過來也叫像素密度,表示設備每英寸所佔有的像素數;數值越高,即表明顯示屏可以以越高的密度顯示圖像。(注:這裏的像素,指的是device pixels。)DPI的計算公式:
有意思的是,這個值比蘋果官網上公佈的326還有高一點點。
其中,PPI在120-160之間的手機被歸爲低密度手機,160-240被歸爲中密度,240-320被歸爲高密度,320以上被歸爲超高密度(Apple給了它一個上流的名字——retina)。
這些密度對應着一個特定的縮放比例值,拿咱們最熟悉的iphone4或4s來講,它們的PPI是326,屬於超高密度的手機。當咱們書寫一個寬度爲320px的頁面放到iphone中顯示,你會發現,它居然是滿寬的。這是由於,頁面被默認放大了兩倍,也就是640px,而iphone4或4s的寬,正是640px。
DevicePixelRadio,定義:window.devicePixelRatio是設備上物理像素(也就是device-width)和設備獨立像素(device-independent pixels,即dips)的比例。公式表示就是:window.devicePixelRatio = 物理像素/dips
Android 和 iPhone 中,都有一個佔整個屏幕大小的換算單位,Android 中叫 dip 或 dp,iPhone 中叫 point。Dip,就是device independent pixels,設備獨立像素。而設備的物理像素和 dip 的比例就是 devicePixelRatio,此值能夠經過 window.devicePixelRatio 屬性獲取。
據我查找到的一些資料顯示,這裏的獨立像素的值其實就是device-width值。這個值也就是咱們平時在手機上佈局用的寬度,固然是在設置了<meta />標籤的前提下。
這裏爲何提到devicePixelRatio這個概念呢?
由於當devicePixelRatio=1.5的時候,也就是說當屏幕分辨率寬與device-width的比值爲1.5時,某些手機自帶的瀏覽器(特別是三星手機出如今最多)會出現1px的線解析成2px的bug,可是經測試同一部手機上安裝的UC瀏覽器通常不會有這個bug。關於這個bug,網上有一篇文章作了比較好的解釋:
https://www.imququ.com/post/devicepixelratio-and-border-width.html
注:文章不少知識引用了《移動webapp開發必備知識》和《什麼是viewport,爲啥須要viewport》,連接分別是:
http://www.qianduan.net/mobile-webapp-develop-essential-knowledge.html
http://www.myexception.cn/mobile/428756.html
還有這篇: http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html
Sanding整理