动态

详情 返回 返回

viewport深入理解和使用 - 动态 详情

什麼是viewport ?

viewport是用户網頁的可視區域,也可叫做視區。手機瀏覽器是把頁面放在一個虛擬的窗口(viewport)中,通常這個虛擬的窗口比屏幕寬,這樣就不用把網頁擠到很小的窗口中,用户可以通過平移和縮放來看網頁的不同部分。

下圖為常見一些設備瀏覽器默認viewport寬度:

css中的1px不等於設備的1px

在css中經常使用px做單位,PC端瀏覽器中的1px往往都是對應電腦屏幕的1個物理像素,這救我讓我們誤以為1px就是一個物理像素,事實並非如此,在不同設備不同環境下,css的1px所代表的設備物理像素是不同的。用户縮放也會影響。如果把頁面放大一倍,那麼css1px所代表的物理像素也會增加一倍,反之,也會縮小一倍。

移動端瀏覽器中,window對象有devicePixelRadio屬性,官方定為為:設備物理像素和獨立像素的比例。

devicePixelRadio = 物理像素 / 獨立像素

css中的px就可以看作獨立像素。

學習viewport的具體用法之前,先搞清楚幾個概念:

  layout viewport:是網頁的所有內容,可以全部或者部分展示給用户。

  可通過 document.documentElement.clientWidth來獲取

  visual viewport:當前顯示給用户內容的窗口,可以拖動或者放大縮小網頁。

  可通過 window.innerWidth 來獲取。

  ideal viewport: 移動設備的屏幕寬度。

          ideal viewport並沒有一個固定尺寸,所有的iphone的ideal viewport寬度都是320px,也就是css中的320px就代表iphone屏幕的寬度。但是安卓手機機型較多,有320px、360px、384px等,所以各個設備ideal viewport不同。       

設置viewport

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

該meta的作用是讓當前viewport的寬度等於設備的寬度,不允許用户手動縮放。

分別對meta的各個屬性介紹如下:

屬性 意義
width 設置viewport的寬度,為一個正整數,或字符串‘device-width’
initial-scale 設置頁面的初始縮放值,是一個數字,可以是小數
maximum-sacle 設置頁面最大縮放值,是一個數字,可以是小數
user-scalable 是否允許用户進行縮放,值為'yes'或者'no',yes表示可縮放,no表示禁止縮放
minimum-scale 允許用户縮放的最小值,是一個數字,可以是小數
height 設置layout viewport的高度,這個屬性很少使用
target-densitydpi 它表示目標設備的密度等級,決定css中1px代表多少物理像素。

這些屬性可以同時使用,使用時用逗號隔開,也可以單獨使用。

此外,安卓手機還支持target-densitydpi 這個私有屬性,它表示目標設備的密度等級,決定css中1px代表多少物理像素。

target-densitydpi值可以為數值或 high-dpi、medium-dpi、low-dpi、device-dpi這幾個字符中的一個
target-densitydpi = device-dpi時,css的1px就等於物理像素1px。由於只有安卓支持,所以我們儘量避免使用它,作為了解就好了。

縮放原理

縮放是相對於ideal viewport來縮放的,縮放值越大,當前viewport的寬度就會越小,反之亦然。

舉例:在iphone中,如果我們設置 initial-scale = 2 ,也就是默認放大2倍,此時viewport就縮小了2倍變成了160px。就是原來的1px變成了2px的長度,放大之後原來需要320px才能填滿的寬度,現在只需要160px就可以做到。因此我們可以得出一個公式:

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

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

ps: visual viewport的寬度指的是瀏覽器可視區域的寬度。

大多數瀏覽器都符合這個理論,但是安卓上的原生瀏覽器以及IE有些問題。安卓自帶的webkit瀏覽器只有在 initial-scale = 1 以及沒有設置width屬性時才是表現正常的,也就相當於這理論在它身上基本沒用;而IE則根本不甩initial-scale這個屬性,無論你給他設置什麼,initial-scale表現出來的效果永遠是1。

