Viewport 不權威指南

什麼是 Viewport,爲什麼需要 Viewport

Viewport:視口,視覺窗口,顯示區域。

在顯示面積上手機屏幕相對桌面顯示器要小很多,在幾年前(現在也如此)大部分網站都是爲桌面顯示器瀏覽而設計,很少考慮到適應手機屏幕,所以如果用手機瀏覽大多網站時會出現問題,比如常見固定寬度的網頁會出現橫向豎向滑動條,當然這不算什麼大問題;但如果是瀏覽流動佈局的網頁那情況會非常糟糕,設想一個寬度爲 30% 的側邊欄對於 320px 手機屏幕而言也就 96px,只能容納八個 12px 的漢字,可閱讀性非常差。

爲了讓手機也能獲得良好的網頁瀏覽體驗,Apple 找到了一個辦法:在移動版的 SafariiOS平臺)中定義了 viewport meta 標籤,它的作用就是創建一個虛擬的窗口(viewport),而且這個虛擬窗口的分辨率接近於桌面顯示器,Apple 將其定位爲 980px

以一代 iPhone 下的 Safari 來說就是:
iPhone 320px 物理屏幕上——視覺窗口(visual viewport),創建出了一個 980px 的虛擬窗口——佈局窗口(layout viewport),在視覺窗口(visual viewport)中我們可以拖動橫向豎向滑動條或者放大縮小網頁,來達到最佳的瀏覽效果(類似桌面瀏覽器);而佈局窗口(layout viewport)用來配合 CSS 渲染布局,例如當我們設置一個容器的寬度爲 100% 時,這個容器的實際值爲 980px 而不是 320px。如此一來大部分網頁就能以縮放的形式正常的顯示在手機屏幕上了。


如何設置 Viewport

有了 layout viewport似乎解決手機瀏覽網頁的難題,但如果遇到專門爲手機優化的網頁就又有新的問題:


是的,因爲 iPhone layout viewport默認爲 980px,導致專爲其優化的 320px 寬的頁面只能以縮放的方式顯示,這時就需要對 viewport 進行設置:

<head>

...

<metaname="viewport" content="width=device-width, initial-scale=1.0,user-scalable=no"/>

...

</head>

這個是最常見的一條 viewport meta 代碼,將 viewport 定義爲:寬度爲設備寬度,初始縮放比例爲 1 倍,禁止用戶縮放。設置好後我們的頁面就顯示完美了:

  1. <meta name="viewport"

  2.        content=" 

  3.            height = [pixel_value | device-height] , 

  4.            width = [pixel_value | device-width ] , 

  5.            initial-scale = float_value , 

  6.            minimum-scale = float_value , 

  7.            maximum-scale = float_value , 

  8.            user-scalable = [yes | no] , 

  9.            target-densitydpi = [dpi_value | device-dpi | 

  10.                                 high-dpi | medium-dpi | low-dpi] 

  11.            " />

 


viewport 全部屬性&值如下:

width: viewport寬度
height: viewport
高度
initial-scale:
初始縮放比例
maximum-scale:
最大縮放比例
minimum-scale:
最小縮放比例
user-scalable:
是否允許用戶縮放

例:

width=960 device-width
height=1000
device-height
initial-scale=0.5
maximum-scale=2
minimum-scale=1
user-scalable=1
0 (yes no)

layout viewport的默認值

Apple實現viewport後,其他瀏覽器也加入了對viewport meta的支持,但彼此間還是有些差異,差異最大的是layout viewport的表現:

Safari iPhone:980px
Opera: 850px
Android WebKit: 800px
IE: 974px

最後關注下 width=device-width

其實這個屬性&值很有意思,字面意應該是 viewport 寬度等於設備寬度,但在實際中不同的瀏覽器都給出了個定值:320px;這個值還是源於 Apple,因爲早期 iPhone 的分辨率爲 320px × 480px,大量爲 iPhone 量身定製的網站都設置了width=device-width,並且按照寬度 320px 來設計製作,所以其他瀏覽器加入 viewport 支持時爲了兼容性也將 device-width 定義爲了 320px

<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"  />

最初執行viewport meta加入如下

<metaname="viewport" content="width=device-width,initial-scale=1.0">

編譯過程會轉化成如下的語意,

@viewport {

width: device-width;

initial-scale:1.0

}

