淺談響應式Web設計與實現思路

淺談響應式Web設計與實現思路
1 Star2 Stars3 Stars4 Stars5 Stars 給文章打分!
Loading...

歡迎訪問我的個人部落格

目錄

響應式(Responsive)

響應式是什麼呢?顧名思義,響應式,肯定會自動響應,響應什麼?應用程式是在終端螢幕視窗中展示給使用者,被使用者訪問的,那麼就是響應螢幕的變化,不同終端螢幕尺寸大小不一致,需要針對不同尺寸螢幕進行不同的展示響應。

響應式(Responsive web design, RWD),是指一套應用程式使用者介面(User Interface)能自動響應不同裝置視窗或螢幕尺寸(screen size)並且內容,佈局渲染表現良好。

自適應(Adaptive)

在響應式設計(RWD)之外,還有一種適配多裝置螢幕的方式,自適應設計(Adaptive web design, AWD)

自適應設計(AWD),是指一個應用程式使用多版本使用者介面,針對不同裝置螢幕,伺服器端返回不同版本使用者介面,供使用者訪問。

自適應vs響應式

自適應和響應式設計的不同主要概括如下:

  1. 自適應是多套使用者介面,而後者則只有一套使用者介面;
  2. 自適應需要服務端檢測請求裝置解析度相關資訊,然後選擇對應版本返回;
  3. 自適應可以在不同版本使用不同適配方案,如在PC端使用百分比,在移動端使用rem等,而響應式則需要一個完美相容的適配方案;
  4. 以頭條網站為例,訪問www.toutiao.comPC端會開啟PC版本web應用,而在移動端開啟,則服務端會重定向至m.toutiao.com,對應的返回的就是移動端版本web應用;

自然的,我們本篇要關注的自然是響應式使用者介面設計,即一套應用程式適配多裝置。

移動優先(Mobile first)

從2014年開始,移動裝置使用訪問率已經超過PC,所以在設計響應式頁面程式時,通常都是移動優先,即先適配移動樣式和佈局,然後再調整適配PC端。

漸進增強(Progress enhancement)

另外我們知道移動裝置眾多,一些低版本或舊系統的裝置並不支援JavaScript或CSS的新特性,如es6,media query等,所以通常實現一個基礎版本,在大部分裝置能滿足基本功能後,針對性相容的新增新功能,新特性,逐步拓展應用,這就是漸進增強。

螢幕(screen)

前面講響應式就是響應螢幕尺寸,那麼螢幕尺寸如何衡量呢?主要從尺寸單位,裝置獨立畫素和畫素密度等角度考慮。

物理尺寸(Display size /Physical size)

螢幕物理尺寸,指根據螢幕對角線(diagonal)測量的實際物理尺寸,就像我們通常說的螢幕是多少寸的,是5.1還是5.5,平板是10.1,電視是42還是37寸,這裡的寸都指(英寸),而且是以對角線長度計量的。

對角線長度,則可以根據三角公式,由寬和高計算得出:

Physical-screen-size

邏輯尺寸(Logic size /Display resolution)

和螢幕物理尺寸相對的則有邏輯尺寸概念,或者叫它展示解析度(resolution),而和物理尺寸以長度inch為單位不同,邏輯尺寸則以畫素(pixel)為單位計量。

Dimension

和物理尺寸以對角線為方向計量螢幕大小不同的是,邏輯尺寸分別從橫向(寬),縱向(高)兩個方向表示螢幕的尺寸:width,height。以一臺“1024 × 768”解析度的筆記本為例,這表示裝置螢幕的寬是1024畫素,高為768畫素。

物理畫素(device pixel)

物理畫素,也叫裝置畫素實際畫素,在計算機數字影象中,一個畫素(pixel)或一個點(dot)是在一個光柵圖片(raster image)中的一個物理點,它是影象在螢幕上展示的的最小可控制元素。

所謂的光柵(raster image)或點陣圖(bitmapped image)圖片,是指將影象定義為由點(或畫素)組成,每個點(或畫素)可以由多種色彩表示,包括2、4、8、16、24和32位色彩。例如,一幅1024×768解析度的32位彩色圖片,其所佔儲存位元組數為:1024×768×32/(8*1024)=3072KB(一位元組等於8位)。

BitMapped Image

如圖,將螢幕放大至一定程度,可以看見是由很多個點(或畫素)組成,螢幕上的這些一個一個的點(或畫素)就是我們說的物理畫素,而畫素數量的不同及每個畫素的不同色彩表示就構成影象展示,決定它的視覺表現。

CSS畫素(CSS Pixel)

除了前面介紹的物理畫素,還有一種畫素經常被提及,那就是CSS畫素,也作邏輯畫素虛擬畫素,它僅僅是描述影象單元資訊的概念,通常描述影象中某一個小方框所需要展示的顏色值,而這一些列方框點合起來就能描述一幅影象,web程式設計中用來度量網頁內容尺寸或位置的就是這個抽象單位

logical pixel

解析度(resolution)

解析度通廠都是指裝置解析度,即裝置螢幕上顯示的物理畫素總和,以一臺“1024 × 768”解析度的筆記本為例,這表示裝置螢幕的寬是1024物理畫素,高為768物理畫素,它展示的畫素總數就是1024*768

畫素密度(Pixel density)

螢幕上每英寸(PPI,Pixel per inch)或每釐米(PPCM,Pixel per centimeter)上擁有的物理畫素(或點)的數量,稱為畫素密度,也作螢幕密度,計算公式為:

pixel density(pd) =  螢幕寬度物理畫素 / 螢幕寬度英寸;

如一個15英寸(對角線)大小的裝置,有一個12英寸寬,9英寸高的螢幕,並且其解析度為1024*768畫素,則其畫素密度則大概為85PPI:

pd = 1024 / 12 ~= 768 / 9 ~= 85PPI

當然橫縱方向上的畫素密度並不總是相同的,如將上面例子的解析度改為1280×1024,則:

  1. 橫向:pd = 1280 / 12 ~=107PPI;
  2. 縱向:pd = 1024 / 9 ~= 114PPI;

解析度轉換為畫素密度

根據螢幕解析度計算得出畫素密度公式,如:
$$
d_{p}={\sqrt {w_{p}^{2} h_{p}^{2}}}
$$

$$
V_{pd}={\frac {d_{p}}{di}}PPI
$$

  1. w<sub>p</sub>:解析度橫向畫素數;
  2. h<sub>p</sub>:解析度縱向畫素數;
  3. d<sub>p</sub>:對角線解析度畫素數;
  4. di:對角線物理尺寸(inch);
  5. V<sub>pd</sub>:畫素密度,單位為PPI;

密度等級劃分

為簡便起見,Android 將所有螢幕密度分組為六種通用密度: 低、中、高、超高、超超高和超超超高。而低密度螢幕在給定物理區域的物理畫素少於高密度螢幕。

點密度(dots per inch)

另外我們可能還聽過點密度(dots per inch,dpi),它和前面介紹的畫素密度相似,通常可以交叉使用,只是描述領域不同,畫素(pixel)通常在計算機視覺顯示領域使用,而點(dot)則主要在列印或印刷領域中使用。

裝置獨立畫素(dp/dip)

裝置獨立畫素(device independent pixel,稱為dp或dip),也叫密度無關畫素,是基於螢幕物理密度的抽象單位。首先由Google提出適配眾多Android裝置螢幕的抽象單位。在定義 UI 佈局時可以使用的虛擬畫素單位,表示佈局維度或位置。

它是一個基於計算機座標系統的物理度量單位,並且可以將物理畫素抽象為虛擬畫素以便在應用中使用,然後計算機內部系統可以將應用中使用的虛擬畫素轉換為實際物理畫素

這中抽象使得移動裝置可以在不同螢幕縮放展示資訊和使用者互動介面,而內部影象系統可以將應用中的抽象畫素度量轉換為實際畫素度量,因此應用可以直接使用抽象畫素,而不用編碼處理大量的物理畫素差異化的裝置。通常,安卓裝置假設“中等”密度螢幕裝置獨立畫素基準為:

一個裝置獨立畫素(dp/dip)等於160 dpi(或PPI) 螢幕上的一個物理畫素,即等於1 / 160英寸。

而windows則定義一個裝置獨立畫素為96dpi螢幕上的一個物理畫素,即1dp等於1 / 96英寸;Apple系統則預設一個裝置獨立畫素為72dpi螢幕上的一個物理畫素。系統執行時,根據當前螢幕的實際密度以透明方式處理 dp 單位的任何縮放 。

計算裝置獨立畫素

如何計算某一裝置的裝置獨立畫素呢?根據上面介紹可以得到dp和inch的如下等式:
$$
1dp={\frac {1}{ratio}}inch
$$

  1. *ratio*:即裝置系統指定的預設比例;
  2. inch:物理尺寸,英寸;

