假設我們規定了 CSS 像素值需要與設備像素大小相等,但當隨著手持設備距離人的遠近不同,設備像素密度的不同,都會導致我們看見的設備上的 CSS 像素的可見大小發生變化(類似于巨大的月亮因為離地球遙遠在人眼看來也不過像硬幣一樣大小)。為了保證 CSS 像素在不同設備和不同距離上觀測到的大小保持一致保持連貫性。W3C 定義了一個 CSS 相對像素(CSS reference pixel)的概念。
W3C 規定,把人眼能夠辨別到的,距離自己一個手臂長度(約 28 英寸),像素密度為 96dpi 設備上的一個物理像素設為參考像素。所以我們可以算出眼睛看到參考像素的視野角度為 0.0213 度:

有了這一系列參照,通過三角函數關系,我們可以算出同樣一臺設備在不同距離下 CSS 像素理想的大小。 當遠離觀察者時像素應該增大,當靠近觀察者時像素應該減小:

這么做的優勢在于無論設備距離觀察者距離是多少,也無論設備的像素密度和物理像素大小是多少,觀察者看到的 CSS 像素是一致的,保證了用戶體驗的一致性:

我們有了物理像素,CSS 像素——那么問題來了,當你在手機上使用瀏覽器打開網頁時,網頁應該按照哪一種寬度進行渲染?
此時我們需要了解一個概念:viewport,常見到的中文譯為視口。
假設 body 標簽內有一個塊狀元素寬度為 10%:`div {width:10%;}`,我們知道當我們縮放瀏覽器時這個塊狀元素的寬度也會跟著變化。 這是因為它的寬度占它父元素的 10%。那么它的父元素,也就是 body 元素的寬度是由誰決定的呢?
我們知道一個塊狀元素默認寬度為它父元素的 100%,也就是 body 元素的寬度與包裹它的 html 元素寬度相同。那么問題又變成了 html 元素的寬度是由誰決定的?
答案是瀏覽器窗口。現在我們可以歸納起來,html 元素是被瀏覽器限制并且包裹起來的。html 的寬度就是瀏覽器的寬度。
但事實上,html 元素寬度是占據 viewport 的 100%,而在桌面瀏覽器中,viewport 與瀏覽器窗口大小剛好相等。
OK,在于是我們得到了一個結論,html 寬度是由 viewport 決定的,但是 在桌面瀏覽器中,viewport 大小與瀏覽器窗口大小相等。
但這一套規則在手機則是無法被執行的。大部分手機的屏幕分辨率目測只有 400px,如果頁面上真的有某一個頁面元素僅占 10%,也就是 40px 的話,肉眼幾乎是無法分辨的。實際情況應該會更糟糕,iPhone4 的 Safari 默認是以 980px 來渲染網頁的。
第一個辦法,放大頁面。我們會很習慣的用手勢去放大頁面。但是要注意我們這里做的僅僅是放大頁面,改變的是頁面的縮放 (scale),效果與 PC 上瀏覽器的類似。但是沒有改變頁面的布局,此時用于渲染頁面布局的 layout 仍然是 980px。
第二個辦法是,改變布局。比如一個頁面上有一張 320px 寬的圖片,如果我們以默認的 980px 去渲染的話,它會顯得過于窄小。

但如果我們可以將渲染它的布局設為 320px 的話,看上去就會好很多了,同時此時我們也未對頁面進行縮放:

在 320px 的像素下,我們可以對頁面進行縮放:

回歸到技術上,以上這些都可以通過 viewport 標簽來解決,比如說上面的需求,把布局設定為 320px,同時進行 1.5 倍的縮放:
~~~html
<meta name="viewport" content="width=320, initial-scale=1.5">
~~~
所見即所得,需要設置的屬性在 content 以逗號分割開來,`width`表示頁面布局寬度,`initial-scale`代表頁面初始狀態的縮放比例,如果你不想讓用戶進行縮放,還可以添加`user-scalable=no`字段來保證用戶無法進行縮放。
更重要的是,我們還可以無需指定特定寬度,通過設置`width=device-width`,指定布局寬度等于手機分辨率寬度來更好的利用響應式設計。注意這里的`device-width`表示手機的分辨率寬度,而并非手機物理像素寬度。iPhone4 在垂直狀態下物理像素寬度為 640,這里的`device-width`代表的則應該是它的 dip 像素 320px。
~~~html
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"/>
~~~
- 第一章:移動開發入門
- 第一節:概述
- 第二節:基礎概念
- 第一課時:像素
- 第二課時:視口
- 第二章:Flex 布局
- 第一節:概述
- 第二節:容器屬性
- 第一課時:flex-direction 屬性
- 第二課時:flex-wrap 屬性
- 第三課時:flex-flow 屬性
- 第四課時:justify-content 屬性
- 第五課時:align-items 屬性
- 第六課時:align-content 屬性
- 第三節:項目屬性
- 第一課時:order 屬性
- 第二課時:flex-grow 屬性
- 第三課時:flex-shrink 屬性
- 第四課時:flex-basis 屬性
- 第五課時:flex 屬性
- 第六課時:align-self 屬性
- 第四節:Flex 實例
- 第一課時:常見頁面布局
- 第三章:響應式布局
- 第一節:概述
- 第二節:媒體查詢
- 第一課時:概述
- 第二課時:響應式設計
- 第三節:柵格系統
- 第一課時:概述
- 第二課時:案例分析
- 第三課時:Bootstrap 簡介
- 第四節:響應式案例
- 第一課時:三星首頁
- 第四章:移動端適配
- 第五章:移動端事件
- 第一節:概述
- 第二節:touch 事件
- 第三節:觸摸事件對象
- 第四節:其他事件
- 第五節:移動端幻燈片
- 第六章:移動端常見問題
- 第一節:瀏覽器兼容性
- 第二節:移動端動畫
- 第三節:300ms 延遲
- 第四節:文字溢出省略
- 第五節:水平居中和垂直居中
- 第七章:項目案例
- 第一節:美團外賣
- 第一課時:首頁
- 第二課時:訂單頁面
- 第三課時:我的頁面
- 第四課時:詳情頁面
- 第五課時:購物車頁