【轉】移動瀏覽器的viewport
本文主要轉自:移動瀏覽器的viewport ,部分內容有補充修改。
對于移動web開發,最好了解一下viewport的概念,在quirksmode.org有兩篇文章詳細介紹了它,A tale of two viewport(1 2),感覺非常好,本來想翻譯的,但這兩篇文章實在太長了,沒耐性,于是抽取了其中重點講viewport的部分,用半翻譯半自己寫的方式寫出來,這也是為了讓自己能夠理解得更好一些。
其中CSS像素和設備像素的概念,還有js獲取各種寬高和位置的內容都沒有提及,要想了解得更清楚還是推薦看看那兩篇文章。以下圖片均來自quirksmode.org。
桌面瀏覽器
先說說桌面瀏覽器上viewport的概念,在桌面瀏覽器上viewport就是瀏覽器內容的可視范圍,它決定了<html>元素的默認寬高。舉個例子:
在一個流動布局的頁面上,你給側欄設置了width:30%,放在<body>下,正常情況下你拖動瀏覽器,改變瀏覽器的大小,這個側欄會自動調整寬度使它的寬度為瀏覽器寬度的30%,那么這個自動調整的過程具體是怎樣的呢?
這個側欄會獲取父元素的寬度,乘以30%得到自己的寬度。那問題就變成這個側欄的父元素<body>寬度的取值問題。一般情況下,一個塊級元素的寬度會自動伸展到父元素的寬度,所以這里<body>的寬度等于<html>的寬度。那么<html>的寬度又由誰決定?理論上,如果沒有給<html>指定CSS寬度,那它的寬度由viewport決定,于是這里30%的寬度就是瀏覽器viewport的寬度。
viewport的寬高不僅在窗口resize的時候會改變,在縮放的時候也會變化。例如:
這個頁面,有一個寬度100%的nav和寬度800px的test元素,把窗口寬度調整到800px,頁面上兩個元素nav和test大小是一致的。對頁面通過瀏覽器縮放放大一倍,此時viewport的css寬度縮小為400px(設備寬度不變),nav元素的css寬度也就縮小到了400px,test元素仍然是800px,比nav大了一倍。
viewport不是HTML的一部分,無法用css控制它,對桌面瀏覽器來說,viewport只是一個擁有瀏覽器可視寬高(css像素)屬性的東西。
移動瀏覽器
移動設備比桌面設備屏幕小很多,如果把桌面瀏覽器viewport的概念照搬過來會出現什么后果?
假設流動布局的網站,一般給側欄設置width:30%,那么假設移動瀏覽器寬高是320*480,那么這個側欄實際擁有的寬度只有不到100px,放幾個字都不夠,這會讓你的網站顯得很糟糕,一大票在桌面瀏覽器結構良好的網頁在移動瀏覽器上都會慘不忍睹。
移動瀏覽器的設計者就希望移動設備上網頁的顯示能盡可能地接近桌面瀏覽器,于是有了這么兩個概念:visual viewport和layout viewport。
visual viewport就是瀏覽器當前顯示的部分頁面,可以通過拖動改變頁面顯示的部分,通過放大縮小改變visual viewport的大小。

layout viewport就是提供給CSS計算的viewport,相當于桌面瀏覽器的viewport,不同的是layout viewport跟當前瀏覽器可視范圍無關系,瀏覽器怎么縮放都與它無關,它是一個給定的值。
不同設備給layout viewport定了不同的默認值,寬度上大概是:Safari 980px,Opera 850px,Android Webkit 800px,IE 974px,高度根據設備屏幕的寬高比計算。(實際上viewport的高度幾乎沒用,可以忽略之)
這樣提供給css計算的viewport寬高就與桌面瀏覽器相近了,頁面計算渲染出來的效果跟桌面瀏覽器幾乎一致。頁面放大縮小不會影響到layout viewport,也就是不會影響到頁面渲染。

在移動瀏覽器上,所有頁面打開時默認visual viewport = layout viewport,也就是最小縮放,例如用mobile safari打開一個頁面,無論頁面內容如何,都會顯示980px寬度的內容。

修改layout viewport
可以通過在<head>上寫<meta>標簽改變瀏覽器的layout viewport,如果專門針對移動瀏覽器設計頁面,那最常用的就是設置layout viewport寬度為設備寬度,或者設置initial-scale,并設置不可縮放,這樣移動瀏覽器就始終以1:1的方式渲染顯示頁面,無需理會縮放,可以像桌面瀏覽器那樣進行精確的開發。
<meta name=”viewport” content=”width=device-width, user-scalable=no”>
<meta name=”viewport” content=”initial-scale=1.0, user-scalable=no”>
Viewport語法為:
<meta name="viewport" content=" height = [pixel_value | device-height] , width = [pixel_value | device-width ] , initial-scale = float_value , minimum-scale = float_value , maximum-scale = float_value , user-scalable = [yes | no] , target-densitydpi = [dpi_value | device-dpi | high-dpi | medium-dpi | low-dpi] "/>
height
和 width 相對應,指定高度。
width
控制 viewport 的大小,可以指定的一個值或者特殊的值,如 device-width 為設備的寬度(單位為縮放為 100% 時的 CSS 的像素)。
initial-scale
初始縮放。即頁面初始縮放程度。這是一個浮點值,是頁面大小的一個乘數。例如,如果你設置初始縮放為“1.0”,那么,web頁面在展現的時候就會以target density分辨率的1:1來展現。如果你設置為“2.0”,那么這個頁面就會放大為2倍。
maximum-scale
最大縮放。即允許的最大縮放程度。這也是一個浮點值,用以指出頁面大小與屏幕大小相比的最大乘數。例如,如果你將這個值設置為“2.0”,那么這個頁面與target size相比,最多能放大2倍。
user-scalable
用戶調整縮放。即用戶是否能改變頁面縮放程度。如果設置為yes則是允許用戶對其進行改變,反之為no。默認值是yes。如果你將其設置為no,那么minimum-scale 和 maximum-scale都將被忽略,因為根本不可能縮放。
所有的縮放值都必須在0.01–10的范圍之內。
target-densitydpi
一個屏幕像素密度是由屏幕分辨率決定的,通常定義為每英寸點的數量(dpi)。Android支持三種屏幕像素密度:低像素密度,中像素密度,高像素密度。一個低像素密度的屏幕每英寸上的像素點更少,而一個高像素密度的屏幕每英寸上的像素點更多。Android Browser和WebView默認屏幕為中像素密度。
下面是 target-densitydpi 屬性的 取值范圍
- device-dpi –使用設備原本的 dpi 作為目標 dp。 不會發生默認縮放。
- high-dpi – 使用hdpi 作為目標 dpi。 中等像素密度和低像素密度設備相應縮小。
- medium-dpi – 使用mdpi作為目標 dpi。 高像素密度設備相應放大,低像素密度設備相應縮小。 這是默認的target density.
- low-dpi -使用mdpi作為目標 dpi。中等像素密度和高像素密度設備相應放大。
- <value> – 指定一個具體的dpi 值作為target dpi. 這個值的范圍必須在70–400之間。
為了防止Android Browser和WebView 根據不同屏幕的像素密度對你的頁面進行縮放,你可以將viewport的target-densitydpi 設置為 device-dpi。當你這么做了,頁面將不會縮放。相反,頁面會根據當前屏幕的像素密度進行展示。在這種情形下,你還需要將viewport的width定義為與設備的width匹配,這樣你的頁面就可以和屏幕相適應。
例如:
<!--(設置屏幕寬度為設備寬度,禁止用戶手動調整縮放)--> <meta name="viewport" content="width=device-width,user-scalable=no" /> <!--(設置屏幕密度為高頻,中頻,低頻自動縮放,禁止用戶手動調整縮放)--> <meta name="viewport" content="width=device-width,target-densitydpi=high-dpi,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
高分辨率移動設備
移動瀏覽器的分辨率與移動設備本身的分辨率并不一定一致。現在市面上有很多高分辨率的手機,例如3.7寸的Nexus One手機分辨率達到800*480,3.5寸的iphone4分辨率達到960*640。但如果以這樣實際的值提供給瀏覽器進行計算和渲染,那會有兩個問題。
- 與其他移動設備差別太大,導致之前專門設計的頁面無法兼容
- 按照這樣的分辨率去設計頁面時,會亂了套,例如12px的字體在普通移動設備上顯示正常,但在高分辨率設備上顯得太小無法分辨,必須手動把它調高N倍。
于是這些高分辨率設備沒有提供真實的像素值給瀏覽器,而是通過比例縮放的。例如iphone4縮小2倍(480*320),Nexus縮小1.5倍(533*320),反過來說就是每個頁面都默認放大X倍顯示。所以以前一個針對iphone3GS以下設計的網頁,在iphone4上表現完全一致,只是更精致了。

浙公網安備 33010602011771號