你真的瞭解css畫素嘛?

淼淼真人發表於2018-09-09

在日常開發中,px一定是大家接觸過最多的css單位,但是你真的瞭解px嘛?1px在螢幕中到底是多大呢?另外不知道大家有沒有過下面這些疑惑:

  • 為什麼一個元素在pc上和移動端的物理尺寸不一樣,但是兩者的視覺效果上卻差不多呢?
  • 改變螢幕的解析度時,螢幕上顯示的內容大小為什麼會跟著改變?
  • 縮放瀏覽器時,瀏覽器中的內容的大小為什麼會跟著改變?

想回答以上問題,我們就要知道css中的px到底指的是什麼?

什麼是css px?

在回答什麼是css px之前,我們先要了解兩個概念——裝置畫素和參考畫素。

裝置畫素(device pixel)

來看這張顯示器螢幕的放大圖。

device pixel

從圖中可以看到,顯示器螢幕實際上是由一個一個"點"組成的(每個"點"又包含3個單位,也稱三元素組),這些"點"就是裝置畫素

需要注意的是,device pixel實際是可以"變化"的,當你降低裝置解析度時,一個"點"就需要更多的三元素組來組成,此時"點"的物理尺寸就增大了。以下是維基百科關於這點的說明,想了解更多,請點選這裡檢視

因為多數計算機螢幕的解析度可以通過計算機的作業系統來調節,螢幕畫素的解析度可能不是一個絕對的衡量標準。
現代液晶螢幕按設計有一個原始解析度,它代表畫素和三元素組之間的完美匹配。
對於該顯示器,原始解析度能夠產生最精細的視訊。但是因為使用者可以調整解析度,顯示器必須能夠顯示其它解析度。非原始解析度必須通過在液晶螢幕上擬合重新取樣來實現,要使用插值演算法。這經常會使螢幕看起來破碎或模糊。例如,原始解析度為1280×1024的顯示器在解析度為1280×1024時看起來最好,也可以通過用幾個物理三元素組來表示一個畫素以顯示800×600,但可能無法完全顯示1600×1200的解析度,因為物理三元素組不夠。

由於不同的裝置螢幕解析度和尺寸可能不一樣,所以裝置上物理畫素的大小也就不一樣。但是對於css來說,它希望在所有的裝置上元素的顯示效果看起來都是差不多的。

那怎麼才能讓同一元素在不同的裝置上顯示的效果差不多呢?w3c提出了一個概念,也就是下面將要介紹的參考畫素(reference pixel)。

參考畫素(reference pixel)

近大遠小
從上面這幅圖可以看到,近處的鐵軌看起來很大,而遠處的鐵軌看起來很小。這是由於我們眼睛的視角所產生"近大遠小"的透視現象所造成的。

那設想一下,如果遠處的鐵軌比近處的鐵軌尺寸大一些,是不是我們看遠處的鐵軌就和看近處的差不多大了呢。

css參考畫素(reference pixel)就是應用了這個原理,w3c是這樣定義參考畫素的

The reference pixel is the visual angle of one pixel on a device with a pixel density of 96dpi and a distance from the reader of an arm's length. For a nominal arm's length of 28 inches, the visual angle is therefore about 0.0213 degrees.

reference pixel圖示

注意了,css參考畫素它是一個visual angle,即一個約等於0.0213度的角。當裝置的典型觀看距離越遠時,參考畫素就越大(注意這裡的大,不是指視角變大,而是角度對應在螢幕上的尺寸變大)。

在介紹完裝置畫素和參考畫素之後,下面該輪到今天的主角——css畫素出場了。

css畫素(css pixel)

顧名思義,css pixel是css樣式表語言中用來表示長度的一個單位,類似的單位還有pt,in,cm等。像pt,in,cm等都是物理單位,相對好理解,而px則有點抽象。

一個px到底是多大? 它又和pt,in,cm的長度等有什麼聯絡呢?這些都是亟待我們思考的問題。

在思考這些問題之前,先看下面這段w3c規範

For a CSS device, these dimensions(指in,pt,px等length單位) are either anchored by relating the physical units to their physical measurements, or by relating the pixel unit to the reference pixel. For print media and similar high-resolution devices, the anchor unit should be one of the standard physical units (inches, centimeters, etc). For lower-resolution devices, and devices with unusual viewing distances, it is recommended instead that the anchor unit be the pixel unit.For such devices it is recommended that the pixel unit refer to the whole number of device pixels that best approximates the reference pixel.

對於css length單位(當然也包括px)來說,不同的解析度裝置對它們的影響是不同的。

對高解析度顯示裝置(如印表機),length的anchor unit(可以理解為基準單位)推薦使用基於物理測量的inches,centimeters等。而對於低解析度的裝置(如電腦顯示器),anchor unit推薦使用pixel單位。下面具體來講講這兩者的區別:

高解析度裝置(high-resolution devices)

關於解析度的東西這裡不多講,不熟悉的同學可以點選這裡檢視。我們之前說了,對於高分辨的顯示裝置,基準單位是基於物理測量的inches, centimeters。

基於物理測量是什麼意思呢?就是它實際的物理長度。如單位cm, 用css設定一個盒子的寬度為1cm,那它就等於物理上的1cm,你用尺子去量,它就是1cm。

