天天看點

了解viewport與device-width 了解viewport與device-width

了解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

繼續閱讀