了解viewport與device-width
時間 2014-04-08 17:39:22 Alex Chao 原文 http://www.xiaocaoge.com/understanding-viewport-and-device-width.html
在響應式設計或移動Web開發當中經常見到的一句代碼:
content屬性還包括initial-scale,user-scalable等,不過這裡不談,它們的意思都很容易了解。這裡要談得是:viewport代表什麼?device-width又是啥?
先來了解兩個概念:device pixels與CSS pixels。
device pixels指裝置的實體像素,在PC端就是你在作業系統裡設定的螢幕分辨率y,其值可以通過
screen.width/screen.height
擷取。在移動端下面再說。
CSS pixels指在CSS檔案中設定的字型大小、元素寬度等,如
font-size: 14px;
width: 100px;
。在PC端,浏覽器縮放比例為100%,也即預設情況下,1 CSS pixel = 1 device pixel。
當你放大頁面到200%時,字型大小與元素寬度的像素值不會改變,是因為這些像素值是用CSS pixels表示的,實際上放大的是CSS pixels,此時 1 CSS pixel = 4 device pixels,高和寬都是200%。此時你擷取
screen.width/screen.height
的值,并沒有變化,而
window.innerWidth
和
window.innerHeight
的值變成了原來一半,是因為
window.innerWidth/window.innerHeight
的值也是用CSS pixels來表示的。
當你進行流式布局時,會用百分比設定元素的寬度,比如一個塊級元素寬度為10%,那麼你也知道10%實際上是父級元素寬度的10%。但是你并沒有設定父級元素的寬度啊,好吧,你也知道父級元素的寬度與其父級元素寬度一樣(通過繼承得來,假設這些元素都是塊級元素)。然後向上到body元素的寬度,最終為html元素的寬度,其值可以通過
document.documentElement.clientWidth
擷取。那這個寬度怎麼來得呢?
Viewport
viewport,翻譯為視口,也即可視區域的大小,PC端通過
window.innerWidth
window.innerHeight
擷取。
html元素也即文檔的寬度,來自于viewport的寬度,在PC端要加上滾動條的寬度才會與viewport的寬度一樣。是以,文檔的寬度最終來自于viewport的寬度,PC端通過
window.innerWidth
擷取。
而在移動端,情況将變得複雜。
首先,上面提到文檔的寬度來自于viewport的寬度,我們把這個viewport稱為layout viewport,因為它和布局有關。在手機上面,因為手機的螢幕很小,當初iphone釋出時,為了顯示完整的桌面網頁,就把給layout viewport設定了一個980px的值。手機上,可以通過
document.documentElement.clientWidth
來擷取,我在安卓手機上測試也是980px。
但是這樣顯示網頁,那網頁的字型、元素都很小,小到打開這樣一個網頁,首先要做的就是放大頁面。為了提高可讀性,Apple允許通meta标簽來設定layout viewport的寬度,也即文章開頭的那行代碼。
但是,device-width又是什麼呢?
第一代iphone的分辨率為320*480,螢幕尺寸為3.5寸。當時把layout viewport設定成與浏覽器寬度一樣(而手機上浏覽器寬度與手機螢幕寬度一樣)時,不用每次打開網頁放大了,而且顯示的字型與桌面上差不多,可讀性很好。是以就定義了一個device-width,即是手機的螢幕分辨率,此時device翻譯為“裝置”還合适。
但是第二代iphone釋出時,螢幕的分辨率變成了480*960,而螢幕尺寸仍然為3.5寸,如果device-width仍然為手機的螢幕分辨率寬度,那麼字型将會比第一代小很多。是以,維持device-width的值不變将會是個很好得選擇,能與前面相容。也是以,iphone上的device-width的值一直為320,隻不過device再表示“裝置”已經不合适了,實際上代表的是一個中間層。而Android也采用了這一概念,其device-width的值為360的多,360=540/1.5,360=720/2。
如何擷取device-width的值呢?
浏覽器并沒有提供一個擷取device-width的屬性或方法,但是通過
window.innerWidth
可以擷取,需要注意的是,必須添加文章開頭那行代碼才可以跨浏覽器擷取。如果不添加那行代碼,我自己在HTC G18/ Andoird OS 4.0.3中測試,自帶浏覽器/UC9.6/QQ5.0可以擷取,而在Chrome33和Opera20中通過screen.width可以擷取。iPhone與iPad我沒測試。這是測試網頁位址:
http://www.xiaocaoge.com/demo/viewport-screen-device-width-mobile.html 。
Chrome與Opera比較深入實作了中間層的概念,螢幕的實際分辨率與Web開發關系并不大,Chrome與Opera就将
screen.width
傳回中間層的寬度。這裡我也不明白哪種設計更好些。
這裡 有個連結 可以檢視各種手機型号的device-width/device-height大小,雖然連結稱為viewport size。
參考資源:
- A tale of two viewports – part one: http://www.quirksmode.org/mobile/viewports.html
- A tale of two viewports – part two: http://www.quirksmode.org/mobile/viewports2.html
- (上面譯文) 兩個viewport的故事 – 第一篇: http://weizhifeng.net/viewports.html
- 兩個viewport的故事 – 第二篇: http://weizhifeng.net/viewports2.html
- Using the viewport meta tag to control layout on mobile browsers: https://developer.mozilla.org/en-US/docs/Mozilla/Mobile/Viewport_meta_tag
- An introduction to meta viewport and viewport: http://dev.opera.com/articles/view/an-introduction-to-meta-viewport-and-viewport/
- 什麼事viewport,為什麼需要viewport: http://zhanchaojiang.iteye.com/blog/1470586