RWD

You jump, I jump.

起源

2010 由 Ethan Marcotte 提出 Responsive Web Design 概念,簡稱 RWD,中文可以稱作響應式網站設計,這並非是種技術,而是種方式、最佳實踐的名詞,達成最終目的:在任何情境下,都有最佳體驗

在這個名詞出現之前,已經有類似的型態,只是沒有特別被提出來討論與重視。如果不使用 CSS 特別排版的話,HTML 本身就有某種程度的 RWD 意思,您可以進入以下範例,調整寬高、縮放試試看:

您會發現調整寬高、縮放網頁之後,還是可以看到所有的內容,這便是 RWD 的核心:流體佈局。流體佈局其實就是順著網頁原本的順序:由左至右、由上至下的方向顯示內容。在排版技巧篇的 float、flex、grid原則都是希望以最小的設定,達成通用的規則,基本上都是基於流體佈局的思考方式。

強烈推薦由左而右、由上至下的觀看順序,跟 DOM 結構高度相關,非必要請「不要」使用特殊的 CSS 任意變換位置,除了可能會造成無障礙的困擾,也可能在後續的維護上沒有準則導致維護困難。

另外,在智慧型手機誕生之初,AWD 概念被提出,AWD 全名為 Adaptive Web Design,與 RWD 的不同之處是,AWD 是直接專門為平板和手機做一個網站,等於是多做一個縮小版的網站,爾後因為成本太高不易維護等原因逐漸被淘汰,延伸出 RWD。

但也不是說 AWD 就是不好,如果經過研究發現特別做一版,例如專門做給特定族群,營運上的效益又可以壓過維護成本,還是可以使用 AWD 概念製作網站,畢竟 RWD 雖然一套吃全部,但相對的在初期規劃就必須更縝密,如果沒設計好,在內容彈性上面可能就略遜一籌。

RWD 的優缺點,評估是否導入

  • 優點:

    • 行動裝置已成為主要瀏覽方式

    • 技術熟練的話,開發成本與時間比 APP、AWD 便宜許多

    • 提升 SEO

    • 給用戶最好的體驗

    • 無障礙較好

  • 缺點:

    • 越複雜的內容成本越高。

    • 無法完全支援舊版瀏覽器,如有需求需要學習 Hack 技術。

    • 開發時會有高耦合,更動設計可能會影響大螢幕和小螢幕,須特別留意,但可靠技術力解耦。

注意事項

緊抓著自然的流體佈局大概念,還有以下幾點是必須要考量的項目:

  • 字級:

    • 原則: 大小需要依照「顯示裝置」與「使用者現實使用情境」決定,以達成最佳觀看效果,例如用手拿著 6 寸手機觀看和走在街上觀看對街的螢幕廣告,在裝置與觀看距離上有巨大的分別。這裡只是概括說明,實際上還得視字體而定,因為每種語言字體的特性、樣式不同,都會影響。製作網頁時如無特別要求的話,就是只針對桌機、平板、手機大小、解析度和一般使用距離情境。

    • 技巧:字級使用相對單位,例如:em、rem、%、vh、vw、cqw、cqi...,搭配 @media、@container 等查詢,也呼應無障礙網頁設計。

