移動端適配方案(上)
要搞懂移動端的適配問題,就要先搞明白像素和視口。
像素
在移動端給一個元素設置 width:200px
時發生了什么?這里的px
到底是多長呢?像素是網頁布局的基礎,但是我們一直在用直覺使用它。
其實存在兩種像素:
1. 設備像素
屏幕的物理像素,任何設備屏幕的物理像素的數量都是固定不變的。
2. CSS像素
在CSS、JS中使用的一個抽象的概念,單位是 px
。
順便說下,CSS像素也可以稱為設備獨立像素(device-independent pixels),簡稱為
dips
,單位是dp
。
那么,我們現在再來說說一個元素 width:200px
以后會怎么樣。這個元素跨越了200個CSS元素,200個CSS元素相當于多少個設備像素取決于兩個條件:
- 頁面是否縮放
- 屏幕是否為高密度
這兩方面后面再解釋,先梳理一下手機硬件之間的關系,注意這里使用的都是物理像素。
以 iPhone5 為例,我們已知的是:
- 分辨率:
1136pt x 640pt
指屏幕上垂直有 1136 個物理像素,水平有 640 個物理像素 - 屏幕尺寸:
4英寸
注意英寸是長度單位,不是面積單位。4英寸指的是屏幕對角線的長度。 - 屏幕像素密度:
326dpi
屏幕像素密度(Pibel Per Inch)簡稱ppi
,單位是dpi
(dot per inch)。這里指屏幕水平或垂直每英寸有326個物理像素。原則上來說,ppi越高越好,因為圖像會更加細膩清晰。
ppi
是可以通過 分辨率 和 屏幕尺寸 計算得到的:
這個網站列出了很多設備的分辨率和屏幕尺寸,并且計算了ppi。
視口
桌面瀏覽器中,瀏覽器窗口就是約束你的CSS布局視口(又稱初始包含塊)。它使所有CSS百分比寬度推算的根源,它的作用是CSS布局限制了一個最大寬度,視口的寬度和瀏覽器窗口寬度一致。
但是在移動端,情況就很復雜了。
布局視口
一個沒有為移動端做優化的網頁,會盡可能縮小網頁讓用戶看到所有東西。這是我的手機查看博客園的樣子,你也可以在Chrome中以移動開發模式看到。
瀏覽器廠商為了讓用戶在小屏幕下網頁也能夠顯示地很好,所以把視口寬度設置地很大,一般在 768px ~ 1024px 之間,最常見的寬度是 980px。
所以,在手機上,視口與移動端瀏覽器屏幕寬度不再相關聯,是完全獨立的,這個瀏覽器廠商定的視口被稱為布局視口。
布局視口我們是看不見的,只知道網頁的最大寬度是 980px
,并且被縮放在了屏幕內。
可以這樣設置布局視口的寬度:
<meta name="viewport" content="width=640">
媒體查詢與布局視口
700px 指的是布局視口的寬度
@media (min-width: 700px){
...
}
document.documentElement.clientWidth/Height
返回布局視口的尺寸
視覺視口
視覺視口是用戶正在看到的網頁的區域,大小是屏幕中CSS像素的數量。
window.innerWidth/Height
返回視覺視口的尺寸
理想視口
布局視口明顯對用戶是不友好的,完全忽略了手機本身的尺寸。所以蘋果引入了理想視口的概念,它是對設備來說最理想的布局視口尺寸。理想視口中的網頁用戶最理想的寬度,用戶進入頁面的時候不需要縮放。
現在討論所謂的『最理想的寬度』到底是多少?其實,如果我們把布局視口的寬度改成屏幕的寬度不就不用縮放了么。可以這樣設置告訴瀏覽器使用它的理想視口:
<meta name="viewport" content="width=device-width">
定義理想視口是瀏覽器的事情,并不能簡單地認為是開發者定義的,開發者只能使用。
screen.width/height
返回理想視口的尺寸,有嚴重的兼容性問題---可能返回兩種值:
- 理想視口的尺寸(下載瀏覽器)
- 屏幕的設備像素尺寸(內置瀏覽器)
Screen size tests和Understanding viewport可以測試你的設備的screen.width
值,同一設備的不同瀏覽器返回的值可能是不一樣的。這一情況主要發生在默認瀏覽器和下載瀏覽器(如UC、Chrome)之間。
默認瀏覽器是安卓系統內置的瀏覽器,長下面那個樣子。而且它使用的是Webkit而不是Blink。只有在更新安卓系統的時候才能更新它。直到安卓4.3,Google不再更新。
而下載瀏覽器都返回的是理想視口尺寸。
縮放
縮放與設備像素、CSS像素的關系
縮放是在放大或縮小CSS像素,比如一個寬度為 200px 的元素無論放大,還是200個CSS像素。但是因為這些像素被放大了,所以CSS像素也就跨越了更多的設備像素。縮小則相反。
縮放與視口
縮放會影響視覺視口的尺寸
頁面被用戶放大,視覺視口內CSS像素數量減少;被用戶縮小,視覺視口內CSS像素數量增多就行了。這個道理應該是不難想的。
用戶縮放不會影響布局視口
注意,這是『用戶縮放』,后面會說開發者設置縮放的情況
縮放比例
我們在開發者工具中可以在這里查看縮放比例:
這里的 0.3 是相對于理想視口的。
在下載瀏覽器中,可以這么算(理想視口與視覺視口的比):
zoom level = screen.width / window.innerWidth
禁止縮放
<meta name="viewport" content="user-scalable=no">
設置縮放
<meta name="viewport" content="initial-scale=2">
使用initial-scale
有一個副作用:同時也會將布局視口的尺寸設置為縮放后的尺寸。所以initial-scale=1
與width=device-width
的效果是一樣的。
完美視口
解決各種瀏覽器兼容問題的理想視口設置
<meta name="viewport" content="width=device-width,initial-scale=1">
設備像素比
在談到像素的時候,講到除了縮放,屏幕是否為高密度也會影響設備像素和CSS像素的關系。
在縮放程度為100%(這個條件很重要,在后面會說到)時,他們的比例叫做設備像素比(device pixel ratio):
dpr = 設備像素 / CSS像素
可以通過JS得到: window.devicePixelRatio
設備像素比也和視口有關:
dpr = 屏幕橫向設備像素 / 理想視口的寬
總結
這一篇介紹了移動端適配需要掌握的知識,先說明了移動端存在的兩種像素,然后介紹了三種視口,由縮放對視口的影響引入理想視口,最后說明設備想告訴比。下一篇介紹現在市面上的適配方案。
參考文章
- ppk的移動端系列文章
- screen.width is useless
- devicePixelRatio
- More about devicePixelRatio
- screen sizes 收集了很多手機的信息
下面這些文章可能也會對你有幫助: