咱們一般在寫移動端頁面時,每每都會在html頁面中加入這樣一段話css
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
可能咱們只知道這三個字段的含義(視口寬度等於設備寬度,屏幕縮放爲1,禁止用戶縮放),可是爲何要這麼寫,其原理又是什麼呢?html
咱們先看一個簡單的demo吧。ios
<!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模擬),可是隻顯示了三分之一左右。iphone
在回答此問題以前,咱們須要先普及一下一些移動端的概念。佈局
px:邏輯像素優化
dp:設備像素(物理像素)網站
dpr:設備像素縮放比spa
(某一方向上-->計算:dpr = 設備像素/邏輯像素,平面上-->計算:1px = (dpr)² *dp)scala
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.
下列圖片將清楚的解釋這個概念。如圖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,就是手機瀏覽器把頁面放到一個虛擬的窗口中,窗口可大於或小於手機的可視區域,通常會大於可視區域。這樣不會破壞沒有針對手機瀏覽器優化的網頁的佈局,用戶能夠經過平移或縮放來看網頁的其它部分。
這也就是爲何咱們沒寫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(佈局視口)]
好比若是要讓iphone6展現1000px的頁面,只設置"width=device-width",確定都會擠在一塊兒。
因此須要讓縮放比爲1,設置initial-scale=1,因此最終版本是這樣
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
最後總結一下移動端中的三個viewport——
1.佈局視口
document.body.clientWidth 爲手機瀏覽器viewport寬度(佈局viewport),默認980
跟width=device-width相關,其值等於meta標籤中的width
initial-scale = 2 ,它會跟着縮小一倍
當你須要使用js而不是媒體查詢來編寫業務邏輯的時候,這頗有幫助
if(document.body.clientWidth >= 400){
.class{...}
}
等價於
@media all and (max-width>=400){
.class{...}
}
咱們用到的vw,vh尺寸單位表明視口的百分比,好比width:50vh,這裏的視口就是指佈局視口,由於若是是視覺視口,每次用戶縮放都會致使元素狂傲發生變化,先不說這個變化帶來的大計算量,這種設計對用戶來講自己就是毫無心義的。
2.視覺視口
window.innerWidth
屏幕上顯示的網站區域尺寸,會受縮放的影響
3.理想視口
screen.width
它是對設備來講最理想的佈局視口尺寸。
-----------------------------------------------------------------------------------------------------------------------
在手機上,桌面視口被拆分紅兩個——佈局視口限制你的css佈局,視覺視口決定用戶能看到什麼。
其實這麼多的viewport看起來可能會亂一點,但事實並非這樣。最佳實踐就是讓瀏覽器直接使用它的理想視口,即把佈局視口設置爲理想視口,而後使用媒體查詢來響應不一樣的理想視口就OK。
響應式設計的核心—— width和height的媒體查詢設置了當前佈局視口的寬高。 使用最佳mate標籤後,就能夠放心的拋開佈局視口的寬度,只專一於理想視口 @media all and (max-width:400) { .class { ... } }