前端系列教學(入門篇) - 響應式設計(1)

(預計閱讀時間:45分鐘,推薦使用電腦閱讀)

傳送門:

前端系列教學(入門篇) - HTML語義化 & 網頁布局

在這一篇我會介紹 設備像素,CSS像素 和 viewport 視口


為什麼要響應式?

在現如今,可以瀏覽器網頁的設備不在局限於桌面電腦。手機,平板,各種不同解析度,不同尺寸的設備層出不窮。作為前端開發人員,我們所寫的網頁不能再只著眼於桌面端,為大屏幕所設計的布局,在小屏幕的移動端設備上,可能會導致布局崩壞,或者內容太小看不清。

為了解決頁面在不同設備上都能有合理的布局,我們需要讓頁面布局根據設備屏幕尺寸的改變而適當改變。也就是所謂的 "響應式設計"。

但在具體介紹之前,我們先了解幾個概念。


「設備像素」,「CSS像素」,「設備獨立像素」

1. 「設備像素」(Device Pixel)DP

「設備像素」 又稱 「物理像素」(physical pixel),是設備 能控制顯示的 最小單位,我們可以把這些 像素 看作成 顯示器 上一個個的點。

一般我們在說 一個手機的解析度 多大時,就是在談論 它的 「設備像素」 的大小。

例如:iPhone 8 像素解析度為(1334 x 750)326 PPI;iPhone X 像素解析度為(2436 x 1125)458 PPI

2. 「CSS像素」 和 「設備獨立像素」 (Device independent Pixel) DIP

「CSS像素」 指的在 CSS樣式 中使用的 「邏輯像素」,也就是說 我們在做網頁時 用到的 CSS像素單位,是抽象的,不實際存在的。

例如我們在 CSS樣式 中寫 width: 500px;,在這裡定義的就是 CSS像素。

在CSS規範中,長度單位可以分為兩類:絕對單位(absolute)相對單位(relative)

「px」 就是一個 與 設備像素 相對 的 相對單位

絕對單位 就是指(「cm」,「dm」,「m」,等)這一類的單位。

「設備獨立像素」 指的是一個可以由程序使用並控制的虛擬像素。其實 「CSS像素」 就屬於這樣的 虛擬像素。只不過是同一種東西的不同說法而已。

我們可以把 「CSS像素」 和 「設備獨立像素」 看作為 同一個東西。

CSS像素 = 設備獨立像素 = 邏輯像素

3. 「設備像素」「CSS像素」 的關係:

在很久以前,移動設備 並不被用來瀏覽網頁。前端開發 只關注於 桌面端。在桌面瀏覽器 中 1 個 「CSS像素」 往往都是對應著 電腦屏幕上的 1 個 「設備像素」。

但是我在前面說了,「CSS像素」 是 「邏輯像素」 是抽象單位,是相對的。在不同的 設備或環境中,CSS 中的 「1px」 所代表的 「設備像素」 是不同的。

在桌面端,一個 400px 寬的 塊級元素,用 400 個 「設備像素」 去顯示不會有什麼問題。

但是在 移動端,現在手機 像素解析度 都很高,可是手機屏幕尺寸 是遠小於 桌面顯示器的。假設 手機 和 桌面顯示屏 的 設備像素 數量一樣。手機的 單位空間像素數量(每英寸像素) 一定大大高於 桌面屏幕。

那麼 400px 寬的 塊級元素 在手機中,就會被縮的很小。

同理 如果 「CSS像素」 和 「設備像素」 是完全對應的話,桌面端 顯示正常的網頁,在 移動端 就會被縮的很小。

為了讓 CSS樣式中定義的尺寸 在任何設備上都會顯示 一樣的大小。

(上圖中,為了讓圖標顯示相同尺寸,在 iphone 3gs 中 1個CSS像素 對應 1個設備像素;在 iphone 4s 中 1個CSS像素 對應 4個設備像素)

我們這個時候要讓 「CSS像素」 和 「設備像素」 呈現 相對 的關係。

一個 CSS像素 在不同解析度的設備上 對應不同數量的 設備像素。

  • 「設備像素」 的大小是固定的,是不可變的。
  • 「CSS像素」 的大小是可以被 放大 或者 壓縮 的。

  • 一個 設備像素 可以對應一個 CSS像素;
  • 一個設備像素 可以對應多個 CSS像素(縮小);
  • 一個 CSS像素 可以對應多個 設備像素(放大);

4. 那 設備像素(DP) 與 CSS像素 之間是如何轉換的呢 ?

在這裡就要用到 每英寸像素設備像素比 這兩個單位。

每英寸像素(pixel per inch) PPI:它是描述在水平的和垂直的方向上,每英寸距離的圖像包含的像素(pixel)數目。PPI 數值越高,代表顯示屏的像素密度越高,可以顯示越清晰的圖像。

設備像素比(device pixel ratio) DPR

設備像素比 = 設備像素 / 設備獨立像素(CSS像素) (得到某一方向上的比率,水平 或 垂直)

手機公司 根據 PPI 的數值大小來分範圍,以此定義 設備的默認縮放比例,即 默認設備像素比。

安卓手機中 PPI 在 120-160 之間的手機被歸為 低密度,160-240 被歸為 中密度,240-320 被歸為 高密度,高於 320 被歸為 超高密度,也就是 蘋果手機中 所謂的 Retina 屏幕。

拿 iphone X 舉例,這個手機的 PPI 為 458,那麼它的 默認設備像素比(DPR)為 2.0。

也就是說 1 個 CSS像素 = 2 x 2 個 設備像素;2 個 CSS像素 = 2 x (2 x 2) 個 設備像素。

(注意:下文我會用 「dip」 作為 CSS像素單位;「px」 作為 設備像素單位)


視口 Viewport

1. 布局視口 Layout Viewport

布局視口 Layout Viewport 也就是顯示<html>元素的地方。

因為 移動設備的屏幕 和 電腦的屏幕 相比要窄小很多。

如果把 為桌面端設計的網頁 在 移動端 顯示,網頁的布局 就會因為屏幕寬度太小,而擠在一起,導致布局崩壞。

有的人說現在手機解析度不都非常大嗎,比如iPhone X 像素就有 2436 x 1125。這麼大怎麼會排不開?

其實這裡要用到上文提到的概念。1個CSS像素 不對應 1個設備像素。如果那樣的話,在屏幕尺寸有限的手機上,網頁就會被縮的很小,以至於根本看不清。

手機上 1個 CSS像素 = 設備像素 x 設備像素比。

所以為了能在 移動設備 上 正常顯示 那些 為桌面瀏覽器 設計的網站,移動設備 上的 瀏覽器 會把自己 默認的 viewport 設一個較寬的值。(一般默認為 980dip,數值為CSS像素,數值取決於瀏覽器)

但因為 屏幕可視區域尺寸 小於 布局視口 為了顯示網頁,瀏覽器 就會出現一個 橫向的滾動條。屏幕 只能在一時間內 顯示網頁的一部分。

這樣一個 默認的 大於移動設備屏幕尺寸 的視口 就被稱為 布局視口 Layout Viewport

具體尺寸數值可通過 JS代碼 document.documentElement.clientWidth/cilentHeight獲得。

2. 可視視口 Visual Viewport

可視視口 Visual Viewport 可以理解為移動設備屏幕的可視區域(包括滾動欄)

具體尺寸數值可通過 JS代碼window.innerWidth/innerHeight獲得。

(上圖很好的展示了二者的區別。)

3. 理想視口 Ideal Viewport

在實際使用中,大尺寸的網頁因為有了 布局視口,在保持 桌面端布局 不變的情況下。用戶往往需要 通過 「放大頁面」 或者 「橫向滾動」 來瀏覽頁面內容。

為了能夠讓用戶能夠 在移動端 舒適 瀏覽頁面(不需要放大,縮小,滾動)。我們就又多了一個 理想視口 Ideal Viewport,也就是 寬度 等同於 移動設備屏幕寬度 的 viewport。

例如:iphone 4, iphone 5 的 ideal viewport 寬度為 320dip,iphone 6,iphone 7 都為 375dip。

每個設備的 ideal viewport 可能都不一樣,在這裡可以查詢。 Viewport Sizes

所謂理想就是說,用戶不需要 縮放 或 橫向滾動 頁面 就能正常查看網站所有內容;同時網頁中的文字大小,在任何設備中都應該顯示一樣的大小。

我們把 通過把 layout viewport 設置成 ideal viewport 我們就可以在一個適合 移動端 的寬度中 安排布局。


使用<meta> 標籤控制 viewport

移動瀏覽器默認的 viewport 就是 布局視口 layout viewport(大多默認為960dip)。但是為了理想的顯示,視口需要被改成 理想視口 ideal viewport。這個時候可以用 <meta> 標籤 來控制 viewport。

