一、背景
通俗來(lái)講,css中的1px對(duì)應(yīng)電腦屏幕的1個(gè)物理像素,那么css中的像素就是屏幕的物理像素嗎?這只是一個(gè)錯(cuò)覺(jué),而實(shí)際上css中的px可以理解為一個(gè)抽象單位,在不同設(shè)備中,css的1px表示的物理像素是不一樣的,特別是在移動(dòng)設(shè)備上。
為什么css的px不代表物理像素呢?
理由一:在window對(duì)象中,存在這樣一個(gè)屬性(設(shè)備像素比例),devicePixelRatio=物理像素 / 獨(dú)立像素,定義為:設(shè)備物理像素和獨(dú)立像素的比值。例如,iphone手機(jī)屏幕上,devicePixelRatio=2,那么css中的1px也就是獨(dú)立像素,表示兩個(gè)物理像素;
理由二:頁(yè)面的縮放會(huì)導(dǎo)致css中的px變化,當(dāng)用戶將移動(dòng)端頁(yè)面放大一倍,css中的1px所代表的物理像素也會(huì)放大一倍。
二、viewport
1. layout viewport
a. 前因
理論上,在pc端瀏覽器所顯示的頁(yè)面,在移動(dòng)端的瀏覽器上都應(yīng)該正常顯示;
但是,將viewport作為瀏覽器的可視區(qū)域,移動(dòng)端屏幕是不夠?qū)挼模W(wǎng)頁(yè)的布局必然會(huì)亂掉;
就算是現(xiàn)在的手機(jī)分辨率都很高了,但是屏幕尺寸是沒(méi)有變大很多的,那么屏幕密度就變大了,意味著css的1px代表更多的物理像素,這會(huì)導(dǎo)致css中1px的元素在移動(dòng)端頁(yè)面看起來(lái)很小很小。
b. 后果
默認(rèn)情況下瀏覽器把viewport設(shè)為一個(gè)較寬的值,通常是980px,pc端的網(wǎng)頁(yè)就能在移動(dòng)端正常顯示了,把這個(gè)默認(rèn)的viewport叫做layout viewport,layout viewport就是網(wǎng)頁(yè)的全部?jī)?nèi)容。
layout viewport的寬度可以通過(guò)document.documentElement.clientWidth獲取。

2. visual viewport
既然有了默認(rèn)的viewport(也就是前面提到的layout viewport),layout viewport的寬度會(huì)大于瀏覽器的可視區(qū)域?qū)挾?,那么就?yīng)該有一個(gè)代表可視區(qū)域的寬度,把這個(gè)可視區(qū)域的viewport叫做visual viewport,visual viewport是用戶能看到的內(nèi)容窗口,可以縮放和滾動(dòng)。
visual viewport的寬度可以通過(guò)window.innerWidth來(lái)獲取。

3. ideal viewport
雖然有了layout viewport和visual viewport,但瀏覽器覺(jué)得這是不夠的,想要在任何分辨率的屏幕下,不需要用戶手動(dòng)縮放、手動(dòng)滾動(dòng),就可以完美的展示頁(yè)面;
把移動(dòng)設(shè)備的理想viewport叫做ideal viewport,無(wú)論在什么樣的設(shè)備上,都能匹配出完美、合適的文字大小以及圖片大小。
所有的iphone的ideal viewport寬度都是320px。
三、meta標(biāo)簽
1. meta標(biāo)簽的作用:
- meta里的數(shù)據(jù)告訴瀏覽器如何解析頁(yè)面;
- 可以發(fā)送數(shù)據(jù)到http請(qǐng)求的headers里面。
2. 如何利用meta來(lái)得到一個(gè)理想的viewport
- meta標(biāo)簽可以用來(lái)設(shè)置viewport,移動(dòng)端的viewport默認(rèn)是layout viewport,利用meta標(biāo)簽來(lái)實(shí)現(xiàn)ideal viewport的效果;
- meta viewport常用屬性:
| 屬性名 | 作用 |
|---|---|
| width | 設(shè)置layout viewport 的寬度,為一個(gè)正整數(shù),可以用字符串”device-width”表示設(shè)備寬度 |
| initial-scale | 設(shè)置頁(yè)面的初始縮放值,為一個(gè)數(shù)字,可以帶小數(shù) |
| minimum-scale | 允許用戶的最小縮放值,為一個(gè)數(shù)字,可以帶小數(shù) |
| maximum-scale | 允許用戶的最大縮放值,為一個(gè)數(shù)字,可以帶小數(shù) |
| height | 設(shè)置layout viewport 的高度,很少使用,因?yàn)闀?huì)隨著width屬性自動(dòng)調(diào)整 |
| user-scalable | 是否允許用戶進(jìn)行縮放,值為”no”或”yes”, no 代表不允許,yes代表允許 |
- 目前被認(rèn)為最有效寫法是:
<meta name="viewport" content="width=device-width, initial-scale=1">,分析:- 想要得到ideal viewport,首先想到是的屏幕寬度設(shè)置,把默認(rèn)的layout viewport寬度設(shè)為移動(dòng)設(shè)備的寬度,即
<meta name="viewport" content="width=device-width">,就能把當(dāng)前viewport的寬度變?yōu)槔硐氲?strong>ideal viewport寬度。但這樣做有一個(gè)缺陷,在iphone或者ipad上,不管當(dāng)屏幕變?yōu)闄M屏還是者豎屏?xí)r,寬度都是即定的豎屏?xí)rideal viewport的寬度; - 其實(shí)以上效果這樣寫也行:
<meta name="viewport" content="initial-scale=1">,initial-scale=1設(shè)置頁(yè)面初始大小為原始頁(yè)面大小。需要確認(rèn)一件事,縮放是相對(duì)于ideal viewport來(lái)進(jìn)行縮放的,效果也就等同于content="width=device-width"。這樣寫的缺陷是windows phone 上的IE,不管當(dāng)屏幕變?yōu)闄M屏還是者豎屏?xí)r,寬度都是即定的豎屏?xí)rideal viewport的寬度。 - 綜上得到最終方案:
<meta name="viewport" content="width=device-width, initial-scale=1">,initial-scale=1可以iphone、ipad上的缺陷,width=device-width可以解決IE上的缺陷。
- 想要得到ideal viewport,首先想到是的屏幕寬度設(shè)置,把默認(rèn)的layout viewport寬度設(shè)為移動(dòng)設(shè)備的寬度,即
<meta name="viewport" content="width=device-width, initial-scale=1">