所以在 RWD 概念設計的網頁中,就不能在網頁底部寫類似「使用 1280 x 800 解析度瀏覽,以達最佳瀏覽體驗。」,因為跟 RWD 的觀念互相衝突,除非網站刻意有所限制,否則 RWD 在理想上必須確保在每個裝置與情境下使用時,都是最佳瀏覽體驗,而這也跟無障礙網頁設計的理念一致,不能因為裝置的問題造成體驗不一致。

  • HTML 的設定:

    • 原則:盡量不要設定太多條件,只需要像 CSS 的 Reset 般,讓每個瀏覽器解讀時有一致的起點。

    • 技巧: <meta> 的 name=viewpoint

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

      一般僅僅需要設定這樣即可,也就是畫面寬度等於裝置的螢幕寬度,初始縮放比例等於 1:1 ,除非特殊情形,請不要強制設定是否可以縮放,在無障礙網頁設計以及使用者經驗來說是不恰當,因為無法預期使用者到底什麼時候會需要使用縮放功能,這裡的設定也會影響到文章後半段提及的@media 媒體查詢,跟版面的呈現息息相關。 借用 Responsive Web Design 基礎 : <meta name=”viewport” > 設定 這篇文章的表格:

  • 多國語言

    • 原則: 不同的語言有不同的文字順序,例如中文有由上至下、由右而左的文章,或由右而左、由上至下的語言,或文字長度普遍較長,掌握文字特行並確保在切換網站目標語言時,體驗一致又不會破版,理念仍然與無障礙網頁設計相同。

    • 技巧: 透過 lang、class 等 attributes ,搭配 CSS Selector 改變 writing-mode、text-orientation、text-combine-upright、text-ellipsis、text-align 等方式達成。

  • 圖片、影片、嵌入區塊

    • 原則: 如同文字一般,隨著「顯示裝置」與「使用者現實使用情境」決定照片大小,且需要注意流量問題與解析度問題,無障礙網頁設計原則亦同。

    • 技巧: CSS 的 background-size、object-fit 等,決定圖片在隨著裝置改變時,情境如何變換。 例如在智慧型手機上觀看時,風景圖可能只呈現部分區域,商品圖可能還是要完整呈現。 如需加註尺寸,搭配 @media、@container 等查詢使用如 %、vw 等相對單位。 解析度問題盡量使用向量圖檔,如果不能,則要將同一張圖至少輸出三種尺寸以上,供不同裝置大小、解析度使用,也要確保圖片是經過壓縮的,甚至使用 Lazy Loading 等提高效能技巧。如果是小圖示,也可以考慮使用 icon font 的方式。

  • 內容

    • 原則:由大到小必須有所取捨,若是不能刪減,必須有合理的結構安排資訊或變換形式。

    • 技巧:@media

  • 斷點

    • 原則: 統計現實使用的多數裝置,並歸納出合理的尺寸切換時間改變排版,這個時間點稱為斷點。

    • 技巧:@media、@container

  • 圖表

    • 原則: 不管可視範圍如何調整,都要可以清楚辨識圖中資訊,不單只以顏色分辨資訊。

    • 技巧:@media、@container,針對不同情境,決定資訊要傳遞多少,甚至不使用圖改用表格等方式顯示也是可以的。

您可能已經發現內文不斷提到無障礙網頁設計,那是因為無障礙網頁設計的理念與 RWD 不謀而合,在任何情境下,都盡量達成最佳體驗

實作技術一:Columns

目前比較少人用,但 CSS Columns 其實也可以做成很好的 RWD 版面。但除了 RWD 外還有別的用處,這邊僅提醒有這些屬性,可以視形況使用。

請打開以下 codepen 頁面,試著將視窗縮小與放大,可以多暸解 column 的特性。即便設定成 3 欄,在寬度不足的情況下也會自動調整欄位數。

實作技術二:@media

當我們真的沒辦法規畫出自然流動的版面,就必須依靠斷點或類型改變版面,上述技巧裡提到的 @media ,全名為 Media Queries,意思是先「查詢」是什麼「媒體類型與特徵」,針對該媒體進行 CSS 的設定。

@media <media-query-list> { <stylesheet> }  

media-query-list 裡是由四種媒體類型和特徵組成,類型如下:

  • all:所有裝置。

  • print:印刷,含列印產生的預覽,如 .pdf。關於列印的技巧,我們會在章節四:進階技巧裡的列印篇詳述。

  • screen:不包含 print 和 speech 的螢幕裝置。

  • speech:可以朗讀頁面的設備,如螢幕報讀。

