譯—— a tale of viewport2

這一頁咱們將討論移動瀏覽器。若是您對移動設備徹底陌生,我建議您首先閱讀第一部分關於桌面瀏覽器的內容,以便在熟悉的環境中作好準備。css

移動瀏覽器的問題

移動瀏覽器和桌面瀏覽器比較,最明顯的差別是屏幕大小。移動瀏覽器若是要顯示桌面優化網頁,要麼字體會縮小到沒法閱讀,要麼只能顯示網頁的一部分。html

移動設備屏幕要比桌面小得多,最大的寬度大概是400px,有些還要更小一些。(有些手機聲稱更大一些的尺寸,可是他們在說謊——或至少給了咱們無用的信息)web

做爲中間層的平板電腦例如iPad等,彌補了臺式電腦和手機支架的差距(讓差距顯得不突兀吧),可是這麼有改變根本性問題。網站依然須要在手機設備上運行,咱們須要讓其在小屏幕上良好顯示。瀏覽器

最重要的問題集中在CSS上,特別是viewport(視口)的大小。若是在移動設備上直接使用桌面網頁,CSS將會出現嚴重錯誤。app

讓咱們回到以前的一個例子,側邊欄寬度width:10%。若是移動瀏覽器同桌面瀏覽器同樣運行,側邊欄的寬度大概是40px,這是在太窄了。流佈局被嚴重壓縮。佈局

一個解決辦法就是針對移動瀏覽器從新構建一個特殊的網站。拋開是否應該這麼作來解決根本問題,實際上能有多少網站提供專門針對於移動設備的網站。測試

移動瀏覽器供應商想要給用戶提供最好的體驗,須要作的就是「儘量跟桌面網頁相似」。若是想要作到這樣,就必須耍些花招。字體

兩個viewport

對於你的CSS佈局來講,目前的viewport太窄了。明顯的解決辦法就是讓viewport更寬些。爲了這個目的,須要將viewport分爲兩個種類:the visual viewport 和the layout viewport。優化

George Cummins在Stack Overflow上對基本概念作了最好的解釋:網站

Imagine the layout viewport as being a large image which does not change size or shape. Now image you have a smaller frame through which you look at the large image. The small frame is surrounded by opaque material which obscures your view of all but a portion of the large image. The portion of the large image that you can see through the frame is the visual viewport. You can back away from the large image while holding your frame (zoom out) to see the entire image at once, or you can move closer (zoom in) to see only a portion. You can also change the orientation of the frame, but the size and shape of the large image (layout viewport) never changes.

將佈局視圖端口想象成一個不改變大小或形狀的大圖像。再想象你有一個相框,能夠經過相框看到那幅大圖像。相框外周都是不透明的,只有經過中間部分能夠看見圖像。能夠透過相框看到的那部分就是the visual viewport(可視窗口)。你能夠拿着相框後退距離圖像遠一點,就能夠看到整個圖像。也能夠距離更近一些,只看圖像的一部分。圖像的大小和形狀(the layout viewport)並不會發生任何改變。

(能夠去看原文,其實英文挺直觀的。而且還有做者引用的其餘解釋)

the visual viewport(可視窗口)是當前顯示在屏幕上的頁面的一部分。用戶能夠經過滾動操做移動去查看頁面的其餘部分,也能夠縮放改變the visual viewport (可視窗口)的大小。

然而,CSS佈局,特別是百分比寬度,是根據layout viewpor(佈局視圖)t計算的,它比visual viewport寬得多。

<html>元素最初會採用layout viewport的寬度,css將會被解釋爲當前屏幕比手機屏幕寬得多。這能夠確保你的站點佈局和桌面佈局一致。

layout viewport到底多寬呢?每一個瀏覽器都不同。Safari Iphone使用980px,Opera使用850px,Android Webkit是800px,IE是974px。

有一些瀏覽有一些特殊的行爲:

  • Symbian Webkit試圖讓layout viewport和visual viewport一致,這會讓百分比寬度表現的很奇怪。可是,若是頁面因爲絕對寬度不適合vidual viewport(可視視圖),瀏覽器會將佈局視圖擴展到最大850px。
  • samsung webkit 使layout viewport跟最寬的元素的寬度一致。
  • BlackBurry的layout viewport和100%縮放的visual viewport一致,而且不會改變。

縮放(zooming)

顯而易見,兩個viewport都是CSS像素單位。可是當visual viewport隨着縮放改變時(若是放大,屏幕顯示的CSS像素就會減小),layout viewport始終保持不變。

理解layout viewport

爲了理解layout viewport 的尺寸先來看一下當頁面徹底縮小的時候發生了什麼。許多移動瀏覽器最初以徹底縮小模式顯示任何頁面。

