1. 程式人生 > >viewport其實沒那麼難理解

viewport其實沒那麼難理解

  在學習移動端佈局的時候,你肯定聽說過"viewport"這個詞,然後去問度娘或谷歌。你會驚奇的發現,這個viewport不簡單,居然有那麼多兄弟——layout viewport、visual viewport、ideal viewport。這些都是什麼鬼,然後就硬著頭皮去發現他們的不同,找了很多資料,很想搞懂他們,最後可能是越看越懵逼,或者就豁然開朗的懂了(我是覺得自己豁然開朗的懂了,所以才寫部落格記錄一下感想,不對之處歡迎來噴...)。雖然自己也知道,移動端開發入門沒那麼難,一句程式碼搞定—— <meta id="viewport" name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1; user-scalable=no;"

> 。可是不理解viewport心裡就是不爽,下面我就簡單歸納一下自己的總結。

1、各種瀏覽器預設viewport大小

  為了能在移動裝置上正常顯示那些傳統的為桌面瀏覽器設計的網站,移動裝置上的瀏覽器都會把自己預設的viewport設為980px或1024px(也可能是其它值,這個是由裝置自己決定的),但帶來的後果就是瀏覽器會出現橫向滾動條,因為瀏覽器可視區域的寬度是比這個預設的viewport的寬度要小的。下圖列出了一些裝置上瀏覽器的預設viewport的寬度。 

 2、css的1px不等於裝置物理畫素的1px

   在早先的移動裝置中,螢幕畫素密度都比較低,如iphone3,它的解析度為320x480,在iphone3上,一個css畫素確實是等於一個螢幕物理畫素的。後來隨著技術的發展,移動裝置的螢幕畫素密度越來越高,從iphone4開始,蘋果公司便推出了所謂的Retina屏,解析度提高了一倍,變成640x960,但螢幕尺寸卻沒變化,這就意味著同樣大小的螢幕上,畫素卻多了一倍,這時,一個css畫素是等於兩個物理畫素的。其他品牌的移動裝置也是這個道理。例如安卓裝置根據螢幕畫素密度可分為ldpi、mdpi、hdpi、xhdpi等不同的等級,解析度也是五花八門,安卓裝置上的一個css畫素相當於多少個螢幕物理畫素,也因裝置的不同而不同,沒有一個定論。例如,在Retina屏的iphone上,devicePixelRatio的值為2,也就是說1個css畫素相當於2個物理畫素。

  還有一個因素也會引起css中px的變化,那就是使用者縮放。例如,當用戶把頁面放大一倍,那麼css中1px所代表的物理畫素也會增加一倍;反之把頁面縮小一倍,css中1px所代表的物理畫素也會減少一倍。

3、viewport三兄弟——layout viewport、visual viewport、ideal viewport

  layout viewport由來:如果把移動裝置上瀏覽器的可視區域設為viewport的話,某些網站就會因為viewport太窄而顯示錯亂(相當於resize瀏覽器的視窗變小了,之後div這樣的block標籤預設寬度auto變小了,頁面就會亂),所以這些瀏覽器就決定預設情況下把viewport設為一個較寬的值,比如980px,這樣的話即使是那些為桌面設計的網站也能在移動瀏覽器上正常顯示了。瀏覽器預設的viewport

叫做 layout viewport。這個layout viewport的寬度可以通過 document.documentElement.clientWidth 來獲取。

  visual viewport由來layout viewport的寬度是大於瀏覽器可視區域的寬度的,所以我們還需要一個viewport來代表 瀏覽器可視區域的大小,這個viewport叫做 visual viewport。visual viewport的寬度可以通過window.innerWidth 來獲取。

  其實上面倆張圖還是很有誤導性的。看下面這張圖,沒設定<meta>的情況下,同時,div寬度為auto時:(人家是剛剛好塞滿的,倆種viewport比例1:1)

 

  ideal viewport由來:現在我們已經有兩個viewport了:layout viewport 和 visual viewport。但瀏覽器覺得還不夠,因為現在越來越多的網站都會為移動裝置進行單獨的設計,所以必須還要有一個能完美適配移動裝置的viewport。所謂的完美適配指的是,首先不需要使用者縮放和橫向滾動條就能正常的檢視網站的所有內容;第二,顯示的文字的大小是合適,比如一段14px大小的文字,不會因為在一個高密度畫素的螢幕裡顯示得太小而無法看清,理想的情況是這段14px的文字無論是在何種密度螢幕,何種解析度下,顯示出來的大小都是差不多的。當然,不只是文字,其他元素像圖片什麼的也是這個道理。這個viewport叫做 ideal viewport——移動裝置的理想viewport。  ideal viewport並沒有一個固定的尺寸,不同的裝置擁有有不同的ideal viewport。iphone的ideal viewport寬度有320px、375px..安卓裝置就比較複雜了,有320px的,有360px的,有384px的等等。(不可改變的)

4、meta標籤的作用

  移動裝置預設的viewport是layout viewport,也就是那個比螢幕要寬的viewport,但在進行移動裝置網站的開發時,我們需要的是ideal viewport。那麼怎麼才能得到ideal viewport呢?這就該輪到meta標籤出場了。我們在開發移動裝置的網站時,最常見的的一個動作就是把下面這個東西複製到我們的head標籤中:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">

  該meta標籤的作用是讓當前viewport的寬度等於裝置的寬度,同時不允許使用者手動縮放。也許允不允許使用者縮放不同的網站有不同的要求,但讓viewport的寬度等於裝置的寬度,這個應該是大家都想要的效果,如果你不這樣的設定的話,那就會使用那個比螢幕寬的預設viewport,也就是說會出現橫向滾動條。

  這個name為viewport的meta標籤到底有哪些東西呢,又都有什麼作用呢?

width 設定layout viewport  的寬度,為一個正整數,或字串"width-device"
initial-scale 設定頁面的初始縮放值,為一個數字,可以帶小數
minimum-scale 允許使用者的最小縮放值,為一個數字,可以帶小數
maximum-scale 允許使用者的最大縮放值,為一個數字,可以帶小數
height 設定layout viewport  的高度,這個屬性對我們並不重要,很少使用
user-scalable 是否允許使用者進行縮放,值為"no"或"yes", no 代表不允許,yes代表允許

上面我們說了,layout viewport = document.documentElement.clientWidth、visual viewport = window.innerWidth。由於移動端沒有那個17px的滾動條,所以layout viewport ≈ visual viewport.

 5、關於縮放以及initial-scale的預設值

    1)、initial-scale=1可以達到和width=device-width一樣的效果,因為所有的scale指令都是相對於ideal viewport的。無視layout viewport設定了多少,所以maximum-scale=3意味著最大的縮放值是ideal viewport的300%。

  2)、最後再來看看initial-scale、visual viewport、ideal viewport關係:

當前縮放值 = ideal viewport寬度  / visual viewport寬度

總結:

1、layout viewport和visual viewport關係。

document.documentElement.clientWidth和window.innerWidth的概念必須搞清楚:document.documentElement.clientWidth/Height的值為可視視窗內部大小,不包括工具欄和水平或垂直滾動條。 window.innerWidth/Height的值也是可視視窗內部大小加上滾動條寬度。 

2、meta標籤中,如果設定了width=device-width 也就是將layout viewport(佈局視口)的寬度設定 ideal viewport(理想視口)的寬度。width=device-width和initial-scale=1指令都可以做到。

3、當前縮放值 = ideal viewport寬度 / visual viewport寬度。