實作對照
四條原則講的是該做什麼,驗收清單 講的是怎麼檢查。這一頁補中間那段:這些原則在元件裡長什麼樣子。
用途有兩個——用元件的人知道自己已經免費拿到什麼;自己實作的人知道要補什麼。
原則 → 元件
1. 觸控目標 ≥ 44px
不是元件層的 API,而是 token 層的約束:--size-control-* 這組尺寸 token
已經把控制項高度訂在觸控友善的範圍,所有控制項共用同一組值。
| 元件 | 怎麼落實 |
|---|---|
Button/Input/Select/NumberInput | 高度綁 --size-control-md(預設)、--size-control-sm(密集表格內) |
Chips/SegGroup | 選項本身就是點擊區,不是「小方塊+旁邊的字」 |
DataTable 的排序欄頭 | 整個 <th> 可點,不是只有箭頭圖示 |
自己實作時最常漏的
把 checkbox 做成 16px 的方塊,然後期待使用者用手指點中。
可點區要包含標籤——這是 SegGroup 與 Chips 存在的理由之一。
2. 鍵盤走完全部流程
元件實際用到的鍵盤機制:
| 元件 | 機制 |
|---|---|
SegGroup/Chips | role="radiogroup"/group + roving tabindex:整組只有一個 tab 停點,方向鍵在組內移動 |
DataTable | 欄頭可聚焦並以 Enter/Space 排序;篩選面板可鍵盤開關 |
Dialog | 焦點鎖定與 Esc 關閉(Radix 提供) |
Tooltip | 鍵盤聚焦即顯示——不是只有 hover |
EditableField | Enter 進編輯、Esc 取消並還原、Tab 移到下一欄 |
Coachmark | aria-modal + 焦點管理,可鍵盤縮小與關閉 |
roving tabindex 是最容易做錯的一個。 一組 8 個選項如果每個都能 tab, 使用者要按 8 次才離開這一組;正確做法是整組一個停點,組內用方向鍵。
3. 對比 AA,淺深各驗一次
在 token 層解決:語意色的淺深兩套值都經過對比檢查,
*-foreground 與其配對背景的組合是設計好的,不要自行混搭
(例如把 text-muted-foreground 放在 bg-primary 上)。
8 色圖表色票另外做了色盲友善處理,淺深各一組。
4. 顏色不是唯一線索
這條在元件層最明顯,也是最常被單獨破壞的一條:
| 元件 | 除了顏色還給了什麼 |
|---|---|
Badge | 文字(不是純色點) |
Delta | 箭頭 + 文字 + 顏色三重編碼 |
Stepper | 完成態同時用勾選圖示與顏色,並以 aria-current 標示當前步驟 |
Callout | 四種語意各有圖示 |
EditableField 已變更態 | 琥珀色 + 「已變更」文字標籤 + 還原鈕 |
DataTable 排序 | 箭頭方向 + aria-sort |
自己實作時的頭號陷阱
「用紅色表示異常」——色覺障礙者、灰階列印、以及把螢幕調暗的人都看不到。 顏色是強化,不是載體。
螢幕報讀器:元件已宣告的語意
| 屬性 | 用在哪 | 作用 |
|---|---|---|
role="radiogroup" / aria-checked | SegGroup、Chips | 報讀「選項 2,共 5 項,已選取」 |
aria-sort | DataTable、Table | 報讀當前排序欄與方向 |
aria-current | Stepper | 報讀「目前在第 2 步」 |
aria-selected | TabPills | 分頁選取狀態 |
aria-live | Coachmark | 導覽步驟變動時主動播報 |
aria-modal | Dialog、Coachmark | 告知焦點被限制在此區 |
aria-live 用得很省是刻意的。 每個變動都播報等於什麼都沒播報——
只有「使用者沒看著、但需要知道」的變動才值得(例如導覽自動前進)。
這一頁不能取代的事
元件幫你處理的是結構性的無障礙。剩下這些只有你自己能做, 而且是驗收清單真正要檢查的部分:
- 文案:
aria-label寫「關閉」還是「關閉單位編輯對話框」,差別很大 - 順序:DOM 順序=閱讀順序。用 CSS 調換視覺位置會讓報讀器讀出錯的順序
- 錯誤訊息:要和欄位關聯(
aria-describedby),不是只在頁面頂端放一段紅字 - 焦點去向:刪除一列之後焦點該落在哪?沒有指定的話會回到
<body>
用了元件不等於通過無障礙驗收——它只是讓你不必從零開始。