那現在問題來了,px呢?px怎麼去基於物理測量呢?

這個問題我們結合w3cmdn,就能得到解答:

Alternatively if the anchor unit is a physical unit, the pixel unit might not map to a whole number of device pixels.

However, for printers and high-resolution screens, one CSS pixel implies multiple device pixels. 1px = 1/96th of 1in.

現在知道了,在高解析度裝置下,1px就等於96分之一英寸,約等於0.2646mm。

低解析度裝置(low-resolution devices)

對於低解析度裝置來說,anchor unit是基於pixel unit的,那pixel unit又是什麼呢?如果有仔細看過css畫素那小節裡引用w3c的那段說明的話,答案你應該已經知道了。為了說明方便,還是把那句最重要的話再寫一遍。

For such devices it is recommended that the pixel unit refer to the whole number of device pixels that best approximates the reference pixel.

這句話非常重要!!!

可以說理解了這句話,你就基本上理解了什麼是css畫素。這裡為了照顧部分英語不好的同學,我把這句話翻譯一遍

對於這樣的裝置(這裡指低解析度裝置),建議畫素單位參考最接近參考畫素的整數個裝置畫素。

我們舉個例子來說明一下,一個解析度為1680 * 1050的22寸電腦顯示器。對於電腦顯示器來說,它的參考畫素約為0.26mm(這個值的大小由裝置的典型視距決定,出廠時已經確定)。

確定了參考畫素之後,再來計算裝置畫素。通過解析度和尺寸,計算出該顯示器的ppi 為90.05,此時一個裝置畫素的值就等於0.28mm。

對比這兩個畫素值之後發現,一個裝置畫素的值是最接近參考畫素的。所以對於這個裝置來說,一個畫素單位(1px)就等於一個裝置畫素。

到這裡,相信大家對css px是什麼應該有了一個基本的概念。下面我們通過分析文章開始時提出的幾個問題,來進一步加深對css px的印象。

分析問題

(1)為什麼一個元素在pc上和移動端的物理尺寸不一樣,但是兩者的視覺效果上卻差不多呢?

因為css px是基於參考畫素確定的,而參考畫素就是為了讓同一元素在不同裝置上顯示效果儘量一致而設計的(對於移動端和pc端來說,參考畫素的物理大小肯定不一樣,但是顯示效果基本是一致的)。所以同一個元素,儘管在pc端和移動端尺寸不一樣,但視覺效果卻是差不多的。

(2)當改變螢幕的解析度時,螢幕上顯示的內容大小為什麼會跟著改變?

我們舉一個例子來說明這個問題,還是以上面那個典型的22寸顯示器為例:

  • 正常解析度下,即1680 * 1050,此時的ppi是90.05,那一個device pixel的長度就約為0.28mm。這時一個device pixel就約等於一個參考畫素對應的大小。如果你用css定義了一個盒子寬為375px,此時你用尺子去螢幕上量,會發現375px盒子的實際寬度是0.28(mm) * 375 ≈ 10.5cm。

  • 調整顯示器的解析度為1024 * 640時,此時一個device pixel對應的長度是0.46mm,雖然它和參考畫素對應的大小有差距,但是沒辦法,你還得使用它,畢竟它現在就是最接近參考畫素大小的device pixel了。上面那個375px的盒子,此時的實際寬度則為0.46 * 375 ≈ 17.4cm。所以降低解析度之後,相同的內容會顯得大了。

  • 調整顯示器的解析度為1920 * 1080,此時一個device pixel對應的長度是0.25mm,此時375px的盒子實際寬度是0.25 * 375 ≈ 9.3cm,所以提高解析度後,內容自然就變小了。

(3)當你縮放瀏覽器大小時,瀏覽器中的內容的大小會跟著改變?

這個現象,ppk在之前的一篇文章裡提到過。縮放瀏覽器時,也就相當於改變了瀏覽器的解析度,所以這個問題和第2個一樣,這裡也就不多贅述了。

總結

1.對於低解析度裝置(絕大部分顯示器,手機螢幕),1個css畫素相當於最接近參考畫素的整數個裝置畫素。

2.對於高解析度裝置(印表機)來說,1個css畫素就是96分之一英寸。

3.參考畫素(reference pixel)就是從一臂之遙看解析度為96DPI的裝置時,1個裝置畫素的視角(但為了方便計算,都把這個視角轉換為其在顯示裝置上對應的大小)。

3.在低解析度裝置中,pt,cm,in等單位的大小不等於它的物理大小,它們的大小需要px(這時等於xx個裝置畫素)來進行轉換,如1in此時等於96個裝置畫素的大小(即96px)。

4.在高解析度裝置中,1px也不等於xx個裝置畫素,px的大小就等於固定值。

5.裝置畫素(device pixel)不是固定不變的,除非你的裝置不能調整解析度。

參考文獻

A tale of two viewports — part one

w3c css規範

CSS畫素、物理畫素、邏輯畫素、裝置畫素比、PPI、Viewport

wiki pixel

wiki 液晶顯示器

移動端高清、多屏適配方案

rethinking the pixel it‘s all relative now

A Pixel Identity Crisis

相關文章