淺談移動端三大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)² *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重疊

Viewport剖析

當我們縮小瀏覽器時,CSS的pixels開始收縮,導致1單位的設備的pixels上重疊了多個CSS的pixels,如圖1-2

Viewport剖析

同理,放大瀏覽器時,相反的事情發生了,CSS的pixels開始擴大,導致1單位的CSS的pixels上重疊了多個設備的pixels,如圖1-3

Viewport剖析

總體而言,你只需要關注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 {
    ...
  }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM