judyshyu
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit
      • Invitee
      • No invitee
    • Publish Note

      Publish Note

      Everyone on the web can find and read all notes of this public team.
      Once published, notes can be searched and viewed by anyone online.
      See published notes
      Please check the box to agree to the Community Guidelines.
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Versions and GitHub Sync
    • Note settings
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Versions and GitHub Sync Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit
Invitee
No invitee
Publish Note

Publish Note

Everyone on the web can find and read all notes of this public team.
Once published, notes can be searched and viewed by anyone online.
See published notes
Please check the box to agree to the Community Guidelines.
Engagement control
Commenting
Permission
Disabled Forbidden Owners Signed-in users Everyone
Enable
Permission
  • Forbidden
  • Owners
  • Signed-in users
  • Everyone
Suggest edit
Permission
Disabled Forbidden Owners Signed-in users Everyone
Enable
Permission
  • Forbidden
  • Owners
  • Signed-in users
Import from Dropbox Google Drive Gist Clipboard
   owned this note    owned this note      
Published Linked with GitHub
Subscribed
  • Any changes
    Be notified of any changes
  • Mention me
    Be notified of mention me
  • Unsubscribe
Subscribe
--- title: 漫談無障礙網頁設計-4 tags: 網頁設計, 無障礙 description: --- # 漫談無障礙網頁設計-4 {%hackmd 7SwuI8Z_SCugN0SHT5LxVw %} ## 在前端實作無障礙網頁不可不知的 HTML tag 這個系列的前三篇文章大致描述了無障礙網頁的基本概念,以及設計師們可以注意的大方向和細節,接下來將從前端實作的角度討論網頁結構有哪些值得注意的地方,HTML 要怎麼撰寫才能符合無障礙規範。這篇文章將聚焦介紹常用的與頁面結構相關的 HTML 元素,至於互動性的元素以及 ARIA 屬性則會在下一篇提及。 <br> ### 大前提:結構的正確性 諸如 HTML tag (HTML 標籤[^1])缺少對應的頭尾、屬性缺少引號、大小寫不符合規範、屬性之間缺少空格……等等都可能導致畫面呈現錯誤,HTML 結構的正確性不只是為了符合無障礙,也是為了整個頁面架構的正確性,可說是撰寫 HTML 時最需要注意的大前提。 如果使用預處理器(preprocessor)通常不會有這類問題,各大編輯器也都有原生功能或套件可以協助做 HTML Lint;如果想要看更詳細的檢測報告,也有[線上服務](http://validator.w3.org/)可以協助檢查 HTML 是否符合規範。 [^1]: 為避免和 `label` (標籤屬性)、 `aria-label` (ARIA 標籤)混淆,這系列的文章會一律以 HTML tag 表示。 <br> ### 使用具備語義的 HTML tag 如果說視覺化地認知網站是藉由元素的排列和樣式來理解各區塊和元件的群組、位置和功能,那麼螢幕閱讀器使用者就是靠著語義化的 HTML tag 來幫助理解當前這個元件在哪裡、可以做什麼、應該如何互動。 瀏覽器會根據頁面的 HTML 建立 DOM Tree,並依據 DOM 元件上的資訊(ARIA 屬性、title……)建構出 Accessibility Tree [^2]。螢幕閱讀器則會根據 Accessibility Tree 進行朗讀,使用 Chrome 的 devTool 可以檢視頁面的 Accessibility Tree : [^2]: [web.dev: The Accessibility Tree](https://web.dev/the-accessibility-tree/) ![利用 Chrome 的 devTool 檢視 Accessibility Tree](https://i.imgur.com/1fyW0qs.jpg) Chrome 目前版本(103.0) devTool 有一個實驗性的功能,可以直接把 Accessibility Tree 顯示在左邊,更方便檢視: ![新的實驗功能讓我們能更容易檢視 Accessibility Tree](https://i.imgur.com/rAtqLQz.jpg) 2014 年推出的 HTML5 標準,新增了非常多語義化標籤(Semantic HTML Element),讓搜尋引擎爬蟲和螢幕閱讀器都能更容易辨識網頁內容。 針對前端切版的初學者,推薦閱讀一遍 W3C School 這篇按照類別排序的 [HTML 標籤列表](https://www.w3schools.com/TAgs/ref_byfunc.asp),先大致瞭解有哪些標籤可以使用。閱讀的時候也不需要把全部標籤都背起來,只要在腦中建立印象,對實際撰寫 HTML 就很有幫助,不至於因為不知道有特定標籤能用而直接寫 `<div>` ,遇到不熟悉的類型只要回頭查閱就可以了。 <br> ### HTML 結構順序 螢幕閱讀器會依照 Accessibility Tree 的順序將內容提供給使用者,所以在前面文章[^3] 提過的流程邏輯與頁面結構的一致性、內容的層級與順序,在 HTML 的實作也一樣需要注意。 設計上為考量視覺使用者觀看網頁的節奏,有時會將畫面的結構順序做調換,遇到這種情形,撰寫 HTML 結構時仍應該維持有意義、有邏輯的順序。善用 CSS 選擇器,配合 `float` 、 `flex-direction` 、 `order` 或 `grid` 等等方式做出變化。 [^3]: 參照[《漫談無障礙網頁設計-2》](https://apodesign.tw/uiux/website-accessibility-2/) ![畫面呈現與實際的 HTML 流向](https://i.imgur.com/Tlfv1Xm.jpg) <br> ## HTML tag 過去沒有這麼多語義化標籤時,會使用 `role` 屬性來補充描述元件的角色功能, HTML5 推出的語義化標籤吸納了不少原本需要寫落落長屬性才能表達的含意。 在實作上,我們應該優先使用語義化 HTML tag ,沒有可採用的 HTML tag 時才使用 `role` 作為補充;因為原生的 HTML tag 在瀏覽器中通常都具備鍵盤可訪問性,這類元件如果選擇使用 `<div>` 搭配 `role` 來呈現,就必須自行撰寫 `tab-index` 和額外的 javascript 來模仿瀏覽器行為。 在一頭栽進 ARIA 的世界之前,下面會按照類型先介紹一些常用的 HTML tag 。 ### Landmark 網頁的 landmark 目前好像沒有正式的翻譯[^4],不過觀察下面幾個標籤,就會發現它們都是定義網頁主要架構、上層的元件,如同單字本身的意思,它可說是網頁的「地標」或「最主要的結構區塊」。 [^4]: 本文提到 landmark 大多會使用原文,少數段落使用「地標」作為中文翻譯(參考 [MDN Web Docs](https://developer.mozilla.org/zh-CN/docs/Web/Accessibility/ARIA) 的中文翻譯) 在無障礙的實現上,landmark 可以說是最重要也是最容易實作的類型,有下面這幾種 HTML tag 可以使用 [^5]: - `<header>` - `<nav>` - `<main>` - `<aside>` - `<section>` - `<form>` - `<footer>` [^5]: [Landmark Regions](https://www.w3.org/WAI/ARIA/apg/practices/landmark-regions/#x4-1-html-sectioning-elements) ![常見的網頁 Landmark 結構](https://i.imgur.com/S9DLncA.jpg) 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>` 。撰寫標題結構要注意: 1. 由`<h1>` 到 `<h6>` ,按照層級順序撰寫; 2. 下層內容與其所屬的上層內容相關; 3. 須從 `<h1>` 開始,且不可以跳層。 ![標題順序的 DOs & DON'Ts](https://i.imgur.com/MbRWvUi.jpg) ### 段落和內容 - `<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>` [^5]: 定義來自 [HTML5 draft](https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-em-element)。實務上 `em` 也被用來強調段落中的文字,不過其強度比 `strong` 低。 ### 圖片 - `<figure>` - `<figcaption>` - `<figcaption>` 必須是 `<figure>` 內第一個或最後一個元件。 - `<img>` - 除非是裝飾性的圖片、或相鄰元件就具備描述性的文字,否則 `<img>` 都應該要有能描述圖片內容的 `alt`,讓螢幕閱讀器使用者能讀取圖片。 ![常見的圖片結構](https://i.imgur.com/jTwVHxP.jpg) ### 表格 - `<table>` - `<caption>` - `<caption>` 必須是 `<table>` 內的第一個元件。 - `<tbody>` 、 `<thead>` 、 `<tfoot>` - `<tr>` - `<th>` - `<td>` 由於 `<table>` 本身的樣式特性,有時用 `<table>` 難以達成特殊的設計排版,這時用 `<div>` 配合 `role` 就可以表達 table 的語義結構。 <br> 下一篇會接續著介紹具備互動性的 HTML 元素,如`<button>` 、 `<a>` 和各種表單元件。 <br>