所以可以得到dp和物理畫素的轉換關係:
$$
1dp={\frac {V_{pd}}{ratio}}(PPI*inch)={\frac {V_{pd}}{ratio}}pixel
$$

  1. V<sub>pd</sub>:裝置畫素密度;
  2. PPI*inchpixel/inch * inch = pixel;

如,當螢幕密度為240dpi(或PPI),即V<sub>pd</sub> = 240時,1 dip 則等於1.5個物理畫素(pixel)。

裝置畫素比(dpr)

關於物理畫素,裝置獨立畫素或CSS畫素,有一個很常見的概念,裝置畫素比(device pixel ratio,dpr),它描述的是使用多少實際畫素渲染一個裝置獨立畫素,它的計算方式為:
$$
dpr={\frac {N_{dp}}{N_{px}}}
$$

  1. N<sub>dp</sub>: 裝置螢幕實際畫素數;
  2. N<sub>px</sub>: 螢幕裝置獨立畫素數(PC端通常等於CSS畫素數);
  3. dpr:裝置畫素比;

在瀏覽器中,我們可以使用window.devicePixelRatio獲取其dpr值,dpr更高的裝置螢幕會使用更多物理畫素展示一個裝置獨立畫素,所以其效果更細膩,更精緻。如在一個dpr=2的裝置上,1個裝置獨立畫素需要使用4個物理畫素展示,因為寬高各為2倍。

裝置獨立畫素與CSS畫素

上一小節介紹的裝置畫素比(dpr),通常指物理畫素和裝置獨立畫素的比例,我們知道,CSS畫素最終是需要轉換為物理畫素展示的,那麼CSS畫素如何對應物理畫素呢?

  1. 根據前文裝置獨立畫素小節所介紹,在具體裝置上,裝置獨立畫素與物理畫素的比例是固定的;
  2. 在PC端,通常裝置獨立畫素和CSS畫素比例是1:1,CSS畫素能以正常比例轉換為物理畫素展示;
  3. 在移動端,為了更好的展現頁面,預設情況下會進行縮放,這時裝置獨立畫素和CSS畫素比例並不是1:1,所以CSS畫素與物理畫素的比例就變了,所以我們看到的效果就變了;
  4. 當我們使用viewport meta明確設定視口width為理想視口時,視口寬度單位為裝置獨立畫素,同時設定intial-scale=1.0即表明將CSS畫素和裝置獨立畫素比例設定為1.0,那麼CSS畫素到物理畫素的轉換就能很好的展現我們的UI了。

UI度量(UI Dimension)

計量螢幕或螢幕內某一區域大小時,我們可以說長,寬多少寸,但是寸只是一個物理長度概念,而在開發UI介面時,由於需要適配諸多不同裝置,所以可衡量,可比較的UI度量則需要使用數字加抽象計量單位,我們可以稱之為UI維度(UI Dimension)。

A dimension is specified with a number followed by a unit of measure

維度使用一個數字加上一個度量單位宣告,如100px,10pt,10in,10dp等。

英寸(in)

Inches – Based on the physical size of the screen.

基於螢幕物理尺寸的度量單位,in

UI畫素(px)

UI畫素px,是一個相對單位,與之相對的是裝置畫素(device pixels)。一個px在不同裝置上可能對應不同的物理畫素數或(點),這取決於裝置畫素比(device pixel ratio)。開發頁面時,經常使用該單位定義UI的佈局和內容尺寸,文字大小,可以在瀏覽器中實現畫素展示良好的UI介面。

但是由於不同裝置上使用px單位時不會根據裝置螢幕大小進行自適應,尤其是PC和移動端差別比較大,所以一般響應式介面較少用px單位。

磅(pt)

磅,pt,即point,是印刷行業常用單位,等於1/72英寸,它是長度單位,是絕對大小,而px則是相對大小。

px與pt

前面說了,px是相對大小,pt是絕對大小,所以在不同裝置上,他們的關係可能不同,以Android裝置為例,一個dp等於160dpi螢幕上的一個物理畫素,則:

1dp = 1 / 160 inch

而結合前面介紹的pt單位:

1pt = 1 / 72 inch 

對於240PPI的螢幕,則:

  1. 1dp = 1 / 160 inch = 240 / 160 px = 1.5物理畫素
  2. 1px = 1 / 240 inch
  3. 1pt = 0.35物理畫素 = 0.35 / dpr CSS畫素(px)

em

em是在web文件中使用的一個縮放單位,1em等於最近父元素的font-size字型尺寸,如最近父元素字型為14pt,則1em=14pt。使用em單位表示的尺寸可以較好的在多終端瀏覽器進行樣式適配。

rem

rem也是一個縮放單位,與em相似,都是基於字型尺寸,不同的是rem是基於文件根元素字型尺寸,而與父元素字型尺寸無關,如文件根元素<html>font-size屬性為12pt,而最近父元素字型為14pt,則1rem=12pt

由於rem基於根元素字型大小計算,所以在文件中,任何一處使用rem單位計算基準都一樣,使得尺寸計算得到統一,而前面的em則在文件中都是基於最近父元素font-size屬性值,這說明在font-size值不同的父元素中使用em單位,計算並不能統一,這也是為什麼在目前的PC,移動端多裝置適配方案中,rem比em更常見。

百分比(%)

還有一個%百分比單位,基於最近父元素的相關屬性尺寸,乘以分配的百分比數,如父元素width為10pt,font-size:14pt,則width:10%就是1pt,font-size: 110%為15.4pt(瀏覽器實際渲染會化為整數渲染)。特別注意的是margin,padding屬性值為百分比時,是基於當前元素width值的。

%單位也是一個縮放單位,所以也常用於樣式適配。

視口(viewport)

在實現響應式設計之前,我們還需要了解一些視口相關概念。

視口(viewport),即可視區域的大小,指瀏覽器視窗內的內容區域,不包含工具欄、標籤欄等,也就是網頁實際顯示的區域。

視口型別

在開發移動端wap應用時,為了開發體驗更友好的介面,需要了解更多視口相關概念,通常將視口分為三種:視覺視口,佈局視口,理想視口。

視覺視口(visual viewport)

visual viewport定義如:

The visual viewport is the part of the page that’s currently shown on screen. The user may scroll to change the part of the page he sees, or zoom to change the size of the visual viewport。

視覺視口是指當前螢幕上頁面的可見區域。使用者可以滾動來改變當前頁面可見部分,或者縮放來改變視覺視口的尺寸。

visual viewport預設可以通過window.innerWidth來獲取,另外使用者可以通過縮放來改變visual viewport的尺寸,縮小時,visual viewport值變大,放大時,visual viewport值變小。

在目前新的草案文件中,已經定義了window.visualViewportAPI可以獲取視覺視窗物件,在Chrome61以上即可訪問:

console.log(window.visualViewport.width);

window.visualViewport物件屬性如:

visualViewport 屬性說明
offsetLeft視覺視口與佈局視口左邊界的間距以CSS pixels表示;
offsetTop視覺視口與佈局視口上邊界的間距以CSS pixels表示;
pageLeft視覺視口左邊界和文件左邊線的偏移距離,以CSS pixels表示;
pageTop視覺視口上邊界和文件上邊線的偏移距離,以CSS pixels表示;
width視覺視口的寬度,以CSS pixels表示;
height視覺視口的高度,以CSS pixels表示;
scale縮放比例,比如文件被放大2被,則返回值 2. 這個值不受裝置畫素比devicePixelRatio的影響。

佈局視口(layout viewport)

layout viewport的定義如下:

In the CSS layout, especially percentual widths, are calculated relative to the layout viewport, which is considerably wider than the visual viewport.

在CSS佈局中,比如百分比寬度是相對於佈局視口來計算的,佈局視口通常比視覺視口寬。

layout viewport寬度可以通過document.documenElement.clientWidthdocument.body.clientWidth來獲取。

為什麼說佈局視口通常比視覺視口寬呢,看圖很容易理解:

Visual VS Layout Viewport

當給定文件內容寬度大於視覺視窗寬度時,會出現如圖情況,視覺視口就是螢幕內文件可見區域,而佈局視口則包括文件不可見區域,只有滾動才能檢視其內容。

通常瀏覽器預設設定佈局視口為980px或1024px,所以通常你會看到它大於裝置螢幕可視區域,尤其是在移動裝置上,另外從上面給的多種例項圖片可以看出頂部position:fixed導航欄,始終跟隨佈局視口,width: 100%對應的是佈局視口寬度。

理想視口(ideal viewport)

理想視口,是指裝置的螢幕尺寸,單位為裝置獨立畫素(虛擬畫素,實際會被轉換為物理畫素展示)。

ideal viewport寬度可以使用screen.width來獲取,其值是由裝置決定,是對裝置來說最理想的佈局視口尺寸。如,iphone5理想視口為320,iphone6為375,IPhone7plus為414