基本說明

width=device-width

先提一下幾個注意的地方,首先在viewport裏面的width通常會看到設定爲device-width ,主要是爲了讓整個頁面寬度與手機可視寬度相同,如此就可以簡單相容於不同機型螢幕大小,如果這邊width沒有設定的話,就會依照html css給予的width當作預設值。

因爲解析度不同,device-width有時候不一定是view width ,所以在類似iphone 4高解析度機器上,device-width=320,可是實際解析度爲480,這時候就需要利用javascript針對UA下去做動態調整。user-scalable 從屬性名稱來看就是允許開啓、關閉的設定,使用者能否放大、縮小頁面,如果頁面不允許手機使用者縮放,就直接設定爲0,或者no,反之要啓動縮放功能,給予1或者是yes接下來將說明幾種常用的方式,以及測試驗證提供給大家參考。基本寬度(並不是指html body width),

註解

除此之外不同移動瀏覽器廠商也有不同的解決方案,例如 UCweb 就是使用中間件技術。
不同的瀏覽器廠商對於 layout viewport的大小定義不同,詳見”layout viewport的默認值

參考文章:

http://dev.w3.org/csswg/css-device-adapt/
http://www.quirksmode.org/mobile/viewports2.html
https://developer.mozilla.org/en/Mobile/Viewport_meta_tag
http://blogs.msdn.com/b/iemobile/archive/2010/11/22/the-ie-mobile-viewport-on-windows-phone-7.aspx

Media queries &Viewport

  解決問題的關鍵就是Media queries和Viewports。下面的內容是關於如何最好的使用Media queries和Viewports的。但是我並不會深入的講怎樣增強響應的細節,如果感興趣,可以查看這篇博文的最後一部分:“參考文章”。

  ● @media queries

  作爲一個網頁設計師或前端開發者,我們希望我們的網頁總能很容易的自適應不同的設備和屏幕尺寸,不管我們用戶使用的是21″臺式顯示器,13″筆記本電腦,10″的iPad或者更小的智能手機。響應式網頁設計使用@media queries根據瀏覽器的寬度和CSS來改變頁面的佈局。我們可以這樣使用的CSS:

1.     /* Default wide-screen styles */

2.     @media all and (max-width: 1024px) {

3.     /* styles for narrow desktop browsers andiPad landscape */

4.     }

5.     @media all and (max-width: 768px) {

6.     /* styles for narrower desktop browsersand iPad portrait */

7.     }

8.     @media all and (max-width: 480px) {

9.     /* styles for iPhone/Android landscape(and really narrow browser windows) */

10.   }

11.   @media all and (max-width: 320px) {

12.   /* styles for iPhone/Android portrait */

13.   }

14.   @media all and (max-width: 240px) {

15.   /* styles for smaller devices */

16.   }

  是的,我們可以設置更小的width,或者中間尺寸。我待會再討論。CSS media queries是非常強大和複雜的,在這裏不想過多的討論,因爲上面的代碼已經足夠應付響應式Web設計了。如果你想要知道更多關於Media Queries的細節,請閱讀參考文獻裏的相關文章。

  ● viewports

  現在,當我們調整我們瀏覽器的大小時,上面的代碼已經可以非常不錯的完成工作了。但這並不能滿足移動端的瀏覽器。原因是移動端瀏覽器(iPhone/Safari, Android/Chrome和Fennec)會默認頁面是爲寬屏幕設計的,所以將它縮小整個頁面來適應小屏幕。這就表明了上面的代碼完全不足於適應移動端的瀏覽器,因爲設備無法識別正確的寬度。解決方法:在文檔的頭部使用蘋果提供的viewport meta標籤,並結合@media queries:

1.     <meta name="viewport"content="...">

  以上的代碼中,content爲空,因爲我覺得有必要詳細講一下,而不是直接給出來,這樣我們就能更清楚的記住,並且知道content裏應該填些什麼,並且爲什麼這樣填

  ● width=device-width

  我們看見很多網站都建議把content屬性的值設置爲width=device-width。這相當於告訴瀏覽器將頁面寬度假設爲設備寬度。不幸的是,只有當設備是縱向時假設纔是正確的。當我們把設備旋轉成橫向時,device-width還是和縱向的一樣(比如,320px),這意味着,即使我們把頁面設計成適應了480px橫向設備,它還是會返回320px的效果。

  曾經嘗試在media query裏使用orientation來解決這個問題,但是orientation不會真正的告訴我們實際的設備寬度,因爲它只告訴我們設備的寬度是大於還是小於設備的高度。正如有人指出,由於大部分網頁往往垂直滾動,所以這是無關緊要的。

  如果我們的頁面在縱向和橫向設備中樣式相同,那麼我們就可以用width=device-width就足夠了,需要注意的是這個是唯一告訴android設備使用設備寬度的方法。

  ● initial-scale=1.0,maximum-scale=1.0

  initial-scale=1設置告訴瀏覽器初始化頁面時不要對頁面進行縮放。解決了沒有使用viewport時出現的頁面縮放問題。但還是有 bug,當我們把移動端設備從縱向轉成橫向時,你就會發現這個問題了。這是因爲initial-scale只在頁面完全加載後有作用。在我們把移動設備從縱向轉成橫向的過程中,瀏覽器就會認爲頁面不變,但scales會設置爲1.5,爲了使320px的頁面適應480px。但是,因爲我們在@media queries中設置了480px這個寬度,那麼頁面CSS規則也會是適應480px的。結果就是,頁面CSS規則是適應480px的,另外scale還是1.5。這個結果並不可怕,但是不可取。

  爲解決這個bug,我們可以添加maximum-scale=1這個設置。它的作用是阻止頁面在旋轉時放大,但它同時帶來了更嚴重的問題:也阻止了用戶手動放大或縮小頁面。同樣user-scalable=no設置也會讓用戶不能縮放頁面。所以一般情況下,不要使用以上倆個設置。

  是不是無法解決這個bug了?首先這個bug最多只是在顯示層面,帶來的後果一點不嚴重,因爲即使頁面自動縮放了,它還是成比例的。

  ● width=<actual width>

  有些人建議在viewport裏使用特定的width,並且也按這個width設計頁面。如果你可以爲每個種類的device編寫頁面的話,這個設置是可行的,但需要我們明白的是它不是響應式設計。打印時,使用固定寬度佈局是必要的,但我們網頁應該適應用戶的各種樣式的設備。總之,不要這樣使用。

  ● @media all and (device-width:480)

  這是個media query而不是viewport標籤裏的選項, 我在很多地方看到過這樣的代碼,但我並不認爲這是好的做法。爲什麼?根據CSS3對media queries的描述,device-width在media queries裏表示的是輸出設備表面渲染的寬度。對於continuous media來說,device-width就是屏幕的寬度;對於paged media來說,device-width就是頁面尺寸的寬度。以continuous media爲例,device-width就是設備屏幕的寬度。除非瀏覽器最大化,它始終大於viewport的width。

  測試表明,大多數桌面瀏覽器把device-width和width當作同義詞。而移動端瀏覽器對此會有點混淆。至於viewport標籤裏,device-width只在縱向時等於設備的width。例如,一個320*480的設備,device-width總是320px,不論方向。然而對於CSS media queries,device-width是基於其目前方向上屏幕的width。

  如果你一定要這樣使用,請和orientation一起使用。但絕對不要使用max-device-width和min-device-width,因爲用max-width和min-width替換會比較好。同樣需要注意的是,新型號設備的寬度可能會改變。

  ● 中間尺寸

  上面我提到過,我們可以爲任意數量的width來設計頁面。最重要的是在不同width的瀏覽器中測試他們,通過調整window瀏覽器的大小來測試是最簡單的方法。隨着設計頁面的width越來越小,我們可以去掉(Display:none;)一些不重要的內容,比如 footer,sidebars,menu等,爲主要內容留足夠大的空間。我們的網站也許需要一個可以在所有width屏幕上運行良好的佈局,也許只需要滿足兩到三個佈局。這是非常容易設計和測試的,所以沒有理由不做。

  ● 推薦設置

   最後,是我推薦的做法:

  1. 使用viewport標籤

  2. 使用media queries來選擇最適合頁面尺寸的CSS

  3. 在viewport標籤裏,使用width=device-width,initial-scale=1或者單獨使用width=device-width

  4. 不要使用maximum-scale=1和user-scalable=no

  5. 不要使用width=<specific width>

 6. 不要使用@media all and (*-device-width: xxx)

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章