特徵如下:

  • width:包含 max-width 和 min-wifth。

  • height:包含 max-height 和 min-height。

  • aspect-ratio:螢幕長寬比例,會寫成 1 / 1 這種格式,包含 max-aspect-ratio 和 min-aspect-ratio。

  • orientation:螢幕方向,直向為 portrait,橫向為 landscape。

  • 其他不常用僅列舉:

    • resolution

    • scan

    • update-frequency

    • overflow-block

    • overflow-inline

    • color

    • color-index

    • display-mode

    • monochrome

    • inverted-colors

    • pointer

    • hover

    • any-pointer

    • light-level

    • scripting

上面有提到類型與特徵可以組成媒體,組成的方式可以使用以下:

  • and

  • only

  • not

  • or

CSS2.1 和 Media Queries 3 定義了幾種額外的媒體類型(tty, tv, projection, handheld, braille, embossed, aural),但它們在 Media Queries 4 中已棄用,不應使用。

截至 2023 ,目前已經可以使用 ( 200px <= width <= 500px) 這種寫法,但僅限於主流瀏覽器,若要使用此種寫法,請思考您的網站所適用的瀏覽器。

除了 or 是直接使用「,」分隔之外,其他都必須特定寫出來。使用方式如下範例:

<!-- HTML -->
<link rel="stylesheet" media="not screen and (color)" href="example.css" />
/* CSS */
h1 {
  font-size:30px;
}

@media not screen and (max-width:300px),
print and (orientation: landscape) {
  h1{
    font-size:50px;
    color:red;
  }
}

要特別注意您必須有條理的管理 CSS,否則可能會讓有寫 @media 的地方散落在各處,造成不好維護,或是權重不同一直被覆蓋無法達成您想要的效果。

實作技術三:@container

容器查詢,2022 最新支援,可以至 caniuse 網站查看支援情況。主流瀏覽器應該都已經支援。

上述 @media 使用時,通常都是用「裝置」的長寬去判定要不要使用某個斷點的 CSS,但有時候我們會在同一個裝置視窗時,因為內部版面配置長寬不同,同樣的元件,想要呈現不一樣的顯示方式。例如:

為了脫離跟 root 相對關係的問題,所以產生了 @container 藉此脫離以 root 為基準的關係,改以指定的上層容器為基準,因為有時候我們想要在某個斷點改變某個區域的樣式,但這個斷點並非包含在開發時預設的幾個斷點,所以會增加客製化的斷點,在管理上與樣式上就會變得凌亂與細碎。

使用容器查詢時,必須先選擇要當作依據的容器,必且給予容器查詢的類型:

.container {
  container-type: size | inline-size | normal;
}

而子容器就可以使用 @container :

/* Default heading styles for the card title */
.card h2 {
  font-size: 1em;
}

/* Container query applied if the container is larger than 700px */
@container (min-width: 700px) {
  .card h2 {
    font-size: 2em;
  }
}

如下範例:

當然,也可能會出現巢狀結構,那麼就可以使用命名的方式:

.container {
  container-type: inline-size;
  container-name: sidebar;
  /* 或是可以寫成一行: container: sidebar / inline-size */
}

@container sidebar (min-width: 700px) {
  .card {
    display: grid;
    grid-template-columns: 2fr 1fr;
  }
}

另外,也新增了關於容器查詢使用的寬度單位:

  • cqw: 1% of a query container's width

  • cqh: 1% of a query container's height

  • cqi: 1% of a query container's inline size

  • cqb: 1% of a query container's block size

  • cqmin: The smaller value of either cqi or cqb

  • cqmax: The larger value of either cqi or cqb

@container (min-width: 700px) {
  .card h1 {
    font-size: max(1.5em, 1.23em + 2cqi);
  }
}

至此,我們可以讓容器裡面的排版與外面的排版脫離,也就是不再具有依賴性質,讓每個容器都有獨立的排版機制去呈現最佳的外觀。

小結

請保持著最大的原則:能利用最自然的流體排版機制就盡量使用。盡量不重複 HTML、盡量不寫多餘的 CSS、依照內容絕定 DOM 的順序以及不濫用媒體查詢與容器查詢。能達成這些通常也代表著效能越高、品質越好。

作業

請試著在網路上找到有 RWD 的設計稿,並且嘗試使用本篇提及的技術排版。

參考連結

Last updated