這裡設定視口為裝置獨立畫素,那如何與UI使用的CSS畫素匹配呢?首先裝置獨立畫素和物理畫素的比例在具體某臺裝置上是固定的,然後我們知道裝置獨立畫素和CSS畫素都是虛擬單位,在PC端,通常裝置獨立畫素和CSS畫素比例是1:1,CSS畫素能以正常比例轉換為物理畫素展示;但是在移動端,為了更好的展現頁面,預設情況下會進行縮放將內容調整為適合螢幕的大小,這時裝置獨立畫素和CSS畫素比例並不是1:1,所以CSS畫素與物理畫素的比例就變了,所以我們看到的效果就變了,當我們使用viewport meta明確設定視口width為理想視口時,視口寬度單位為裝置獨立畫素,同時設定intial-scale=1.0即表明將CSS畫素和裝置獨立畫素比例設定為1.0,那麼CSS畫素到物理畫素的轉換就能很好的展現我們的UI了。

viewport meta

在現在的移動端網頁中,我們經常可以看到這麼一句程式碼:

 <meta name="viewport", width=device-width, initial-scale=1.0>

device-width返回的就是裝置的ideal viewport寬度,這句程式碼就是宣告當前佈局使用裝置理想視口寬度,在這種情況下,以iphone6理想視口為375為例,html設定width: 100%,最終得到的寬度就是320px

對於未設定meta元視口程式碼的頁面,在移動端訪問時,佈局視口為預設值980px,文件被縮小以完全展示內容,此時CSS畫素與物理畫素的比例變大,即一物理畫素展示更多CSS畫素,展示效果如圖:

blog ui

此時visualViewport物件資訊如下:

visualViewport

視口與佈局

在iphone之前,都是通過調整內容,適配PC端網站使其在手機瀏覽器上也可以友好訪問;後來iphone提出在“虛擬視窗”(視口)上展現網頁內容,並提供viewport元資訊元素以控制虛擬視窗大小。

在桌面瀏覽器中,瀏覽器視窗寬度就是我們CSS佈局時,能使用的最大寬度,如果內容寬度超出視口寬度,則會出現滾動條,以檢視所有內容;在移動瀏覽器中則不同,我們可以額外使用viewport控制視口以滿足展示需求。

預設佈局視口

如下對於一個PC網站,PC端正常展示如下:

PC Blog

而在移動端預設情況下,展示如圖:

Mobile Blog

  1. 我們給文件html,body寬度設定為width:100%,所以html,body的寬度是980px,這是瀏覽器預設設定的佈局視口寬度

  2. 預設,移動端瀏覽器佈局視口為980px,然後根據頁面內容進行縮放以使頁面內容能在當前可視視窗完全展示;當明確設定寬度width時:

    1. 若width大於980:我們設定html等元素width: 1200px後,視口將縮小布局以支援更多CSS畫素,即一個物理畫素將對應更多CSS畫素,視覺上看就是頁面被縮小了,這也驗證了CSS畫素只是一個虛擬畫素;

      Mobile 1200 px

    2. 若width小於980:我們設定html等元素width: 400px後,內容在視口的一部分展示,剩餘部分空白,視覺上並沒有被縮放,只是在更小的區域展示,導致文字換行,高度增加;

      Mobile 400px

比較特殊的是position:fixed;定位的頂部導航欄元素,其始終對應於佈局視口。

新增meta

加入給頁面新增元視口程式碼:

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

新增如上程式碼後,明確設定佈局視口為理想視口寬度,這樣瀏覽器就能完美展示我們的頁面,頁面也不會被縮放處理。當然,我們設定元素樣式時,其寬度便不能超過該佈局視口寬度,對於iphone6,為375px;如果超出則會出現滾動條。

device-width

CSS3 媒體查詢(media query)

CSS3 中的 Media Queries 增加了更多的媒體查詢,就像if條件表示式一樣,我們可以設定不同型別的媒體條件,並根據對應的條件,給相應符合條件的媒體呼叫相對應的樣式表。如:

  1. 視口寬度大於 800px 的縱向顯示屏,載入特定css檔案:

    <link rel="stylesheet" media="screen and (orientation: portrait) and (min-width:
    800px)" href="800wide-portrait-screen.css" />
    
  2. 列印裝置特定css檔案:

    <link rel="stylesheet" type="text/css" media="print" href="print.css" />
    
  3. 視口在375和600之間,設定特定字型大小18px:

    @media screen (min-width: 375px) and (max-width: 600px) {
    body {
    font-size: 18px;
    }
    }
    

響應式實現基礎

響應式設計實現通常會從以下幾方面思考:

  1. 組合流式佈局、彈性盒子(包括圖片、表格、視訊)和媒體查詢等技術;
  2. 使用百分比佈局建立流式佈局的彈性UI,同時使用媒體查詢限制元素的尺寸和內容變更範圍;
  3. 使用相對單位使得內容自適應調節;
  4. 選擇斷點,針對不同斷點實現不同佈局和內容展示;

響應式設計模式

目前,響應式設計實踐大致可總結為五類:mostly fluid、column drop、layout shifter、tiny tweaks 和 off canvas,通常,我們選擇其中的某一種或幾種組合實現我們的響應式UI。

微調式(Tiny Tweaks)

Tiny Tweaks佈局模式主要表現為單一列展示大部分內容,隨著視口寬的的增加,改變font-size值和padding間距,以保證內容的持續可讀性。

微調式針對單列布局,簡單的修改字型大小,padding和margin間距,保證內容可讀性。

Tiny taeaks

.c1 {
padding: 10px;
width: 100%;
}
@media (min-width: 600px) {
.c1 {
padding: 20px;
font-size: 1.5rem;
}
}
@media (min-width: 960px) {
.c1 {
padding: 40px;
font-size: 2rem;
}
}

浮動式(Mostly Fluid)

Mostly Fluid佈局是一種多列布局,在大螢幕上設定較大margin,但是在移動端則會浮動後續列,垂直堆疊排列。該模式很常見,因為通常只需要設定一個斷點。

浮動式佈局,精髓在於浮動,隨著螢幕縮小,浮動後續列,通常float/flex width然後使用media query設定不同width值實現。

Mostly fluid

以如下html結構為例:

<!--Pattern HTML-->
<div id="pattern" class="pattern">
<div class="c">
<div class="main">
<h2>Main Content (1st in source order)</h2>
<p>1</p>
</div>
<div class="c2">
<h3>Column (2nd in source order)</h3>
<p>3</p>
</div>
<div class="c3">
<h3>Column (3nd in source order)</h3>
<p>4.</p>
</div>
</div>
</div>
<!--End Pattern HTML-->

其樣式通常有如下方式:

.main {
background-color: #8e352e;
}
.c2 {
background-color: #c84c44;
}
.c3{
background-color: #a53d36;
}
@media screen and (min-width: 37.5em) {
.c2, .c3 {
float: left;
width: 50%;
}
}

當螢幕寬度大於31.42em,瀏覽器預設font-size為16px,則為37.5 * 16 = 600px,大於600px畫素時下面兩個div則浮動並列顯示,否則垂直堆疊展示。

斷列式(Column Drop)

Column Drop也是一種多列布局方式,在移動端垂直堆疊排列,隨著螢幕增大將各列平鋪排列,這種模式就需要我們選擇多個斷點並選擇變化列。

斷列士核心是將內容劃分為多列,然後隨著螢幕變小,依次將左/右列斷開堆疊至主列下方。

Column drop

<!--Pattern HTML-->
<div id="pattern" class="pattern">
<div class="c">
<div class="main">
<h2>Main Content (1st in source order)</h2>
<p>1</p>
</div>
<div class="sb">
<h3>Column (2nd in source order)</h3>
<p>2</p>
</div>
<div class="sb-2">
<h3>Column (3nd in source order)</h3>
<p>3</p>
</div>
</div>
</div>
<!--End Pattern HTML-->

樣式如:

.main {
background-color: #8e352e;
}
.sb {
background-color: #c84c44;
}
.sb-2 {
background-color: #a53d36;
}
@media screen and (min-width: 42em) {
.main {
width: 75%;
float: left;
padding: 0 1em 0 0;
}
.sb {
float: left;
width: 25%;
}
.sb-2 {
clear: both;
}
}
@media screen and (min-width: 62em) {
.main {
width: 50%;
margin-left: 25%;
padding: 0 1em;
}
.sb {
margin-left: -75%;
}
.sb-2 {
float: right;
width: 25%;
clear: none;
}
}

移位式(Layout Shifter)

Layout Shifter響應式設計是指標對不同螢幕進行不同佈局和內容展示,通常需要設定多個斷點,然後針對不同大小螢幕,進行不同設計,和前面幾種模式在處理小螢幕時自動將後面列往下堆疊不同,在每類斷點之間都需要涉及佈局和內容兩者的修改;這意味著我們需要做更多的編碼工作,當然我們的可控性也更強。

移位式核心在於確定不同螢幕需要何種佈局及內容展示方式,然後在各斷點使用media query進行控制。

Layout Shifter

分屏式(Off Canvas)

在這之前的四種設計思路都是在大屏鋪開展示,然後隨著螢幕縮小,將其餘列垂直堆疊展示,使用者需要上下滾動才能檢視頁面所有內容,而Off Canvas模式則換了一個思路:分屏:

  1. 在小螢幕裝置,將不常用或非主要的內容(如導航和選單之類)放在螢幕外左右兩側,點選可以切換顯示/隱藏;
  2. 在大螢幕可選擇性的鋪開展示;

分屏式精華是劃分主要內容(如文章列表)和非主要內容(如導航欄),然後優先展示主要內容,非主要內容可以在左右兩側隱藏,支援使用者主動點選/滑動切換顯示/隱藏。

Off Canvas

通常的做法是,在小螢幕,設定不常用內容display: none;transform: translate(-200px, 0);,然後點選開啟按鈕時,新增恢復樣式display: block;transform: translate(0, 0);,即可展示;在大螢幕則可選擇性設計展示方式,通常是直接平鋪。

響應式實現

理論知識基本準備的差不多了,接下來實現一個簡單的例子。

設定視口

在html內新增元視口程式碼:

<meta name="viewport" content="width=device-width, initial-scale=1.0">
  1. width=device-width 指定視口為理想視口,以便使用當前視口(裝置獨立畫素為單位)能展現良好的頁面;
  2. initial-scale=1 指定將 CSS 畫素與裝置獨立畫素比例設為 1:1。

intial-scale=1.0 即阻止移動瀏覽器自動調整頁面大小 ,瀏覽器將按照視口的實際大小(此處設定為理想視口)來渲染頁面。

當然還可以通過[email protected]方式宣告,與meta標籤效果相同:

@viewport {
width: device-width;
zoom: 1;
}

其中,zoom屬性等同於 viewport meta 標籤的 initial-sacale 屬性。

媒體查詢

當前各主流瀏覽器基本都支援meida query,但是如果你期望網站在IE8甚至以下版本也展示良好,則需要新增相容,可以用 media-queries.js 或 respond.js:

<!--[if lt IE 9]>
<script src="//css3-mediaqueries-js.googlecode.com/svn/trunk/css3-mediaqueries.js"></script>
<![endif]-->

設定斷點(breakpoints)

響應式設計還有一個重要的問題是如何確定檢視斷點,是以裝置為依據嗎?當然不行,裝置是無窮無盡的,最好的實踐是以內容為依據,然後從移動裝置開始,從小到大依次增加一屏展示內容,確定我們期望的多個檢視斷點及布對應設計UI。

以material-ui為例,分為:

  1. xs, extra-small: > 0
  2. sm, small: >= 600
  3. md, medium: >= 960
  4. lg, large: >= 1280
  5. xl, xlarge: >= 1920

Breakpoints

可以自由選擇斷點並使用media query設定響應式佈局,如:

/* for 1280px or less */
@media screen and (max-width: 1280px) {
#pagewrap {
width: 95%;
}
#content {
width: 65%;
}
#sidebar {
width: 30%;
}
}
/* for 960px or less */
@media screen and (max-width: 960px) {
#content {
width: auto;
float: none;
}
#sidebar {
width: auto;
float: none;
}
}
/* for 600px or less */
@media screen and (max-width: 600px) {
h2 {
font-size: 0.8em;
}
#sidebar {
display: none;
}
}

當然這並不意味著我們只能使用這幾個斷點,也許我們希望在特定情況下,進行一些特定處理:

@media (min-width: 360px) {
body {
font-size: 1rem;
}
}

相對單位

既然是響應式設計,需要實現響應式檢視,那麼固定值的長度單位就必然很難滿足期望;如果使用固定單位,如px,則需要針對每一種情況進行不同處理,多了很多工作,否則就無法實現響應式。

例如,給在容器div設定width: 100%;可以確保其填充視口寬度,相對視口而言不會太大也不會太小,無論裝置是寬度為320畫素的 iPhone5、寬度為375畫素的iPhone6,還是寬度為360畫素的 Nexus 5,div 均會適應於這些裝置螢幕;此外,使用相對單位可以自動調整內容尺寸空間,而不會出現橫向滾動條的情況。

.wrap {
width: 320px;
font-size: 20px;
}
// 相對單位
.wrap {
width: 100%;
font-size: 1.25rem;
}

相對單位有百分比(%),em,rem等。

響應式文字

針對網站可讀性的調研發現,閱讀體驗友好段落行內應該包含 70 到 100 個字元,通常是8-15個英文單詞,20-50箇中文漢字,所以需要針對檢視斷點進行控制:

