移動端適配之一:到底什麼是像素

最近在作移動端的開發,深刻了解了下移動端適配的一些問題,加上本身的理解,記錄下來,寫一個小的系列博客,與你們分享。全部的問題,就開始從像素提及吧~javascript

像素是一個常常提到的概念,寫CSS的人都常常會用到px做爲單位。可是,在移動端,看着分辨率高達1125x2436的iPhone X,在控制檯中卻只有375x812的分辨率,彷佛有點不合邏輯。這些問題,都將在下面找到答案。css

一切都是點

常常用像素來描述分辨率,好比圖片的分辨率、視頻的分辨率、顯示器的分辨率、手機的分辨率等。不管是那種分辨率,用像素做爲單位,其實就是用點的個數做爲單位,一個像素,就是一個點,或者說是一個很小的正方形html

屏幕中的分辨率

任何顯示設備,如電腦顯示器和手機屏幕,其實都是由不少個小點組成的。好比,個人顯示器分辨率是1920x1080,就表示顯示器橫向一共有1920個像素點,縱向一共有1080個像素點,每一個像素點均可以單獨顯示一種顏色。因而,全部像素點顯示的顏色加起來,就是咱們最後看到的效果。前端

至於每一個像素點是多大,這就跟顯示器硬件的性能有關了。須要注意的是,屏幕大小和分辨率的高低並沒有直接關係java

  • 相同大小的屏幕,分辨率並不必定就相同
  • 屏幕大的顯示設備,分辨率並不必定就高,如iPhone X的分辨率高達2436×1125,就比我用的21英寸顯示器的1920x1080的分辨率還要高

如今經常會提到4K顯示器,就要求屏幕的橫向分辨率達到約4000像素,如3840x2160或4096×2160。很明顯,對於大小相同的屏幕,分辨率越高,像素點越多,每一個像素點也就越小,成本也就越高。可是,分辨率高的最直觀感覺,就是能夠看更高清的圖片和視頻,顯示會更加清晰。程序員

圖片和視頻中的像素

與上面相似,圖片和視頻中的分辨率,也是描述橫向和縱向分辨有多少個像素點。每一個像素點表示一種顏色,全部顏色顯示出來,就是一張圖片。理論上,能夠用數字徹底描述一張圖片,以下面的例子:編程

#ddfd23, #234862 ..... #fab421
#ddfd23, #234862 ..... #fab421
......
#ddfd23, #234862 ..... #fab421
#ddfd23, #234862 ..... #fab421
複製代碼

每一個像素點上的顏色,都用一個色值表示,若是圖片分辨率爲400x300像素,那麼橫向就有400個值,縱向是300個值。瀏覽器

物理像素與設備獨立像素

對於一臺顯示器或手機,實際上是有2個分辨率的,這兩個分辨率是不一樣的,但也是相關的。bash

概念

上面所解釋的屏幕中的分辨率,其實都是物理像素,也就是廠家在生產顯示設備時就決定的實際點的個數。上面提到,對於不一樣的設備而言,物理像素點的大小是不同的,這樣就會帶來問題:舉個例子,21英寸顯示器的分辨率是1440x1080,5.8英寸的iPhone X的分辨率是2436×1125,我用CSS畫一條線,其長度是20px,若是都以物理像素做爲度量單位,那麼在顯示器上看起來正常,在iPhone X屏幕上就變得很是小,不是咱們想要的結果。因此呢,爲了解決這個問題,還須要一個新的度量單位,這個度量單位必須是與設備無關的,採用這個單位,不管在何種設備上,相同長度的線看起來都應該差很少,這就是設備獨立像素(device-independent pixels, dips )。咱們在CSS中用的CSS像素,其實就是一種設備獨立像素,在Android或IOS開發中,人家就不能叫CSS像素了,不過意思仍是同樣滴~網絡

物理像素能夠理解爲硬件設備,設備獨立像素能夠認爲是程序員控制顯示器的接口,中間會通過操做系統來將設備獨立像素轉換成物理像素,用實際的物理像素點來顯示。因此,在編程中能獲取到的都是設備獨立像素,如CSS中的獲取的全部像素都是設備獨立像素,而物理像素對於程序員來講是透明的,咱無法在代碼中看到的。至於怎麼看,將在下文介紹。

物理像素是在出廠時就決定的,可是設備獨立像素實際上是可調的。你們用電腦的時候,應該都試過調整分辨率,此時調整的實際就是設備獨立像素,好比Macbook能夠這樣調整分辨率:support.apple.com/kb/PH25175?…

在設備中查看

廠家在宣傳本身的產品時,每每會拿物理像素說話,由於物理像素纔會表明其工藝水平,纔會吸引用戶花更多的錢去買。對於物理像素,通常在產品的官網參數裏面均可以看到,也能夠在屬性中查看。如對於個人Mac筆記本,在關於本機->顯示器中能夠看到以下的信息,其物理分辨率大小爲2560 x 1600:

顯示器物理分辨率

要查看顯示器的設備獨立像素,做爲寫前端的人,打開瀏覽器,再打開控制檯,敲一下代碼:

screen.width
screen.height
複製代碼

對於個人Mac,獲得的值爲1440 x 900。對於手機,物理像素能夠在手機說明書或者官網的參數配置中查到,而設備獨立像素打開控制檯選擇對應機型後就能夠看到:

固然,也能夠在控制檯中用上面的js命令查看。此外,這裏也提供一個網站:material.io/tools/devic…

無論何種設備,通常都知足:設備獨立像素 <= 物理像素

關係

window.devicePixelRatio = 設備物理像素 / 設備獨立像素
複製代碼

