pc端和移動端的“窗口”(viewport)故事(part1)


A tale of two viewports — part one

在以下的系列文章中,我將為大家解釋瀏覽器中的視窗和一些重要的元素的尺寸是如何起作用的,如:大家最熟悉的html元素以及window和screen對象。
這篇文章作是本系列的第一部分,是關於台式電腦的瀏覽器的,主要目的是為后續的移動端瀏覽器的討論奠定一個基礎。大部分的web開發者能夠憑直覺理解大部分台式機瀏覽器的概念。在移動端我們也將遇到一樣的概念,不過對於這些人人都知道的概念進行更加復雜和預先的討論將會極大地幫助大家理解移動端瀏覽器。

概念:設備像素和css像素

首先要理解的概念是理解css像素以及與設備像素之間的差異。

設備像素:設備像素是我們直覺上最容易理解的。這些像素是描述了所在設備的分辨率,可以通過screen.width/height來獲取。假定給定一個元素的寬度為width:128px,顯示器寬度是1024px,無縮放的情況下,要8個元素才能填滿整個顯示器。如果用戶縮放到200%,只要4個元素就可以填滿整個顯示器。

現代瀏覽器中的縮放僅僅是拉伸像素。這意味着元素的寬度不會從128px變為256px,而是實際的像素尺寸變成雙倍。元素的寬度仍然為128 css px,即使他占據了256個設備像素的空間。換句話說,縮放到200%使得一個css像素變成4倍的設備像素大小。

下面的圖將解釋這個概念。

(1)無縮放的4像素的圖。css像素與設備像素完全重合 一個css像素等於一個設備像素

(2)縮小 css像素開始收縮,一個設備像素覆蓋多個css像素

(3)放大 css像素開始變大,一個css像素覆蓋多個設備像素

但是我們只關注渲染頁面的css像素。設備像素對於前端工程師來說幾乎沒有什么用處。只有用戶會縮放頁面使得閱讀舒適。瀏覽器會根據你的css樣式去自適應頁面元素的大小以及保持特定的元素比例。

屏幕尺寸

screen.width 和 screen.height分別表示用戶屏幕的寬高。他們都是以設備像素衡量的,因為設備像素是不會改變的,設備像素是顯示器的屬性,與瀏覽器無關。

但是屏幕尺寸對我們來說沒有什么作用,除非你想要建立一個web統計數據庫。

window大小

我們感興趣的是瀏覽器窗口的內部尺寸。這是用戶當前css層可用的實際空間,分別是 window.innerWidth 和 window.innerHeight。

顯然,窗口的內部寬度是用css像素衡量的。當用戶放大的時候,你可以得到更少的窗口空間,window.innerWidth 和window.innerHeight將會變小。
(Opera瀏覽器是個例外, window.innerWidth/Height不會隨着用戶放大而縮小,他們以設備像素衡量。這在台式機中很煩人,在移動端中是致命的)需要注意的是,測量的widths 和 heights是包括滾動條的。

Scrolling offset

window.pageXOffset 和 window.pageYOffset 分別是document的橫向和縱向的滾動距離。

這些也是以css像素衡量的。你可以知道文稿被滾動了多少,不論它是否被縮放。
理論上,如果用戶頁面向上滾動然后放大,window.pageX/YOffset會改變。然而,當用戶縮放時,瀏覽器想要通過使得可見頁面的頂部是同樣的元素來保證網頁的一致性。這通常並不能表現的很好,不過這使得實際的 window.pageX/YOffset 不會發生改變。

concept:viewport

viewport的作用是限制<html>元素,是最高級的塊級容器。html的寬度是受view的寬度限制的,是viewport寬度的100%。
viewport正好等於瀏覽器窗口。

consequences

這樣的限制機制會導致一系列的瀏覽器顯示效果。如下,將屏幕滾動到頂部,然后放大2——3次使得網頁的內容溢出瀏覽器窗口。然后滾動到最右側,此時上面的的藍色條塊布局出現異常。

這就是viewport的定義導致的影響。藍色條的width為100%。相對於什么元素的100%?相對於html元素的話,應該是與viewport等寬,也等於瀏覽器窗口寬度。關鍵的點是這在無縮放的情況下顯示正常,此時放大的頁面的使得viewport小於整個網頁內容的寬度,網頁內容溢出了html元素,但是這個元素是有益溢出的屬性:overflow:visible,這表示溢出的內容不論怎樣都會顯示。但是藍色條沒有溢出。他的寬度為100%,瀏覽器會將它的寬度設為與viewport等寬。

document width?

ducument width表示網頁內容的總寬度,但是沒有這個css屬性。

Measuring the viewport

viewport可以通過document.documentElement.clientWidth 和 -Height得到。

如果你了解dom,就會知道document.documentElement事實上是html元素,它是任何html文檔的根元素。然而,viewport是更高一層的,它包括html元素。如果要給定html元素寬度,將會與viewport有關。在那種情況下,document.documentElement.clientWidth 和 -Height仍然是viewport的尺寸,而不是html元素。(這是viewport一個特殊的屬性,其他的元素都是元素本身的屬性)

因此,document.documentElement.clientWidth 和 -Height總是表示viewport的尺寸,與html元素無關。

Two property pairs

window.innerWidth/Height難道不表示vewport的尺寸么?是,也不是。document.documentElement.clientWidth 和 -Height不包括滾動條,而window.innerWidth/Height包括。這兩個屬性的出現源於瀏覽器大戰。 Netscape僅僅支持 window.innerWidth/Height ,ie僅僅支持document.documentElement.clientWidth and -Height。從此,所有的其他瀏覽器都支持clientWidth/Height,但是ie沒有選擇window.innerWidth/Height。在台式機中,擁有這兩種屬性是不友好的,但是在移動端中應該慶幸。

Measuring the element

因此,clientWidth/Height在任何情況下都表示viewport的尺寸。html的尺寸則用 document.documentElement.offsetWidth 和-Height來表示。如果你設置html的尺寸,offsetwidth等會反應出來。

Event coordinates

1.pageX/Y 表示事件位置相對於html元素的css像素坐標位置。
2.clientX/Y 表示事件位置相對於viewport的css像素坐標位置。
3.screenX/Y 表示事件位置相對於screen的設備像素的坐標位置。

pageX/Y

lientX/Y

screenX/Y

Media queries

最后,是關於媒體查詢,可以定義在不能頁面尺寸下的css樣式。

 div.sidebar {
	width: 300px;
}

@media all and (max-width: 400px) {
	// styles assigned when width is smaller than 400px;
	div.sidebar {
		width: 100px;
	}

}

有兩種相關的媒體查詢: width/height 和 device-width/device-height。
1.width/height 與 documentElement .clientWidth/Height值相等(相對於viewport,css像素);
2.device-width/device-height 相對於screen,與screen.width/height的尺寸一致,是設備像素。

use width and forget device-width — on desktop

Conclusion

以上是關於台式機瀏覽器的一些屬性和特征,關於移動端的見part2.
翻譯原文地址:https://quirksmode.org/mobile/viewports.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM