在這個系列文章中,我將說明viewports和重要元素的寬度是如何工做的,好比<html>
元素、window和 scrren的寬度。css
這篇文章是關於桌面瀏覽器的,目的是爲介紹移動瀏覽器作好準備。大部分的web開發者已經對桌面瀏覽器的一些概念很熟悉了。在移動瀏覽器上咱們會發現一樣的概念,只不過要更復雜一些,回顧一下這些熟悉的概念將對咱們理解移動瀏覽器有很大的幫助。
<!-- more -->html
你須要理解的第一個概念是css像素和設備像素之間的區別。web
設備像素,顧名思義,不管你用什麼設備,設備像素都是表示設備的實際分辨率。設備像素能夠從screen.width/height
讀取。數據庫
若是你給一個元素widht:128px
,你的顯示器是1024px寬,你最大化你的瀏覽器,這個元素能夠在屏幕上平鋪8個。(大概;忽略一些不肯定因素)瀏覽器
若是用戶縮放了頁面,這個值將發生改變。若是用戶放大瀏覽器到200%,你的128px的元素只能在屏幕上平鋪4個了。dom
用戶縮放在瀏覽器中是經過拉伸像素實現的。也就是說,元素的寬度並無從128px變成256px,而是像素的尺寸變成了原來的兩倍。綜上,這個元素仍舊有128px的css像素,可是此時它卻佔有256px的設備像素。ide
換句話說,放到到200%使一個css像素尺寸了變成了4倍的設備像素的尺寸。(兩倍的寬,兩倍的高)。佈局
下面幾個圖片能夠很清楚的說明這個概念。第一個是縮放爲100%,這個沒什麼可看的。css像素徹底覆蓋了設備像素。網站
如今咱們縮小頁面。css像素開始縮小,意味着一個設備像素能夠覆蓋若干個css像素。ui
若是你放大,相反的事情就發生了。css像素開始變大,如今一個css像素能夠覆蓋若干個設備像素
關鍵點在於你只須要關係css像素,它決定你的樣式如何渲染。
設備像素對於你來講幾乎是無用的。對用戶來講不是,用戶會縮放頁面直到頁面看起來舒服位置。可是這個縮放比對你來講不重要,瀏覽器會自動根據縮放比來縮小或者放大的你的css像素。
我上面提到的例子,前提是100%的縮放。如今能夠更嚴格的定義一下:
在100%縮放的狀況下,css像素和設備像素是嚴格相等的。
這100%縮放的概念在咱們的這個解釋中是很是有用的,可是咱們在平常開發中不須要過分擔憂這個。在桌面瀏覽器開發中一般你都是在100%縮放的狀況下,即便用戶縮放頁面,css像素的原理也能保證你的佈局保持比例,不能打亂。
讓咱們來看一下實際的尺寸吧。咱們從screen.width
和screen.height
開始。他們表示用戶屏幕的總寬度和總高度。他們的單位是設備像素,由於它們歷來不會改變:它們是顯示器的特性,不是瀏覽器的特性。
頗有意思!可是咱們能用這個信息作什麼那?
基本沒有用。用戶的顯示器尺寸對咱們來講不重要,除非你想作一個web資料數據庫。
相反,你關心的是瀏覽器窗口的內部尺寸是什麼。那會告訴你用於展現你的css佈局的空間是多大。你能夠經過window.innerWidth
和window.innerHeight
來獲取。
很明顯,窗口的內部寬度的單位是css像素。你須要知道的是你的css佈局有多少能夠呈如今瀏覽器窗口中,並且這個呈現的數量會隨着用戶放大頁面而減小(css像素越大,所呈現的內容越少)。所以若是用戶放大頁面,你可用的空間也就越少,在window.innerWidth/Height
反應爲值減少。
注意!這個寬度和高度包括滾動條。滾動條也被認爲是瀏覽器窗口的一部分。(這個有歷史的緣由)
window.pageXOffset
和window.pageYOffset
,表示document橫向和縱向的滾動偏移。經過這兩個屬性,你能夠知道用戶滾動的位置。
這兩個屬性的單位也是css像素。理論上,若是用戶向上滾動而後放大,window.pageX/YOffset
應該發生改變。可是瀏覽器作了一些處理,在用戶縮放的時候,瀏覽器試圖使同一個元素保持在瀏覽器窗口的頂部來使頁面看起來不會跳動。這意味着window.pageX/YOffset
在用戶縮放的時候不會改變:被滾動出屏幕的css像素數不會改變。
在咱們繼續介紹更多的js屬性以前,咱們必須介紹另一個概念:viewport。
viewport的做用是限制<html>
元素,是網站的最頂級的塊級元素。
這聽起來或許有一點模糊,咱們來舉一個實際的例子。假設你有一個流體佈局,你的側邊欄是width:10%
.當你調整瀏覽器的大小時,側邊欄隨着增大或減少。那它究竟是怎麼工做的那?
從技術上說,側邊欄在獲取它父元素的寬度的10%的時候發生了什麼。咱們假定<body>
元素爲父元素。因此如今問題變成了<body>
元素(你沒有給<body>
賦寬度)的寬度是多少。
一般來講,全部的塊級元素的寬度都是父元素的寬度的100%。所以<body>
元素是和它的父元素<html>
同樣寬的。
如今<html>
元素的寬度是多少那?爲何它和瀏覽器同樣寬。這也是爲何你的width:10%
的側邊欄佔整個瀏覽器寬度的10%的緣由。全部的web開發者都知道這個事實。
你或許不知道這其中的工做原理。理論上,html元素的寬度是被viewport的寬度限制的。html元素等於viewport的寬度。
viewport和瀏覽器窗口相等的:它就是這麼被定義的。viewport不是一個HTML結構,因此你不能靠css影響它。它就是有瀏覽器窗口的寬度和高度(桌面);在移動瀏覽器上它是比較複雜的。
這些東西有時候會有一些奇怪的結果。你能這個網站(http://www.quirksmode.org/mob...。滾動到最頂部,而後放大頁面2到3倍,使頁面內容溢出瀏覽器窗口。
如今滾動到最右邊,你將會看到頂部的藍色欄再也不被正確的排列。
這個行爲是viewport被定義的方式致使的。我給了藍色頂部欄一個width:100%
.什麼的100%?html元素的100%。<html>
元素和viewport是等寬的,因此和瀏覽器窗口也是等寬的。
重點是:在100%縮放時,它是正常的,如今咱們放大頁面,致使viewport變的比咱們頁面的總寬度小。對於它本身來講這不重要,頁面的內容溢出了html元素,可是html元素是[overflow](http://www.quirksmode.org/css/overflow.html): visible
,這就意味着超出的元素會被顯示。
可是藍色頂部欄沒有溢出。我給了它width:100%,瀏覽器會給它一個viewport的寬度。他們不關心如今的寬度過小了。
我真正想知道的是頁面內容的總寬度是多少,包括突出的部分。據我所知,瀏覽器並未提供這個值。
我開始相信咱們須要一個js屬性對來表示我稱做"document width"的值。
若是咱們真是以爲這樣不爽,爲何不把document width的值暴露給css那?我但願藍色頂部欄繼承document寬度,而不是html元素的寬度。(這個確實有些棘手,若是不可能實現我也不會以爲驚訝)
瀏覽器廠商,大家怎麼認爲那?
你或許想要知道viewport的尺寸。他們能夠經過document.documentElement.clientWidth/clientHeight
來獲取.
若是你瞭解dom結構,你就知道document.documentElement
實際上是<html>
元素:<html>
文檔的根元素。然而,viewport是更高一級的,能夠說它是包含<html>
元素的元素。若是你給了<html>
元素一個寬度,那就變得比較重要了(不推薦這樣作,可是這是能夠的)。即便在這種狀況下,document.documentElement.clientWidth/clientHeight
仍舊給出的是viewport的尺寸,而不是html的尺寸。(這是一個只對這個元素和這個屬性對起做用的特例。其餘狀況下clientWidth/clientHeight
都是取元素的真實尺寸)。
所以document.documentElement.clientWidth/clientHeight
老是給出viewport的尺寸,無視html的尺寸。
那麼viewport的尺寸是否是也能夠由window.innerWidth/Height
給出。答案是也不是。
這兩對屬性值的惟一區別在於,window.innerWidth/Height
包括滾動條的寬度,document.documentElement.clientWidth/clientHeight
不包括。
咱們之因此有兩對屬性是瀏覽器大戰的產物。當時Netscape只支持window.innerWidth/Height
,而IE只支持document.documentElement.clientWidth/clientHeight
。當全部其餘瀏覽器開始支持document.documentElement.clientWidth/clientHeight
的時候,IE仍舊不支持window.innerWidth/Height
.在桌面瀏覽器上有兩個屬性對是一個煩人的事情,可是在移動瀏覽器上它是一個福音。
document.documentElement.clientWidth/clientHeight
在全部的狀況下都給出的是viewport的尺寸。那麼咱們從哪裏獲取html元素自身的寬和高那?他們被存在document.documentElement.offsetWidth/offsetHeight
裏。
這兩個屬性真地給了你一個訪問<html>
元素做爲塊級元素的接口。若是你設置width
或者offsetWidth
將會影響這兩個屬性。
有一些事件座標值。當一個鼠標事件發生時,很多於5對屬性值會被暴露出來給你事件發生的具體位置信息。其中3對是對咱們的討論來講重要的:
1. pageX/Y給出相對於html元素的座標,單位是css像素 2. clientX/Y給出相對於viewport的座標,單位是css像素 3. screenX/Y給出相對於屏幕的座標,單位是設備像素
pageX/Y
clientX/Y
screenX/Y
你90%的狀況下都會使用pageX/Y
;一般你想要知道相對於document的位置。其餘的10%你想要用clientX/Y
.你基本不須要知道相對於屏幕的尺寸。
最後,說一些媒體查詢。這個思想很簡單:你能夠指定在頁面在不一樣條件下運行不一樣的css,好比頁面寬度大於、等於、小於某個尺寸的時候。
div.sidebar{ width:30%; } @media all and (max-width:400px) { //styles assigned when width is smaller than 400px; div.sidebar { width: 100px; } }
如今這個sidebar在寬度大於400px的時候寬300px,小於等於400px的時候寬100px;
問題是哪一個寬度和400px比較?
有兩個相關的媒體查詢:width/height
和 device-width/device-height
.
1. `width/height`用的是`documentElement.clientWidth/height`(就是viewport)。單位是css像素。 2. `device-width/device-height`用的是`screen.width/height`.單位是設備像素。
應該用哪一個寬度?想都不用想,固然是width
。web開發者對設備寬度不感興趣,只是對瀏覽器窗口的寬度感興趣。
在桌面瀏覽器上使用width
,忘記device-width
.正如咱們所看到的,這在移動設備上是更復雜的。
這篇文章總結了咱們對桌面瀏覽器的探索。第二篇文章將介紹這些概念在移動瀏覽器的應用,並重點說明和桌面瀏覽器的不一樣。