前言
對於移動webapp開發人員來說,viewport是個很重要的東西,容易用但很多時候都是不明白的,於是我決心去弄清楚它。
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
viewport涉及的單位
分辨率:指設備顯示器所能顯示的像素有多少
物理分辨率:指設備顯示器所能顯示最高的像素數
DPI (Dots Per Inch):每英寸的點數密度
PPI(Pixels Per Inch):每英寸的像素點
DIP/DP(device independent pixels): 設備獨立像素, 這個由設備硬件決定。
devicePixelRatio : 設備像素比 ( window.devicePixelRatio = 物理分辨率 / dip )
PS:在計算機或移動屏幕中提到ppi和dpi其實都一樣, 越高的PPI所呈現的內容越清晰。
什么是viewport?
其實手機瀏覽器裝載頁面是放在一個中間件里面的,而這個中間件就是viewport。(起初是ios提出的,后來android借用了)
viewport重要概念
1.可視區(visual area) : 就是我們設備上能看到頁面的區域 (這個長度不是固定的)。
2.設備寬度(device-width) : 這個就是DIP的值,即是設備獨立像素,由設備硬件本身決定(iPhone4S 是 320, iPhone6 plus 是 414, 魅藍 是 432 )
PS:device-width一般值范圍是320—432
viewport屬性
width:viewport 的寬度
height:viewport的高度 (很少使用)
initial-scale:設置頁面的初始縮放值
minimum-scale:允許用戶的最小縮放值
maximum-scale:允許用戶的最大縮放值
user-scalable:是否允許用戶進行縮放
target-densitydpi(android才生效):設備的密度等級
PS:講上面所有屬性是沒有必要的,我理出最重要的三個屬性來說明,即可理解viewport
viewport重要屬性
三個重要屬性是分別是width、initial-scale、target-densitydpi(這個屬性放后面講)
width與initial-scale組合設置,有四種不同的情況(android上設initial-scale無效的,這個后面講,先講ios上的情況),iPhone4S(它的設備寬度是320)上測試:
1.設width(固定值),不設initial-scale
ios瀏覽器會為了調整頁面能夠滿屏顯示,會自動計算縮放比,即initial-scale
例如:設置width=640
viewport width = 640px
縮放比 = 320 / 640 = 0.5
可視區寬度 = 設備寬度 / 縮放比 = 320 / 0.5 = 640px
PS:上面這條可視區寬度的計算公式是我測試得出的, 不過回過頭看某些介紹viewport文章, 他們也有介紹。
2.設width(固定值),設initial-scale = 1.0
例如:設置width=640
viewport width = 640px
縮放比 = 1.0
可視區寬度 = 設備寬度 / 縮放比 = 320 / 1.0 = 320px
PS:所以如果這樣設置,就會出現頁面只顯示了一半的情況。
3.設width為device-width, 不設initial-scale
沒有設initial-scale情況下,initial-scale一直是1.0
例如:設置width=device-width
viewport width = 320px (iPhone4s設備寬度)
縮放比 = 1.0
可視區寬度 = 設備寬度 / 縮放比 = 320 / 1.0 = 320px
4.設width為device-width, 設initial-scale = 0.5
例如:設置width=device-width
viewport width = 320px (iPhone4s設備寬度)
縮放比 = 0.5
可視區寬度 = 設備寬度 / 縮放比 = 320 / 0.5 = 640px
PS:這個時候顯示的頁面是640px寬
說到這里,大家應該對各種設置viewport的方式有一定的了解。
viewport之android
這里之所以把android單獨拿出來,就是target-densitydpi(以后的android版本會廢棄)這個屬性的問題。
對於android來講,initial-scale在大部分機型上無效的,無論是0.5或2都不會變化,但這不影響我們使用viewport。
target-densitydpi這個屬性設置設備使用什么dpi顯示,其實在我的理解來說,其實就是充當縮放的功能。
target-densitydpi取值:可以為一個數值或 high-dpi 、 medium-dpi、 low-dpi、 device-dpi 這幾個字符串中的一個。
一些特殊取值:
low-dpi : 120
medium-dpi : 160
high-dpi : 240
xhdpi : 320
xxhdpi : 400
PS:不設置的情況下,默認選擇的是 medium-dpi(但有些機型默認不是這個,像小米1默認就是high-dpi)
設置target-densitydpi這些值會導致怎么樣的縮放呢?
縮放的比是與 medium-dpi的比:
120 -> 120/160 = 0.75
160 -> 160/160 = 1 (華為榮耀xx device-dpi)
240 -> 240/160 = 1.5 (小米1 device-dpi)
320 -> 320/160 = 2 (聯想樂檬 device-dpi)
400 -> 400/160 = 2.5 (魅藍 device-dpi)
PS:后面括號里是我測試的機型它們各自的device-dpi
例如:
1.當你設target-densitydpi = 240時:
華為榮耀xx可視區寬度 = 設備寬度 * dpi比值 = 360 * 1.5 = 540
小米1可視區寬度 = 設備寬度 * dpi比值 = 320 * 1.5 = 480
聯想樂檬可視區寬度 = 設備寬度 * dpi比值 = 360 * 1.5 = 540
魅藍可視區寬度 = 設備寬度 * dpi比值 = 432 * 1.5 = 648
2. 當你設target-densitydpi = device-dpi時:
華為榮耀xx可視區寬度 = 設備寬度 * dpi比值 = 360 * (160/160) = 360
小米1可視區寬度 = 設備寬度 * dpi比值 = 320 * (240/160) = 480
聯想樂檬可視區寬度 = 設備寬度 * dpi比值 = 360 * (320/160)= 720
魅藍可視區寬度 = 設備寬度 * dpi比值 = 432 * (400/160) = 1080
PS:根據上面的結論,我強烈建議不要使用 target-densitydpi = device-dpi, 因為不同設備上最終的可視區的寬度差異很大,除非你的app有為之做處理(rem、em的相對單位寫法)。
viewport的東西也大體講到這里!
注意:
1.何時viewport width設置固定值?
當你的頁面為某個固定寬度,或者里面的元素長寬和字體大小在某種寬度顯示才看起來正常時候。
2.固定viewport width的注意事項
當設備橫豎屏切換時候,就需要切換viewport的width值,而且手機和平板的viewport width也是不同的。
3.viewport的width多大多小?
當width小於設備寬度時候按設備寬度計算,而能設多大這個想法並沒什么意義。
總結:
其實說了那么多,其實就回到開頭那句代碼,而最終建議設的viewport也是那一句,也希望我的想法大家能理解,如果有錯誤地方請指正。
附上ios對viewport的講解:Configuring the Viewport
本文為原創文章,轉載請保留原出處,方便溯源,如有錯誤地方,謝謝指正。