好了,現在再來説下initial-scale的默認值問題,就是不寫這個屬性的時候,它的默認值會是多少呢?很顯然不會是1,因為當 initial-scale = 1 時,當前的layout viewport寬度會被設為 ideal viewport的寬度,但前面説了,各瀏覽器默認的 layout viewport寬度一般都是980啊,1024啊,800啊等等這些個值,沒有一開始就是 ideal viewport的寬度的,所以 initial-scale的默認值肯定不是1。安卓設備上的initial-scale默認值好像沒有方法能夠得到,或者就是乾脆它就沒有默認值,一定要你顯示的寫出來這個東西才會起作用,我們不管它了,這裏我們重點説一下iphone和ipad上的initial-scale默認值。

根據測試,我們可以在iphone和ipad上得到一個結論,就是無論你給layout viewpor設置的寬度是多少,而又沒有指定初始的縮放值的話,那麼iphone和ipad會自動計算initial-scale這個值,以保證當前layout viewport的寬度在縮放後就是瀏覽器可視區域的寬度,也就是説不會出現橫向滾動條。比如説,在iphone上,我們不設置任何的viewport meta標籤,此時layout viewport的寬度為980px,但我們可以看到瀏覽器並沒有出現橫向滾動條,瀏覽器默認的把頁面縮小了。根據上面的公式,當前縮放值 = ideal viewport寬度 / visual viewport寬度,我們可以得出:

當前縮放值 = 320 / 980
也就是當前的initial-scale默認值應該是 0.33這樣子。當你指定了initial-scale的值後,這個默認值就不起作用了。

總之記住這個結論就行了:在iphone和ipad上,無論你給viewport設的寬的是多少,如果沒有指定默認的縮放值,則iphone和ipad會自動計算這個縮放值,以達到當前頁面不會出現橫向滾動條(或者説viewport的寬度就是屏幕的寬度)的目的。

動態修改

方法1:使用document.write動態輸出meta標籤

document.write('<meta name="viewport" content="width=device-width,initial-scale=1">')
方法2:通過setAttribute來改變

<meta id="testViewport" name="viewport" content="width = 380">
<script>
 var mvp = document.getElementById('testViewport');
 mvp.setAttribute('content','width=480');
</script>

説了那麼多廢話,最後還是有必要總結一點有用的出來。

第一:如果不設置meta viewport標籤,那麼移動設備上瀏覽器默認的寬度值為800px,980px,1024px等這些,總之是大於屏幕寬度的。這裏的寬度所用的單位px都是指css中的px,它跟代表實際屏幕物理像素的px不是一回事。

第二:每個移動設備瀏覽器中都有一個理想的寬度,這個理想的寬度是指css中的寬度,跟設備的物理寬度沒有關係,在css中,這個寬度就相當於100%的所代表的那個寬度。我們可以用meta標籤把viewport的寬度設為那個理想的寬度,如果不知道這個設備的理想寬度是多少,那麼用device-width這個特殊值就行了,同時initial-scale=1也有把viewport的寬度設為理想寬度的作用。所以,我們可以使用

<meta name="viewport" content="width=device-width, initial-scale=1">

來得到一個理想的viewport(也就是前面説的ideal viewport)。

為什麼需要有理想的viewport呢?比如一個分辨率為320x480的手機理想viewport的寬度是320px,而另一個屏幕尺寸相同但分辨率為640x960的手機的理想viewport寬度也是為320px,那為什麼分辨率大的這個手機的理想寬度要跟分辨率小的那個手機的理想寬度一樣呢?這是因為,只有這樣才能保證同樣的網站在不同分辨率的設備上看起來都是一樣或差不多的。實際上,現在市面上雖然有那麼多不同種類不同品牌不同分辨率的手機,但它們的理想viewport寬度歸納起來無非也就 320、360、384、400等幾種,都是非常接近的,理想寬度的相近也就意味着我們針對某個設備的理想viewport而做出的網站,在其他設備上的表現也不會相差非常多甚至是表現一樣的。

user avatar haoqidewukong 头像 aqiongbei 头像 thosefree 头像 febobo 头像 woniuseo 头像 imba97 头像 yuzhihui 头像 ccVue 头像 wmbuke 头像 yixiyidong 头像 weidewei 头像 kitty-38 头像
点赞 115 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.