淺談viewport
我們通常在寫移動端頁面時,往往都會在html頁面中加入這樣一段話
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
可能我們只知道這三個字段的含義(視口寬度等於設備寬度,屏幕縮放為1,禁止用戶縮放),但是為什麽要這麽寫,其原理又是什麽呢?
我們先看一個簡單的demo吧。
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Test 02</title> </head> <style> body{ margin: 0; } .pic{ width: 320px; height: 568px; background-color: #72DFFF; color: white; font-size: 60px; text-align: center; line-height: 568px; font-family: cursive; } </style> <body> <div class="pic"> 320*568 </div> </body> </html>
該demo展示一個寬度為320px的div,我們在iphone5上面打開看一下。
有沒有感覺很詭異?明明iphone5的分辨率是320px*568px(我使用的是谷歌的mobile模擬),但是只顯示了三分之一左右。
在回答此問題之前,我們需要先普及一下一些移動端的概念。
px:邏輯像素
dp:設備像素(物理像素)
dpr:設備像素縮放比
(某一方向上-->計算:dpr = 設備像素/物理像素,平面上-->計算:1px = (dpr)2 *dp)
ppi:屏幕每英寸的像素數量,即單位英寸內的像素密度(計算:分辨率平方後開跟/屏幕尺寸)
ppi與dpr的關系表
ldpr | mdpr | hdpr | xhdpr | |
ppi | 120 | 160 | 240 | 320 |
默認縮放比 | 0.75 | 1.0 | 1.5 | 2.0 |
我們得知iphone5的尺寸為4英寸,設備分辨率為1136dp*640dp,由此我們可以得出iphone5的分辨率為320px*568px,如下圖(retina為高清)。
該頁面展示三分之一的原因是ios中默認的布局viewport是980px,然後根據剛才的計算的iphone5分辨率才會出現此情況。
邏輯像素(css pixels)與設備像素(device pixels)的區別------------
我們姑且認定設備的pixels為正確(標準)的pixels寬度。這些pixels決定了你工作所用的那些設備上正式的分辨率。
如果用戶縮放(zoom)了瀏覽器,當然必須改變計算方式。
現代瀏覽器上的縮放,是基於“伸展”pixels。結果是,html元素上的寬度並沒有因為縮放200%而由128pix變成256px,而是真實的pixels的被計算成了雙倍。html元素在形式上依然是128CSS的pixels,即便它占用了256設備的pixels 。
換言之,縮放200%將一個單位的CSS的pixels變成了4倍的設備的pixels那麽大,即寬度 * 2、高度 * 2,面積擴大了2 * 2.
下列圖片將清楚的解釋這個概念。如圖1-1.有4個1像素,縮放為100%的html元素,CSS的pixels完整的和設備的pixels重疊
當我們縮小瀏覽器時,CSS的pixels開始收縮,導致1單位的設備的pixels上重疊了多個CSS的pixels,如圖1-2
同理,放大瀏覽器時,相反的事情發生了,CSS的pixels開始擴大,導致1單位的CSS的pixels上重疊了多個設備的pixels,如圖1-3
總體而言,你只需要關註CSS的pixels,這些pixels指定你的樣式被如何渲染。
就像剛開始的那個小demo,在pc以及iphone5上展示是兩種完全不同的效果。
在這裏我普及一個知識點,對於viewport,蘋果手機瀏覽器默認做了兩件事——
1.頁面渲染在一個980px(IOS)的viewport(安卓viewport寬度不固定)
2.縮放
這也就是為什麽我們沒寫viewport,手機會默認將布局寬度置為980px的原因。
為什麽要有viewport?
一個300多像素的屏幕,放一個1000多像素的頁面,會混亂,所以要先虛擬一個980像素的頁面,然後進行縮放。
為什麽不使用默認980px的布局viewport
1.寬度不可控,不同設備(安卓)默認值可能不同
2.頁面縮小版展示,交互不友好
3.有縮放,縮放後有滾動
4.font-size 可能要設置40px才等於pc上12px,不規範
然後為了在iphone5上正常展示,我們需要寫這樣一個viewport
<meta name="viewport" content="width=320">
這樣效果ok,但是如果我們的設備是iphone6,iphone6s呢?
<meta name="viewport" content="width=375">
顯然是不符合規定的,所以我們需要設置
<meta name="viewport" content="width=device-width">
但是每個不同的設備都會有不同的縮放比
window.innerWidth/document.body.clientWidth 為 initial-scale
度量viewport/布局viewport [Layout Viewport(布局視口)]
所以需要讓縮放比為1,設置initial-scale=1,所以最終版本是這樣
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
淺談viewport