前言
相信在移動端開發的過程中大家都會發現,移動端的顯示一般與桌面端的不一樣。比如在iPhone6上顯示一個1334x750畫素大小塊狀元素,雖然在蘋果官網上iphone6標稱的螢幕畫素密度是1334x750規格,但是我們卻發現這個1334x750畫素大小的塊狀元素卻不能鋪滿整個螢幕。
那到底是為什麼呢?下面從幾個方面來作探討。
畫素密度(PPI)
PPI(Pixel Per Inch),即表示每英寸有多少畫素,類似於人口密度和建築密度,如下圖舉例了幾種PPI的表示。
以iphone6為例,一般畫素密度的計算公式為: Math.sqrt(1366*1366 + 640*640)
但是要計算這個PPI,那麼我們先要知道裝置的螢幕上到底有多少個畫素,也就是Pixel Per Inch 中的第一個Pixel。
裝置畫素(DP)&& 裝置畫素比(DPR)
裝置畫素(Device pixel),也稱物理畫素(Physical pixel),也就是本文一開始提到iphone6的螢幕規格。畫素密度中所指的畫素就是裝置畫素,對於一般的顯示裝置來說,一個畫素對應著螢幕上的一個發光點,因此PPI也稱為DPI(dots per inch),但是這僅在顯示裝置上才等價,比如在印表機上就不一樣了。
由於市面上每一臺手機的螢幕規格不一樣,有的是720P,有的是1080P,甚者是2K等等,這些裝置的螢幕有些畫素多,有些畫素少,如果同樣顯示一個畫素的話,則會出現像以下的情況:
越高PPI的螢幕,顯示一個畫素點的面積就越小,一張由4x4個畫素點組成的圖顯示在PPI為64的螢幕上,那麼換到256PPI的螢幕上顯示則會縮小為原來大小的一半。
反過來,如果要在PPI為256的螢幕上顯示效果與PPI為64的螢幕一樣,那麼得要把圖片放大2倍。
因此配有高畫質螢幕的手機,廠商為了其裝置的可用性,即圖示和文字可以被正確識別和準確點選,就必須保證各類素材在其裝置上的顯示與標清裝置一樣,而這個解決方法就是把所有尺寸都放大若干倍。這個放大比例就叫作裝置畫素比(Device Pixel Ratio, DPR),一般DPR對應著下面這個表:
ldpi | mdpi | hdpi | xhdpi | |
---|---|---|---|---|
ppi | 120 | 160 | 240 | 320 |
dpr | 0.75 | 1.0 | 1.5 | 2.0 |
因此高畫質裝置上應該配有高畫質圖片顯示,不然圖片在高畫質裝置上放大後沒有足夠的畫素顯示其細節,那麼這張圖片就會變得看起來很模糊。
CSS畫素
講了這麼多概念,彷彿還是沒有很好地解釋文章開頭的問題。下面討論完CSS畫素後估計大家會有一個比較清晰的概念。
我們通宵在寫CSS的時候會用到畫素單位px,但是這個畫素單位並不一直是與裝置畫素一一對應,也就是說在CSS中1px(畫素)不是對應著裝置螢幕中的一個畫素點。為了與裝置畫素區別,CSS中所指的畫素px我們一般稱為CSS畫素。也就是說CSS畫素是一個虛擬的、相對的單位。
例如在頁面上畫一個300px寬的塊元素,在一般的顯示器下它只會佔螢幕的一部分,但如果我們手動地去放大頁面,很快這個塊狀元素也會充滿整個頁面。由此說明,一般情況下CSS畫素與系統解析度下的畫素大小相等,即在標清裝置中,一個CSS畫素應該是與一個裝置畫素大小相等的。但是是高畫質裝置或者使用者縮放的過程中,一個CSS畫素也有可能等於多個裝置畫素。
舉另外一個例子,在移動原生應用開發中,如果必須以一個裝置畫素為單位進行開發,那將會是一件非常痛苦的事,因為不是每一臺移動裝置的系統解析度都是對應著一個裝置畫素,有的是1:2,有的是1:2.46,正是因為有這種差異,在安卓開發中會有例如dp,dt這種單位(在iOS中會有pt單位),當我們給一個元素定義大小時,只需要給定一個dp值,系統將會根據這個值再與系統解析度與裝置畫素的比值(即DPR)進行換算,最終計算出顯示在螢幕上的實際裝置畫素。
上面所指出的dp這種抽象單位稱為裝置無關畫素(device independent pixel)。當然CSS畫素也屬於裝置無關畫素,我們在寫CSS畫素的時候,不用關心一個CSS畫素對應著多少個裝置畫素,系統會自動地根據DPR來幫我們換算好。我們要關心的只是如何保證網頁元素因為系統換算而導致被放大的時候下,還能清晰地展示在裝置上。
視口(Viewport)
正常來說,在移動端開啟一個頁面,如果瀏覽器先會以正常的比例來渲染頁面,然後再自動地設定一個比例來縮放頁面,目的是為了讓內容更好地展示出來,即頁面內容剛好鋪滿整個手機螢幕,當然如果頁面沒有禁止掉使用者縮放的話,你也可以用兩個手指把頁面縮放回原始的比例。這整個過程就是透過視口(viewport)來實現的,原始頁面渲染好後透過視口縮放使得與系統寬度一樣,從而可以完整地展示頁面。
(圖片來自tgideas團隊部落格)
我們可以透過在content中新增inital-scale屬性來控制渲染時視窗的縮放比例,把它設定為1則無縮放。
我們也可以定義device-width屬性來控制viewport的寬度
一般在移動開發中我們會設定不允許使用者縮放,並把最大、最小縮放比設為1
總結(Summary)
透過連續幾天的翻閱資料與探索,終於完整地對移動開發最入門的地方有了準確的理解,之前也只是一直把meta裡的程式碼直接複製過來用就是了,一直沒去弄清楚,這次趁著有空並且手上剛好有相關的資料,一併整體地走一遍,最後記錄成此文件,希望對日後甚至會對大家有幫助。
參與資料:
1.深入瞭解viewport和px
2.高效能響應式Web開發實戰