有兩篇翻譯過來的博客值得一看:css
兩個viewport的故事(第一部分)
兩個viewport的故事(第二部分)html
這兩篇博客探討了一些基本概念。瀏覽器
它們是顯示器的屬性,而不是瀏覽器的。框架
window.pageXOffset和window.pageYOffset,包含了文檔水平和垂直方向的滾動距離。因此你能夠知道用戶已經滾動了多少距離。ide
window.innerWidth/Height是以CSS像素進行度量的。當用戶放大的時候這個數值會減小。因此若是用戶進行放大操做,那麼在窗口中你能獲取的空間將會變少,window.innerWidth/Height的值也變小了。佈局
viewport的尺寸能夠經過document.documentElement.clientWidth和-Height獲得。學習
document.documentElement實際上指的是元素:即任何HTML文檔的根元素。能夠說,viewport要比它更高一層;它是包含元素的元素。
在這種狀況下document.documentElement.clientWidth和-Height給出的仍然是viewport的尺寸,而不是元素的。(這是一個特殊的規則,只對這個元素的這個屬性對產生做用。在任何其餘的狀況下,使用的是元素的實際寬度。)
因此document.documentElement.clientWidth和-Height一直表明的是viewport的尺寸,無論元素的尺寸是多少。測試
可是難道viewport寬度的尺寸也能夠經過window.innerWidth/Height來提供嗎?怎麼說呢,模棱兩可。.net
兩個屬性對之間存在着正式區別:document.documentElement.clientWidth和-Height並不包含滾動條,可是window.innerWidth/Height包含。這像是雞蛋裏挑骨頭。翻譯
事實上兩個屬性對的存在是瀏覽器戰爭的產物。當時Netscape只支持window.innerWidth/Height,IE只支持document.documentElement.clientWidth和Height。從那時起全部其餘瀏覽器開始支持clientWidth/Height,可是IE沒有支持window.innerWidth/Height。
瀏覽器錯誤:IE不支持pageX/Y。IE和Opera以CSS像素爲單位計算screenX/Y。
當一個鼠標事件發生時,有很多於五種屬性對能夠給你提供關於事件位置的信息。對於咱們當前的討論來講它們當中的三種是重要的:
pageX/Y提供了相對於元素的以CSS像素度量的座標。
clientX/Y提供了相對於viewport的以CSS像素度量的座標。
screenX/Y提供了相對於屏幕的以設備像素進行度量的座標。
90%的時間你將會使用pageX/Y;一般狀況下你想知道的是相對於文檔的事件座標。其餘的10%時間你將會使用clientX/Y。你永遠不須要知道事件相對於屏幕的座標。
意義:見正文。
度量單位:見正文。
瀏覽器錯誤:IE不支持它們。
若是 device-width/height是以CSS像素進行度量的,那麼Firefox將會使用screen.width/height的值。
若是width/height是以設備像素進行度量的,那麼Safari和Chrome將會使用documentElement.clientWidth/Height的值。
最後,說說關於媒體查詢的事。原理很簡單:你能夠聲明「只在頁面寬度大於,等於或者小於一個特定尺寸的時候纔會被執行」的特殊的CSS規則。好比:
div.sidebar { width: 300px; } @media all and (max-width: 400px) { // styles assigned when width is smaller than 400px; div.sidebar { width: 100px; } }
當前sidebar是300px寬,除了當寬度小於400px的時候,在那種狀況下sidebar變得100px寬。
問題很顯然:咱們這兒度量的是哪一個寬度?
這兒有兩個對應的媒體查詢:width/height和device-width/device-height。
width/height使用和documentElement .clientWidth/Height(換句話說就是viewport寬高)同樣的值。它是工做在CSS像素下的。
device-width/device-height使用和screen.width/height(換句話說就是屏幕的寬高)同樣的值。它工做在設備像素下面。
你應該使用哪一個?這還用想?固然是width。Web開發者對設備寬度不感興趣;這個是瀏覽器窗口的寬度。
因此在桌面環境下去使用width而去忘記device-width吧。咱們即將看到這個狀況在移動端會更加麻煩。
viewport太窄了,以致於不能正常展現你的CSS佈局。明顯的解決方案是使viewport變寬一些。不管如何,須要把它分紅兩部分:visual viewport和layout viewport。
George Cummins在Stack Overflow上對基本概念給出了最佳解釋:
把layout viewport想像成爲一張不會變動大小或者形狀的大圖。如今想像你有一個小一些的框架,你經過它來看這張大圖。(譯者:能夠理解爲「管中窺豹」)這個小框架的周圍被不透明的材料所環繞,這掩蓋了你全部的視線,只留這張大圖的一部分給你。你經過這個框架所能看到的大圖的部分就是visual viewport。當你保持框架(縮小)來看整個圖片的時候,你能夠不用管大圖,或者你能夠靠近一些(放大)只看局部。你也能夠改變框架的方向,可是大圖(layout viewport)的大小和形狀永遠不會變。
也看一下Chris給出的解釋:
visual viewport是頁面當前顯示在屏幕上的部分。用戶能夠經過滾動來改變他所看到的頁面的部分,或者經過縮放來改變visual viewport的大小。
像桌面環境同樣,screen.width/height提供了以設備像素爲單位的屏幕尺寸。像在桌面環境上同樣,作爲一個開發者你永遠不須要這個信息。你對屏幕的物理尺寸不感興趣,而是對屏幕上當前有多少CSS像素感興趣。
你還需知道的是visual viewport當前相對於layout viewport的位置。這是滾動距離,而且就像在桌面同樣,它被存儲在window.pageX/YOffset之中。
<html>
元素的總體尺寸。就像在桌面上同樣,document.documentElement.offsetWidth/Height提供了以CSS像素爲單位的元素的整個尺寸。
媒體查詢和其在桌面環境上的工做方式同樣。width/height使用layout viewport作爲參照物,而且以CSS像素進行度量,device-width/height使用設備屏幕,而且以設備像素(??不是很理解)進行度量。
換句話說,width/height是document.documentElement.clientWidth/Height值的鏡像,同時device-width/height是screen.width/height值的鏡像。(它們在全部瀏覽器中實際上就是這麼作的,即便這個鏡像的值不正確。)
這裏的事件座標與其在桌面環境上的工做方式差很少。不幸的是,在十二個測試過的瀏覽器中只有Symbian WebKit和Iris這兩個瀏覽器能獲取到三個徹底正確的值。其餘全部瀏覽器都或多或少有些嚴重的問題。