重點是:瀏覽器選擇了layout viewport的大小以至於它以徹底縮小的模式覆蓋屏幕(所以同visual viewport 一致)

 所以,layout viewport的寬高等於以最大縮小模式顯示在屏幕的內容的寬高。即便用戶放大,也不會發生改變。

layout viewport老是保持不變。當你旋轉你的手機,visual viewport發生改變,可是瀏覽器適配器會適當放大使得layout viewport和visual viewport同樣寬。

這對layout viewport的高度有影響,layout viewport的高度大大低於豎屏模式。可是web開發人員並不關心高度,只關心寬

測量layout viewport

如今有了兩個viewport尺寸須要測量。很是幸運的是,瀏覽器大戰給了咱們兩對屬性。

document.documentElement.clientWidth/Height表示layout viewport的大小。

方向與高度有關,但與寬度無關。

 

測量visual viewport

至於visual vireport,能夠經過window.innerWidth/Height得到。很顯然,當用戶進行縮放時,這個數值會發生變化,使更多或者更少的CSS像素適合屏幕。

不幸的是,這是一個沒有徹底兼容的領域。許多瀏覽器仍然須要添加對測量visual viewport的支持。可是,沒有瀏覽器將此測量存儲在任何其餘屬性對中,我猜想window.innerWidth/Height是一個標準,儘管支持力度不夠。

window.innerWidth/Height

Meaning
    Visual viewport dimensions
Measured in
    CSS pixels
Full support
    iPhone, Symbian, BlackBerry
Problems
    Opera and Firefox return the screen width in device pixels.
    Android, Bolt, MicroB, and NetFront return the layout viewport dimensions in CSS pixels.
Not supported
    IE, but it gives the visual viewport dimension in document. documentElement. offsetWidth/Height.
    Samsung WebKit reports either the dimensions of the layout viewport or of the <html>, depending on whether a <meta viewport> tag has been applied to the page or not.
Gibberish
    Iris, Skyfire, Obigo

 

屏幕(the screen)

就像在桌面,screen.width/height給出屏幕的大小,使用設備像素。如同桌面同樣,做爲web開發者,不須要知道這個信息。您感興趣的不是屏幕的物理大小,而是它當前適合多少CSS像素。

screen.width and screen.height

Meaning
    Screen size
Measured in
    Device pixels
Full support
    Opera Mini, Android, Symbian, Iris, Firefox, MicroB, IE, BlackBerry
Problems
    Opera Mobile on Windows Mobile only gives the landscape size. Opera Mobile on S60 gets it right.
    Samsung WebKit reports either the dimensions of the layout viewport or of the <html>, depending on whether a <meta viewport> tag has been applied to the page or not.
    iPhone and Obigo only give portrait sizes.
    NetFront only gives landscape sizes.
Gibberish
    Bolt, Skyfire

 

縮放級別

不可能直接讀取縮放級別,可是分割screen.width和window.innerWidth獲得。問題是若是這兩個屬性對都獲得徹底的支持才能夠。

幸運的是縮放級別並不重要。你須要知道的是,屏幕適合多少CSS像素。能夠從window.innerWIdth獲取I信息——若是它被正確支持。

滾動偏移量

若是須要知道相對於layout viewport當前頁面的位置。也就是滾動偏移量,跟桌面同樣,存在window.pageX/YOffset中。

window.pageX/YOffset

Meaning
    Scrolling offset; which is the same as the visual viewport’s offset relative to the layout viewport.
Measured in
    CSS pixels
Full support
    iPhone, Android, Symbian, Iris, MicroB, Skyfire, Obigo.
Problems
    Opera, Bolt, Firefox, and NetFront always return 0.
    Samsung WebKit reports correct values only if a <meta viewport> is applied to the page. 
Not supported
    IE, BlackBerry. IE stores the values in document. documentElement. scrollLeft / Top

html元素

和桌面同樣,document.documentelement.offsetWidth/Height給出了以CSS像素爲單位的<html>元素的總大小。

document. documentElement. offsetWidth / Height

Meaning
    Total size of the <html> element.
Measured in
    CSS pixels
Full support
    Opera, iPhone, Android, Symbian, Samsung, Iris, Bolt, Firefox, MicroB, Skyfire, BlackBerry, Obigo.
Problems
    NetFront’s values are only correct at 100% zoom.
    IE uses this propery pair to store the dimensions of the visual viewport. In IE, see document. body. clientWidth/Height for the correct values.

媒體查詢

媒體查詢和桌面查詢相同。width/height使用layout viewport做爲參考,使用CSS像素做爲單位。device-width/height採用設備屏幕,設備像素做爲單位。