在 HTML文檔 的 <head> 標籤 中加入下面這個 <meta>標籤。來把當前的layout viewport 寬度 設置為 ideal viewport 的寬度

<meta name="viewport" content="width_=device-width, initial-scale=1">

  • width:用來控制layout viewport(布局視口)的寬度。一般默認為 980px。device-width 為設備的寬度。可以指定的一個值,如 320px。
  • initial-scale:初始縮放比例,也即是當頁面第一次 load 的時候縮放比例。

其他的屬性在這裡就不列舉了。具體可以參考 響應式 Web 設計 - Viewport。


將 viewport 設置為 ideal viewport

<meta name="viewport" content="width_=device-width, initial-scale=1">

這句代碼可以將 viewport 設置為 ideal viewport。

但是其實如果我們只寫

<meta name="viewport" content="initial-scale=1">

也可以把 viewport 寬度改成 ideal viewport 的寬度。

因為 「initial-scale」 是相對於 ideal viewport 的寬度進行縮放。initial-scale=1的意思就是說 相對於 「initial-scale」 進行 100% 縮放。

"viewport" = "initial-scale" / 100%

結果當然是 viewport 設置為 ideal viewport 了。

那既然寫這一句已經可以了,為什麼還要寫 width_=device-width ?

因為 iphone 手機 「橫屏」 的時候,還是相對 「豎屏」 的寬度進行縮放的。為了預防這種問題發生,我們需要做兩手準備。

<meta name="viewport" content="width_=device-width, initial-scale=1">

上面代碼可以保證設備的 viewport 無論是 橫屏 還是 豎屏,都會是 ideal viewport。

widthinitial-scale 出現衝突。例如當 iphone 7 橫屏的時候 width_=device-width 想要把 viewport 寬度 設置為 667dip,而 initial-scale=1 相對於 豎屏的 ideal viewport 縮放,想設置為 375dip。

那麼這個時候,667dip 大於 375dip。哪個大聽哪個


練習時間到!

下面讓我們手把手的把 前端系列教學(入門篇) - HTML語義化 & 網頁布局 這節最後的 練習題 的 viewport 改成 ideal viewport 吧!

(在下面我使用的是 Chrome瀏覽器,具體步驟可能因瀏覽器不同而有出入。)

1. 首先在 桌面端瀏覽器 中模擬 移動端 顯示

(在頁面中點擊滑鼠右鍵,之後點擊 Inspect 審查元素,調試網頁)

(之後點擊這個 手機/平板 小圖標)

(之後我們可以模擬 移動端 顯示了,你可以自定義 移動端設備,設備方向等)

2. 將 htmlbody元素 的 width 改成 100%

為了讓html元素的width 相對於 layout viewport 寬度。body元素的width相對於html元素寬度。

我們需要將其width屬性值 改成 百分比。

在CSS樣式添加

html { width: 100%;}

body 原來的 min-width: 650px; 改成 width: 100%;

現在 html 的寬度 等於 layout viewport 的寬度,body 的寬度 等於 html 的寬度。

現在可以看見body的寬度已經為 「980px」。

  1. 添加<meta> 標籤

在html文檔的head標籤中,添加代碼

<meta name="viewport" content="width_=device-width, initial-scale=1">

之後head標籤內容為:

<head> <meta charset="utf-8"> <meta name="viewport" content="width_=device-width, initial-scale=1"> <title>Pratice</title> <link rel="stylesheet" type="text/css" href="./style.css"></head>

現在 layout viewport 已經設置成 ideal viewport。<body> 寬度已為 「375px」。

但是因為寬度太低,我們可以看到右邊的布局已經崩壞,所有我們還需要設置Media Queries來使 樣式 隨 頁面寬度 改變而改變。

在下一章,我會介紹 Media Queries,讓頁面真正的變得響應式。

傳送門:前端系列教學(入門篇) - 響應式設計(2)


好啦,今天的教程就告一段落啦。

如果喜歡的話就點個關注吧!謝謝各位的支持!

如果有寶貴意見,也請大家多多留言!


推薦閱讀:

拒了 offer,我只說不喜歡加班。HR又打來電話說可以加錢,怎麼看?
web 前端開發工作加班頻繁嗎?會不會經常加班到十一、二點?
我是剛開始學習JS的小白,面對複雜的學習路徑,層出不窮的框架工具無所適從,不知道從哪裡學起怎麼辦?

TAG:Web开发 | 前端开发 | 前端入门 |