經過window.devicePixelRatio,能夠知道一個設備獨立像素用幾個物理像素點來表示。如iPhone X中,devicePixelRation爲3,iPhone6/7/8中devicePixelRatio的爲2。固然,devicePixelRation並不必定是整數,也有多是1.5,2.25這些小數值。

通過個人實際測試,在手機模式下,上面這個公式基本都是成立的,而在電腦顯示器上,還有些問題。另外,當我調整電腦顯示器的分辨率時,不管調整出來的電腦顯示器分辨率爲多少,在個人MacBook上,devicePixelRation的值都爲2(理論上,調整電腦顯示器的分辨率,即調整了設備獨立像素,而物理像素是固定的,因此devicePixelRation的值會跟着改變猜對)。經查,這多是devicePixelRation在不一樣平臺的定義不一樣形成的,因此目前,在移動端能夠放心的用,在PC端仍是慎用。

縮放

說完上面的概念,也許會有個疑惑:有一張400x300的圖片,分別放到400x300和800x600的顯示器上全屏顯示,會怎麼樣呢?

  • 先來看400x300的顯示器,因爲是全屏顯示,正好圖片也是400x300的分辨率,二者相等,因而很愉快的,顯示器上一個像素點就顯示照片上的一個像素,整個圖片完美的顯示出來了

  • 而在800x600的顯示器上全屏時,圖片上點的數目不夠用了,這時,屏幕上的4個像素點只能顯示照片的一個像素點(爲何是4呢,由於一個像素點能夠當作是一個正方形,橫向和縱向都是2倍,因此2x2=4)。因爲像素已是最小的單位了,不能再往下分了,因此就只能就近取色,因此最後的圖片看起來就會模糊。

這個原理與Retina屏幕顯示是同樣的。好比,對於一幅400x300的圖片,用CSS設定其寬高爲400x300,CSS設定的是設備獨立像素。在普通屏幕上,CSS指定的400x300像素大小區域正好是400x300個物理像素點,圖片完美顯示,對應上面的狀況一;在Retina屏上,devicePixelRatio爲2,CSS指定的400x300像素大小區域有800x600個物理像素點,對應的就是上面的狀況2,因此就會有模糊的狀況。具體原理能夠參考下面的圖(來自網絡):

爲了解決Retina屏幕的顯示問題,每每會用更高分辨率的圖片來代替,好比對於上面的狀況,若是用800x600的圖片,那麼在Retina屏幕上顯示就會很是完美,可是換到普通屏幕上,問題又來了:顯示器上的一個物理像素點要顯示照片上的4個像素點,裝不下了。這時候,會自動下采樣。下采樣以後的,看起來也不會有太大問題,但可能會有點色差或者缺乏銳利度。

CSS的單位

你可能在有的博客上看到,一個像素的長度是一英寸的1/96。這種解釋,貌似給了像素這個比較抽象的單位一個直觀的感覺,可是如今來看,這個只能用來描述CSS像素,不能用來描述物理像素,並且,即便是描述物理像素,也不那麼準確了。因此,在這裏,有必要介紹一下CSS中的單位,順便解釋一下這個問題。

CSS的單位分兩種:絕對長度單位和相對長度單位。

絕對長度單位

  • cm:釐米
  • mm:毫米
  • in:英寸
  • pc(picas):一英寸的1/6
  • pt(points):一英寸的1/72
  • px(pixels):一英寸的1/96

之因此叫絕對長度單位,是由於在只有普通屏幕的時代,相同的單位不管在何種設備上,顯示出來的長度都是一致的,而且1cm就是等於物理長度1釐米。然後來,因爲Retina顯示屏的出現,絕對長度單位裏面的「絕對」,是指單位之間關係是絕對固定的。好比,1in = 72pt1in = 96px是永遠固定不變的。關係不變,就須要選取其中一個做爲基準:

  • 在打印機設備中,通常是以物理單位做爲基準,即1in對應物理單位的1in,此時,1px的長度就是1/96in。全部單位都是與物理長度對應的
  • 而在顯示設備(電腦和手機)中,通常是以像素做爲基準的。好比在iPhone X中,設備的寬度是2.79in(物理寬度),屏幕分辨率是1125物理像素,window.devicePixelRatio = 3,也就是3個物理像素表示一個CSS像素,因此iPhone X寬度的CSS像素是375px。此時,CSS單位的1in表示的實際長度是2.79 / 375 * 96in = 0.71424in,此時,CSS的1in並不表示物理長度1in

之因此這種絕對長度再也不絕對,就是由於多倍屛的出現,使得像素點的物理尺寸縮小。因而,CSS也修改了這些單位的定義,目前已經獲得大多數設備的支持。關於這一點,能夠參加CSS官方文檔:www.w3.org/TR/css-valu…

相對長度單位

相對於預約義的長度或特徵,通常是相對於字體或者viewport,在移動端適配中有很重要的做用

相對於字體

  • ex (x-height):等於所用字體的小寫字母x的高度
  • ch (character):等於所用字體的數字0的寬度
  • em:相對於最近父級font-size,因此會有層層嵌套的問題,每一層都是相對於最近父級
  • rem :相對於html標籤的font-size

相對於viewport

  • vh:viewport高度的1/100
  • vw:viewport寬度的1/100
  • vmin:viewport寬高較小者的1/100
  • vmax:viewport寬高較大者的1/100

總結

這裏花了很大的篇幅去介紹像素,這個看起來簡單實際卻有點複雜但又必須弄清楚的東西,爲後面的移動端適配作基礎。

相關文章
相關標籤/搜索