換句話說,width/height反映的是document.documentElement.clientWidth/Height的值。device-width/height反映的screen.width/height的值。(它們實際上在全部瀏覽器中都這樣作,即便反映的值可能不正確。)

因此到底哪一個數值對於開發是有用的呢。其實我也不知道

我開始認爲device-width是最重要的,由於它給的是設備的信息,咱們可能會須要這個信息。例如,能夠改變佈局的寬度以適應設備的寬度。不過,您也可使用<meta viewport>;使用device-width的媒體查詢並非絕對必要的。

那麼,width究竟是不是更重要的媒體查詢呢?也許;它提供了一些線索,關於瀏覽器供應商認爲何是該設備上一個網站的良好寬度。但這是至關模糊的,寬度媒體查詢實際上沒有提供任何其餘信息。

因此我猶豫不決。就目前而言,我認爲媒體查詢對於判斷您是在臺式機、平板電腦仍是移動設備上很是重要,但對於區分不一樣的平板電腦或移動設備並非很是有用。

事件座標

事件座標或多或少與桌面座標相同。不幸的是,在12個通過測試的瀏覽器中,只有兩個,即Symbian WebKit和Iris,徹底正確地實現了這三個功能。全部其餘瀏覽器都有或多或少的嚴重問題。

pageX/Y依然是相對於頁面座標,使用的是CSS像素。這是目前三對屬性中最有用的信息,跟桌面同樣。

clientX/Y是相對於visual viewport的座標,使用的是CSS像素單位。這是有道理的,儘管我不徹底肯定它有什麼好處。

screenX/Y是相對於屏幕的,使用的是設備像素單位。固然,固然,這是clientX/Y使用的相同參照物,設備像素是無用的。因此咱們不須要擔憂screenX/Y,它和在桌面同樣毫無用處。

meta viewport

最後,來討論<meta name="viewport' content="width=320">;最開始是蘋果手機的擴展,如今已經在其餘瀏覽器普遍使用。它的意思是調整layout viewport。爲了理解這個操做的必要性,先回退一步。

若是你構建了一個簡單的頁面,而且沒有給任何元素寬度。他們會拉伸到l填充layout viewport。大多數瀏覽器多會縮小使得可以在頁面上顯示整個layout viewport,效果以下圖

全部用戶都會當即放大,這是可行的,但大多數瀏覽器保持元素的寬度不變,這使得文本難以閱讀。

(Android WebKit是一個顯著的例外,它實際上減小了包含文本的元素的大小,使它們適合顯示在屏幕上。這很是棒,我以爲全部其餘瀏覽器都應該複製這種行爲。稍後我會詳細記錄下來。)

如今,你設置<html>的寬度width:320px。如今,<html>元素縮小了,全部其餘元素也縮小了,它們如今佔用了320px的100%。這在用戶放大時有效,但在最初,當用戶面對一個放大後的頁面,整個頁面大包含大部分空白。

爲了解決這個問題,蘋果發明了meta viewport標籤。當您設置<meta name="viewport" content="width=320">時,您將佈局viewport的寬度設置爲320px。如今頁面的初始狀態也是正確的。

你能夠設置layout viewport爲任何值,能夠是device-width。device-width採用screen.width做爲參考,而且能夠響應調整layout viewport。

不過這裏有個陷阱。有時候screen.width沒有多大意義,覺得像素值過高了。好比,Nexus One的正式寬度爲480px,可是谷歌的工程師認爲,當使用device-width時,將layout viewport的寬度設置爲480px實在是太大了。他們縮小它至三分之二。因此device-width變爲320px,就像在iPhone上同樣。

若是真的像傳言的那樣,新款iPhone的像素會更大(這並不必定意味着屏幕更大!)也許最終設備的寬度就是320像素。

結論

結論其實和桌面瀏覽器差很少,可是因爲移動瀏覽器對於許多屬性對沒有徹底支持,移動設備有不少種,使得在移動設備上實現良好的佈局比較不容易。

  • screen.width/height,設備的屏幕尺寸。

  • window.innerWidth/Height,包含滾動條尺寸的瀏覽器完整尺寸。

  • document.documentElement.clientWidth/Height,viewport 的尺寸。

  • document.documentElement.offsetWidth/Height<html>的尺寸。

  • window.pageX/YOffset,頁面的移位。

  • window.pageX/Y,從<html>原點到事件觸發點距離。

  • window.clientX/Y,從 viewport 原點(瀏覽器窗口)到事件觸發點的距離。

  • window.screenX/Y,從用戶顯示器窗口原點到事件觸發點的距離。

參考

  1. 原文
相關文章
相關標籤/搜索