Import from clipboard

Advanced permission required

Your current role can only read. Ask the system administrator to acquire write and comment permission.

This team is disabled

Sorry, this team is disabled. You can't edit this note.

This note is locked

Sorry, only owner can edit this note.

Reach the limit

Sorry, you've reached the max length this note can be.
Please reduce the content or divide it to more notes, thank you!

Import from Gist

Import from Snippet

or

Export to Snippet

Are you sure?

Do you really want to delete this note?
All users will lose their connection.

Create a note from template

Create a note from template

Oops...
This template is not available.
Upgrade
All
  • All
  • Team
No template found.

Create custom template

Upgrade

Delete template

Do you really want to delete this template?
Turn this template into a regular note and keep its content, versions, and comments.

This page need refresh

You have an incompatible client version.
Refresh to update.
New version available!
See releases notes here
Refresh to enjoy new features.
Your user state has changed.
Refresh to load new user state.

Sign in

Forgot password

or

By clicking below, you agree to our terms of service.

Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
Wallet ( )
Connect another wallet

New to HackMD? Sign up

Help

  • English
  • 中文
  • Français
  • Deutsch
  • 日本語
  • Español
  • Català
  • Ελληνικά
  • Português
  • italiano
  • Türkçe
  • Русский
  • Nederlands
  • hrvatski jezik
  • język polski
  • Українська
  • हिन्दी
  • svenska
  • Esperanto
  • dansk

Documents

Help & Tutorial

How to use Book mode

How to use Slide mode

API Docs

Edit in VSCode

Install browser extension

Get in Touch

Feedback

Discord

Send us email

Resources

Releases

Pricing

Blog

Policy

Terms

Privacy

Cheatsheet

Syntax Example Reference
# Header Header 基本排版
- Unordered List
  • Unordered List
1. Ordered List
  1. Ordered List
- [ ] Todo List
  • Todo List
> Blockquote
Blockquote
**Bold font** Bold font
*Italics font* Italics font
~~Strikethrough~~ Strikethrough
19^th^ 19th
H~2~O H2O
++Inserted text++ Inserted text
==Marked text== Marked text
[link text](https:// "title") Link
![image alt](https:// "title") Image
`Code` Code 在筆記中貼入程式碼
```javascript
var i = 0;
```
var i = 0;
:smile: :smile: Emoji list
{%youtube youtube_id %} Externals
$L^aT_eX$ LaTeX
:::info
This is a alert area.
:::

This is a alert area.

Versions and GitHub Sync
Upgrade to Prime Plan

  • Edit version name
  • Delete

revision author avatar     named on  

More Less

No updates to save
Compare with
    Choose a version
    No search result
    Version not found
Sign in to link this note to GitHub
Learn more
This note is not linked with GitHub
 

Feedback

Submission failed, please try again

Thanks for your support.

On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

Please give us some advice and help us improve HackMD.

 

Thanks for your feedback

Remove version name

Do you want to remove this version name and description?

Transfer ownership

Transfer to
    Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

      Link with GitHub

      Please authorize HackMD on GitHub
      • Please sign in to GitHub and install the HackMD app on your GitHub repo.
      • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
      Learn more  Sign in to GitHub

      Push the note to GitHub Push to GitHub Pull a file from GitHub

        Authorize again
       

      Choose which file to push to

      Select repo
      Refresh Authorize more repos
      Select branch
      Select file
      Select branch
      Choose version(s) to push
      • Save a new version and push
      • Choose from existing versions
      Include title and tags
      Available push count

      Upgrade

      Pull from GitHub

       
      File from GitHub
      File from HackMD

      GitHub Link Settings

      File linked

      Linked by
      File path
      Last synced branch
      Available push count

      Upgrade

      Danger Zone

      Unlink
      You will no longer receive notification when GitHub file changes after unlink.

      Syncing

      Push failed

      Push successfully