local-tool/: visionA-local desktop app
- M1: Wails shell + Go server + Next.js UI + Mock mode (macOS dmg ready)
- M2: i18n (zh-TW/en) + Settings 4-tab refactor
- M3: Embedded Python 3.12 runtime (python-build-standalone) + KneronPLUS wheels
- M4: Windows Inno Setup script (build on Windows runner)
- M5: Linux AppImage script + udev rule (build on Linux runner)
- M6: ffmpeg (GPL, pending legal review) + yt-dlp bundled
- Lifecycle: watchServer health check, fatal native dialog,
Wails IPC raise endpoint, stale process cleanup
.autoflow/: full PRD / Design Spec / Architecture / Testing docs
(4 rounds tri-party discussion + cross review)
.github/workflows/: macOS / Windows / Linux build CI
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
193 lines
7.5 KiB
Markdown
193 lines
7.5 KiB
Markdown
# 09 — 無障礙(A11y)要求
|
||
|
||
## 9.0 目標與範圍(第四輪 R4-3 定案)
|
||
|
||
**目標:盡力而為(best effort),不以 WCAG 2.2 Level AA 為硬性驗收標準。**
|
||
|
||
原本規劃以「WCAG 2.2 AA 合規」作為硬指標,但第四輪決策 R4-3 將其**從硬目標降級為「盡力而為」**,理由:
|
||
- 本產品為**內部工具、工程師族群為主**,非對外公眾服務,無法律合規壓力
|
||
- 硬性 AA 驗證(axe serious=0、screen reader 全流程、色彩對比全面實測)會佔用 M1 大量人力,排擠核心功能
|
||
- PRD 非功能需求已把 a11y **列入 non-goals**(不做硬性驗證,只列為指引)
|
||
|
||
**本章角色變更為「a11y 設計指引」**:Design 在元件設計時**參考**本章原則,Frontend 在實作時**盡量**採納,但**不以此作為 code review 或 QA 的 blocker**。
|
||
|
||
**仍會做的(low cost 的基本盤)**:
|
||
- 所有可聚焦元素有 visible focus ring(無額外成本)
|
||
- 語意化 HTML(`<button>`、`<nav>`、`<main>`,不用純 `<div>`)
|
||
- `<label>` 與 `<input>` 正確關聯
|
||
- `aria-label` 給 icon-only button
|
||
- 鍵盤可完成核心流程(Tab 順序大致合理即可,不強求完美)
|
||
- 尊重 `prefers-reduced-motion`
|
||
|
||
**不做的(高成本項目,R4-3 後明確排除)**:
|
||
- 色彩對比逐一實測(4.5:1、3:1)
|
||
- Screen reader 全流程人工驗證(VoiceOver / NVDA)
|
||
- axe / Lighthouse 自動掃描作為 CI gate(可跑但不 block)
|
||
- Reflow 320px 支援
|
||
- ARIA 角色完整覆蓋
|
||
- 推論結果的「非視覺呈現」文字清單(原 9.8)
|
||
|
||
以下各節**作為指引保留**,實作時採納即可;**不列為驗收條件**。
|
||
|
||
## 9.1 色彩對比
|
||
|
||
| 元素類型 | 最低對比 | 檢驗方式 |
|
||
|---------|---------|---------|
|
||
| 正文 body text | 4.5 : 1 | Chrome DevTools contrast checker |
|
||
| 大字體(≥18pt 或 ≥14pt bold) | 3 : 1 | 同上 |
|
||
| UI 元件(border、icon) | 3 : 1 | 手動檢查 |
|
||
| Focus ring | 3 : 1(對周邊背景) | 手動檢查 |
|
||
|
||
**已知需注意**:
|
||
- Dark mode 的 `color.muted-foreground` (oklch 0.708) 對 `color.card` 背景需複測
|
||
- Mock badge 的黃底黑字需達 4.5 : 1
|
||
|
||
## 9.2 觸控/點擊目標
|
||
|
||
| 元素 | 最小尺寸 |
|
||
|------|---------|
|
||
| Button / Icon button | 40×40px(桌面 app 可略小於 44,因為用滑鼠) |
|
||
| Sidebar item | 44×240px |
|
||
| Checkbox / Radio hit area | 32×32px(含 label 區域) |
|
||
|
||
**桌面 app 例外**:因為主要輸入裝置是滑鼠,可以比 mobile 44×44 稍小,但不能低於 32×32。
|
||
|
||
## 9.3 鍵盤導航
|
||
|
||
**所有功能必須可用鍵盤完成**,無 mouse 也能跑完整流程。
|
||
|
||
### Tab 順序原則
|
||
|
||
1. Header(幫助按鈕、Mock badge)
|
||
2. Sidebar(主導航 1→4,然後 Settings)
|
||
3. Content 主區塊(由上到下、由左到右)
|
||
4. 頁面內的主 CTA 位置要 Tab-friendly
|
||
|
||
### 特殊鍵
|
||
|
||
| 鍵 | 行為 |
|
||
|----|------|
|
||
| Tab / Shift+Tab | 下一個 / 上一個可聚焦元素 |
|
||
| Enter | 啟動按鈕、提交表單 |
|
||
| Space | 啟動按鈕、切換 checkbox |
|
||
| Esc | 關閉 modal、drawer、tooltip、dropdown menu |
|
||
| 方向鍵 | 清單中移動(如 sidebar 項目、model grid) |
|
||
| ⌘/Ctrl + K | 保留給未來 command palette(目前不做) |
|
||
|
||
### Focus Ring
|
||
|
||
- 所有可聚焦元素必須有可見 focus ring
|
||
- 使用 `color.ring` (oklch 0.708 / 0.556),2px outline + 2px offset
|
||
- 不要用 `outline: none` 而不補替代方案
|
||
|
||
### Skip Link
|
||
|
||
在 Sidebar 最前面加 `skip to main content` link(預設 `sr-only`,Tab 聚焦時顯示)。
|
||
|
||
## 9.4 ARIA
|
||
|
||
### Landmark roles
|
||
|
||
```html
|
||
<aside role="navigation" aria-label="主導航"> <!-- Sidebar -->
|
||
<header role="banner"> <!-- Header -->
|
||
<main role="main" id="main-content"> <!-- Content -->
|
||
```
|
||
|
||
### 常用 ARIA 屬性
|
||
|
||
| 場景 | ARIA |
|
||
|------|------|
|
||
| Sidebar 當前頁 | `aria-current="page"` |
|
||
| Tab 群組 | `role="tablist"` / `role="tab"` / `aria-selected` / `aria-controls` |
|
||
| Modal 開啟時 | `role="dialog"` / `aria-modal="true"` / `aria-labelledby` |
|
||
| Loading 按鈕 | `aria-busy="true"` / `aria-label="載入中"` |
|
||
| 禁用按鈕 | `aria-disabled="true"`(不用 `disabled` 屬性以保留可聚焦性) |
|
||
| Toast | `role="status"`(success/info)/ `role="alert"`(error) |
|
||
| Dropdown | `aria-haspopup="menu"` / `aria-expanded` |
|
||
| Mock badge | `role="status"` / `aria-label="目前為 Mock 模式"` |
|
||
|
||
### 動態內容
|
||
|
||
Live regions 用 `aria-live`:
|
||
|
||
| 場景 | `aria-live` |
|
||
|------|------------|
|
||
| Server 狀態變化 | `polite` |
|
||
| 推論結果更新 | `off`(太頻繁會吵) |
|
||
| 錯誤訊息 | `assertive` |
|
||
| Toast success | `polite` |
|
||
|
||
## 9.5 圖片與圖示
|
||
|
||
| 類型 | 標註 |
|
||
|------|------|
|
||
| 裝飾性圖示 | `aria-hidden="true"` |
|
||
| 功能性圖示(icon only button) | `aria-label="動作描述"` |
|
||
| 資訊性圖片(logo、插圖) | `alt="..."` |
|
||
| 影片 feed(攝影機串流) | `aria-label="即時攝影機畫面"`(無法提供動態描述) |
|
||
| 推論結果 overlay(bounding box) | 獨立顯示為清單,不只靠視覺(見 9.8) |
|
||
|
||
## 9.6 表單
|
||
|
||
- 所有 input 必須有對應的 `<label>`
|
||
- 錯誤訊息用 `aria-describedby` 連結
|
||
- 必填欄位用 `aria-required="true"` + 視覺標記 `*`
|
||
- 驗證時機:`blur`(失去焦點)+ `submit`
|
||
|
||
## 9.7 Reduced Motion
|
||
|
||
偵測 `prefers-reduced-motion: reduce`:
|
||
|
||
```css
|
||
@media (prefers-reduced-motion: reduce) {
|
||
*, *::before, *::after {
|
||
animation-duration: 0.01ms !important;
|
||
transition-duration: 0.01ms !important;
|
||
}
|
||
}
|
||
```
|
||
|
||
**不要**直接禁用所有動畫 — 有些微小回饋(< 100ms)可以保留,只關閉長動畫與 parallax。
|
||
|
||
## 9.8 推論結果的非視覺呈現
|
||
|
||
攝影機串流 + bounding box 對視障使用者幾乎無意義。補償方案:
|
||
|
||
- Inference panel 同步顯示**文字清單**:「偵測到:人 (信心度 92%)、車 (信心度 85%)」
|
||
- 用 `aria-live="polite"` 但節流(每 2 秒更新一次,否則太吵)
|
||
- 提供「暫停語音播報」選項
|
||
|
||
## 9.9 語言與 lang 屬性
|
||
|
||
- HTML `lang` 屬性隨 i18n 動態切換:`<html lang="zh-TW">` 或 `<html lang="en">`
|
||
- 避免混雜未標註語言的文字(如中文頁面中的英文專有名詞用 `<span lang="en">`)
|
||
|
||
## 9.10 測試與驗證(R4-3 後:不列為硬指標)
|
||
|
||
> 本節原先定義 Lighthouse a11y ≥ 95、axe 無 critical/serious 的硬指標,**第四輪 R4-3 後改為「建議但非必要」**。
|
||
|
||
| 工具 | 建議用途(非強制) |
|
||
|------|------------------|
|
||
| axe DevTools | 開發時期手動自檢常見問題(不納入 CI gate) |
|
||
| Lighthouse | 偶爾看一下分數即可(不設最低門檻) |
|
||
| 鍵盤測試 | 主要流程用鍵盤跑過一次(核心流程能通即可) |
|
||
| Screen reader | **不做**(R4-3 明確排除) |
|
||
| 色彩對比 | **不做逐項實測**,依 Design Tokens 的 oklch 色盤視覺合理即可 |
|
||
|
||
**驗收條件**:無硬性 a11y 驗收條件。若 Frontend 實作時有餘力可追加,不強制。
|
||
|
||
## 9.11 與 i18n 的互動
|
||
|
||
中英雙語時注意:
|
||
- 英文版某些標籤可能比中文長(如「繼續」vs「Continue」),設計要容錯
|
||
- 確認 RTL 不是需求範圍(中英都是 LTR,確認後可放心)
|
||
|
||
## 9.12 可忽略範圍(需使用者確認)
|
||
|
||
以下 WCAG 標準因桌面 app 特性可以忽略,列出讓使用者確認:
|
||
|
||
- **1.4.10 Reflow(320px 寬度可用)** — 桌面 app 最小視窗 960px,不支援 320px
|
||
- **2.4.5 Multiple Ways** — 不提供全域搜尋、sitemap(IA 太淺不需要)
|
||
- **3.1.4 Abbreviations** — 某些術語(KL720、FPS、.nef)不提供縮寫展開
|