width: 100%;
padding: 10px;
@media screen (max-width: 600px) {
.article {
width: 100%;
papdding: 15px;
margin: 0 auto;
font-size: 1rem;
}
}
@media screen (min-width: 600px) and (max-width: 960px) {
.article {
max-width: 700px;
margin-left: 0 auto;
}
}

如上,在較小的螢幕上,大小為1rem的字型可以使每行完美地呈現約20-30中文,而在較大的螢幕上就需要新增斷點了,如,當瀏覽器寬度超過 600px,則內容理想寬度是100%,最大理想寬度是700px。

響應式圖片

因為佈局是響應式的,所以圖片也需要根據佈局進行響應式展現。

彈性圖片佈局

首先在佈局上,我們的圖片肯定需要隨著佈局變更而彈性變化,所以不能設定固定尺寸,通常使用相對單位,設定如下樣式:

.img-wrap {
width: 100%;
}
img { max-width: 100%; }

設定寬度100%,寬度自適應,不設定高度,圖片高度將按照圖片解析度比例自適應,於是,圖片便可以自動跟隨容器縮放良好展現。

同時我們也有必要為圖片容器設定最大寬度,避免出現圖片拉伸過大,損失質量的情況:

.img-wrap {
max-width: 200px;
}

圖片響應式

是不是這樣就結束了呢?當然不是,通常,PC端需要使用大尺寸圖片展現,但是在移動端限於頻寬和網路流量原因,必然不適合使用大尺寸圖,圖片內容也需要響應式,我們應該為不同的螢幕尺寸提供不同的圖片,為大螢幕準備大尺寸圖片,小螢幕準備尺寸更小的清晰圖片,另外高解析度 (2x, 3x) 顯示屏上高解析度圖片可保證清晰度。

Responsive imgs

srcset

srcset 屬性增強了 img 元素的行為,我們可以針對不同裝置提供不同尺寸圖片。類似於 CSS 原生的 image-set CSS 函式srcset 也允許瀏覽器自動根據裝置特性選擇最佳影象,例如,在 2x 顯示屏上使用 2x 影象。

<img src="photo.png" srcset="[email protected] 2x" />

在不支援 srcset 的瀏覽器上,瀏覽器需使用 src 屬性指定的預設影象檔案,所以需要始終包含一個在任何裝置上都能顯示的預設影象。如果 srcset 受支援,則會在進行任何請求之前對逗號分隔的圖片條件列表進行解析,並且只會下載和顯示預設圖片。

當然該方式目前相容性實在不樂觀,比較少使用。

藝術方向(picture)

藝術方向是指使用 picture 元素,根據裝置特性選擇特定影象。 picture 元素支援宣告式方式定義,根據裝置大小、裝置解析度、螢幕方向等不同特性來提供一個圖片的多尺寸版本:

<picture>
<source media="(max-width: 599px)" srcset="profile-s.png">
<source media="(min-width: 600px)" srcset="profile-600w.png">
<img src="profile-600w.png" alt="Progile">
</picture>
  1. picture元素包含了source元素列表,瀏覽器可以根據當前裝置特性選擇特定源圖片,然後需要宣告一個img元素提供預設圖片;
  2. <source>元素包含一個media屬性,該屬性是一個媒體條件,根據這個條件決定顯示哪張圖片,從上至下,遇到匹配條件為真,則顯示對應圖片。在如上例項,若視口寬度不超過599px,則顯示第一個<source>元素srcset指定的圖片,若視窗寬度大於或等於600px,則顯示第二張圖片;
  3. srcset屬性包含要顯示圖片的路徑。請注意,正如我們在<img>上面看到的那樣,<source>可以使用引用多個影象的srcset屬性,還有sizes屬性。所以支援通過一個 <picture>元素提供多個圖片,也可以給每個圖片提供多解析度的圖片,不過通常需求比較少;
  4. 最後一點需要注意的是,我們應該總是在 </picture>前面提供一個<img>元素以及它的srcalt屬性,否則不會有圖片顯示,並且當媒體條件都不匹配時,會載入img提供的圖片,;另外,如果瀏覽器不支援 <picture>元素,也會預設使用該img元素替換;

更多關於響應式圖片資訊可以查閱參考資料

總結

本文主要介紹了響應式設計相關理論基礎,包括:螢幕尺寸,物理,CSS畫素等相關概念,視口,響應式設計基礎,常見設計模式,及響應式UI實現基本思路等,目前最常見的多屏適配rem方式,博主計劃後續繼續介紹。

參考

  1. Responsive Design
  2. Respinsive Web Design
  3. A tale of two viewports
  4. Display Size
  5. Viewport Meta tag

前端開發 最新文章