在前端實作無障礙網頁不可不知的 HTML
這個系列的前三篇文章大致描述了無障礙網頁的基本概念,以及設計師們可以注意的大方向和細節,接下來將從前端實作的角度討論網頁結構有哪些值得注意的地方,HTML 要怎麼撰寫才能符合無障礙規範。這篇文章將聚焦介紹常用的與頁面結構相關的 HTML 元素,至於互動性的元素以及 ARIA 屬性則會在下一篇提及。
大前提:結構的正確性
諸如 HTML tag ( HTML 標籤[1] )缺少對應的頭尾、屬性缺少引號、大小寫不符合規範、屬性之間缺少空格……等等都可能導致畫面呈現錯誤,HTML 結構的正確性不只是為了符合無障礙,也是為了整個頁面架構的正確性,可說是撰寫 HTML 時最需要注意的大前提。
如果使用預處理器( preprocessor )通常不會有這類問題,各大編輯器也都有原生功能或套件可以協助做 HTML Lint;如果想要看更詳細的檢測報告,也有 線上服務 可以協助檢查 HTML 是否符合規範。
使用具備語義的 HTML tag
如果說視覺化地認知網站是藉由元素的排列和樣式來理解各區塊和元件的群組、位置和功能,那麼螢幕閱讀器使用者就是靠著語義化的 HTML tag 來幫助理解當前這個元件在哪裡、可以做什麼、應該如何互動。
瀏覽器會根據頁面的 HTML 建立 DOM Tree,並依據 DOM 元件上的資訊( ARIA 屬性、title ……)建構出 Accessibility Tree [2]。螢幕閱讀器則會根據 Accessibility Tree 進行朗讀,使用 Chrome 的 devTool 可以檢視頁面的 Accessibility Tree :
Chrome 目前版本(103.0) devTool 有一個實驗性的功能,可以直接把 Accessibility Tree 顯示在左邊,更方便檢視:
2014 年推出的 HTML5 標準,新增了非常多語義化標籤(Semantic HTML Element),讓搜尋引擎爬蟲和螢幕閱讀器都能更容易辨識網頁內容。
針對前端切版的初學者,推薦閱讀一遍 W3C School 這篇按照類別排序的 HTML 標籤列表,先大致瞭解有哪些標籤可以使用。閱讀的時候也不需要把全部標籤都背起來,只要在腦中建立印象,對實際撰寫 HTML 就很有幫助,不至於因為不知道有特定標籤能用而直接寫 <div>
,遇到不熟悉的類型只要回頭查閱就可以了。
HTML 結構順序
螢幕閱讀器會依照 Accessibility Tree 的順序將內容提供給使用者,所以在前面文章[3] 提過的流程邏輯與頁面結構的一致性、內容的層級與順序,在 HTML 的實作也一樣需要注意。
設計上為考量使用者觀看網頁的節奏,有時會將畫面的結構順序做調換,遇到這種情形,撰寫 HTML 結構時仍應該維持有意義、有邏輯的順序。善用 CSS 選擇器,配合 float
、 order
或 grid
等等方式做出變化。
HTML tag 類型和 role
屬性
過去沒有這麼多語義化標籤時,會使用 role
屬性來補充描述元件的角色功能, HTML5 推出的語義化標籤吸納了不少原本需要寫落落長屬性才能表達的含意。
在實作上,我們應該優先使用語義化 HTML tag ,沒有可採用的 HTML tag 時才使用 role
作為補充;因為原生的 HTML tag 在瀏覽器中通常都具備鍵盤可訪問性,這類元件如果選擇使用 <div>
搭配 role
來呈現,就必須自行撰寫 tab-index
和額外的 javascript 來模仿瀏覽器行為。
在一頭栽進 ARIA 的世界之前,下面會按照類型先介紹一些常用的 HTML tag 。
Landmark
網頁的 landmark 目前好像沒有正式的翻譯[4] ,不過觀察下面幾個標籤,就會發現它們都是定義網頁主要架構、上層的元件,如同單字本身的意思,它可說是網頁的「地標」或「最主要的結構區塊」。
在無障礙的實現上,landmark 可以說是最重要也是最容易實作的類型,有下面這幾種 HTML tag 可以使用[5] :
<header>
<nav>
<main>
<aside>
<section>
<form>
<footer>
landmark 可以輔助導航功能,能讓螢幕閱讀器的使用者跳到特定的區塊進行閱覽,這也是為什麼 WCAG 建議所有的頁面內容都應該被放在 landmark 結構中。這同時意味著 landmark 的使用應該盡量精簡,以免讓使用者難以理解網頁主結構。
原則上,一個頁面應該只有一個 <main>
,其他 landmark 在有複數個同時存在時,需利用 aria-label
來區別其目的。例如頁面常見在 <header>
、 <footer>
裡有多個 <nav>
,此時就可以針對內容,標示 <nav aria-label="Header">
、 <nav aria-label="Footer ">
、或是 <nav aria-label="Social">
。
要注意, <header>
、 <footer>
常見被作為子區塊結構(例如獨立的文章有自己的標題和結尾區塊),這時它們不會被認定是 landmark role;只有在位於第一層(直屬於 <body>
)的情況下, landmark HTML 元素才會被認定為對應的 landmark role。 <section>
、 <form>
則是需要有可供辨識的名稱如 aria-labelledby
、 aria-label
或 title
屬性,才會被認定為 landmark role。關於 ARIA role 的類型會在後面的文章介紹。
標題
標題是讓使用者(無論是否借助螢幕閱讀器)快速瞭解頁面結構的重要元件,標題的 HTML tag 就是單純的 <h1>
~ <h6>
。撰寫標題結構要注意:
- 由
<h1>
到<h6>
,按照層級順序撰寫; - 下層內容與其所屬的上層內容相關;
- 須從
<h1>
開始,且不可以跳層。
段落和內容
<article>
<blockquote>
<ul>
、<ol>
- 兩者的差別在於
<ul>
是無序、<ol>
則是有序的列表。
- 兩者的差別在於
<li>
必須被直接放在<ul>
或<ol>
內。<p>
<br>
- 避免使用
<br>
來呈現 CSS 可以達成的間距,例如將兩個段落的文字內容都放在一個<p>
裡面,中間加一堆<br>
來做出間隔,「兩個段落」顧名思義就是兩個<p>
,別再偷懶啦!
- 避免使用
<del>
<em>
- 相較單純只呈現樣式的
<i>
(斜體字),使用<em>
可以讓螢幕閱讀器使用者也接收到「這段內容可能有不同解讀」的語義 [5]。
- 相較單純只呈現樣式的
<strong>
- 相較單純只呈現樣式的
<b>
(粗體字),使用<strong>
可以讓螢幕閱讀器使用者也接收到「重要內容」的語義。
- 相較單純只呈現樣式的
<ins>
<sub>
、<sup>
<hr>
<code>
<time>
圖片
<figure>
<figcaption>
<figcaption>
必須是<figure>
內第一個或最後一個元件。
<img>
- 除非是裝飾性的圖片、或相鄰元件就具備描述性的文字,否則
<img>
都應該要有能描述圖片內容的alt
,讓螢幕閱讀器使用者能讀取圖片。
- 除非是裝飾性的圖片、或相鄰元件就具備描述性的文字,否則
表格
<table>
<caption>
<caption>
必須是<table>
內的第一個元件。
<tbody>
、<thead>
、<tfoot>
<tr>
<th>
<td>
由於 <table>
本身的樣式特性,有時用 <table>
難以達成特殊的設計排版,這時用 <div>
配合 role
就可以表達 table 的語義結構。
下一篇會接著深入介紹表格元件。
[註1] 為避免和 label
(標籤屬性)、 aria-label
(ARIA 標籤)混淆,這系列的文章會一律以 HTML tag 表示。
[註2] web.dev: The Accessibility Tree
[註3] 延伸閱讀:《漫談無障礙網頁設計-2》
[註4] 本文提到 landmark 大多會使用原文,少數段落使用「地標」作為中文翻譯(參考 MDN Web Docs 的中文翻譯)
[註5] 定義來自 HTML5 draft。實務上 em
也被用來強調段落中的文字,不過強度比 strong
低。
系列文章目錄:
漫談無障礙網頁設計-1(無障礙網頁介紹)
漫談無障礙網頁設計-2(在設計上實作無障礙網頁的大方向)
漫談無障礙網頁設計-3(在設計上實作無障礙網頁的元件)
漫談無障礙網頁設計-4(在前端實作無障礙網頁不可不知的 HTML)← 現在在這裡!
漫談無障礙網頁設計-5(表格的使用)