Communitygithub.com

Blaise1030/astro-marketing

根據 WCAG 2.2 指南稽核並改善網頁無障礙性。當被要求「改善無障礙性」、「a11y 稽核」、「WCAG 合規」、「螢幕閱讀器支援」、「鍵盤導航」或「讓內容可供存取」時使用。

astro-marketing 是什麼?

這個技能提供了一個基於證據的無障礙稽核工作流程,專門針對 Web 開發和 AI 代理(如 Claude Code、Cursor 等)進行最佳化。使用者可以對已渲染的頁面執行即時 Lighthouse 無障礙稽核,並根據失敗的稽核節點精確定位相關元件,而無需搜尋整個程式碼庫。當 Live 工具不可用時,它會回退到 Lighthouse CLI 或 axe 進行自動化測試。該技能以 WCAG 2.2 的 POUR 原則(可感知、可操作、可理解、穩健)為基礎,涵蓋從文字替代方案、色彩對比(AA/AAA)、鍵盤可存取性、焦點可見性、目標尺寸到 ARIA 使用等所有內容。重點強調使用原生的、語義化的 HTML 元素,只有在必要時才使用 ARIA,並提供實際的程式碼範例和測試清單。它包括 WCAG 2.2 的新成功標準,例如焦點未被遮蔽(2.4.11)、目標尺寸(2.5.8)、拖曳動作(2.5.7)、一致的說明(3.2.6)、冗餘輸入(3.3.7)和可存取的驗證(3.3.8)。此技能支援 Chrome DevTools MCP(用於 lighthouse_audit 和 take_snapshot),也支援獨立的 CLI 工具。最終目標是讓每個人都能使用內容,包括身障人士,自動化評分並不等於 WCAG 合規——人工檢查是必要的。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Blaise1030/astro-marketing/tree/HEAD/.agents/skills/accessibility

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

預覽

來自技能 README

astro-marketing preview
astro-marketing preview
astro-marketing preview

說明文件

無障礙性 (a11y)

基於 WCAG 2.2 和 Lighthouse 無障礙稽核的全面無障礙指南。目標:讓每個人都能使用內容,包括身障人士。

基於證據的稽核工作流程

當有已渲染的頁面時:

  1. 在該功能可用時,執行即時 Lighthouse 無障礙稽核;使用 Chrome DevTools MCP 時,請使用 lighthouse_audit。對於一般公開頁面,使用行動導航模式;當重新載入會遺失已驗證或用戶建立的狀態時,使用快照模式。
  2. 使用失敗的稽核節點來定位相關元件或模板,而不是在整個儲存庫中搜尋通用模式。
  3. 檢查已渲染的無障礙樹快照,以取得名稱、角色、狀態、地標和標題結構;使用 Chrome DevTools MCP 時,請使用 take_snapshot。使用鍵盤操作受影響的流程。
  4. 修正來源,然後重新執行相同的稽核和手動互動。

如果 Live 工具不可用,請使用 Lighthouse CLI 或 axe 進行自動化覆蓋,並完成相同的⼿動檢查。自動化工具只能偵測一部分的無障礙障礙:滿分 100 並不等於 WCAG 合規,低分數也不能取代基於問題的證據。

WCAG 原則:POUR

原則說明
P 可感知 (Perceivable)內容可以透過不同的感官來感知
O 可操作 (Operable)介面可供所有使用者操作
U 可理解 (Understandable)內容和介面是可理解的
R 穩健 (Robust)內容可與輔助技術相容使用

符合性等級

等級要求目標
A最低無障礙性必須通過
AA標準合規應該通過(在許多司法管轄區是法律要求)
AAA增強無障礙性有則更好

可感知 (Perceivable)

文字替代方案 (1.1)

圖片需要替代文字:

<!-- ❌ 缺少 alt -->
<img src="chart.png">

<!-- ✅ 描述性 alt -->
<img src="chart.png" alt="長條圖顯示第三季銷售額成長 40%">

<!-- ✅ 裝飾性圖片(空的 alt) -->
<img src="decorative-border.png" alt="" role="presentation">

<!-- ✅ 複雜圖片配有更長的說明 -->
<figure>
  <img src="infographic.png" alt="2024 市場趨勢資訊圖表" 
       aria-describedby="infographic-desc">
  <figcaption id="infographic-desc">
    <!-- 詳細說明 -->
  </figcaption>
</figure>

圖示按鈕需要可存取的名稱:

<!-- ❌ 沒有可存取的名稱 -->
<button><svg><!-- 選單圖示 --></svg></button>

<!-- ✅ 使用 aria-label -->
<button aria-label="開啟選單">
  <svg aria-hidden="true"><!-- 選單圖示 --></svg>
</button>

<!-- ✅ 使用視覺上隱藏的文字 -->
<button>
  <svg aria-hidden="true"><!-- 選單圖示 --></svg>
  <span class="visually-hidden">開啟選單</span>
</button>

視覺上隱藏的類別:

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

色彩對比 (1.4.3, 1.4.6)

文字大小AA 最低要求AAA 增強要求
一般文字 (< 18px / < 14px 粗體)4.5:17:1
大型文字 (≥ 18px / ≥ 14px 粗體)3:14.5:1
UI 元件與圖形3:13:1
/* ❌ 對比度不足 (2.5:1) */
.low-contrast {
  color: #999;
  background: #fff;
}

/* ✅ 足夠的對比度 (7:1) */
.high-contrast {
  color: #333;
  background: #fff;
}

/* ✅ 焦點狀態也需要對比度 (相對於背景為 3:1,WCAG 1.4.11) */
:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

不要僅依靠顏色:

<!-- ❌ 僅用顏色指示錯誤 -->
<input class="error-border">
<style>.error-border { border-color: red; }</style>

<!-- ✅ 顏色 + 圖示 + 文字 -->
<div class="field-error">
  <input aria-invalid="true" aria-describedby="email-error">
  <span id="email-error" class="error-message">
    <svg aria-hidden="true"><!-- 錯誤圖示 --></svg>
    請輸入有效的電子郵件地址
  </span>
</div>

媒體替代方案 (1.2)

<!-- 帶有字幕的影片 -->
<video controls>
  <source src="video.mp4" type="video/mp4">
  <track kind="captions" src="captions.vtt" srclang="en" label="English" default>
  <track kind="descriptions" src="descriptions.vtt" srclang="en" label="Descriptions">
</video>

<!-- 帶有逐字稿的音訊 -->
<audio controls>
  <source src="podcast.mp3" type="audio/mp3">
</audio>
<details>
  <summary>逐字稿</summary>
  <p>完整的逐字稿文字...</p>
</details>

可操作 (Operable)

鍵盤可存取 (2.1)

所有功能必須可透過鍵盤存取。 優先使用原生的互動元素 — <button>、<a href> 和表單控制項會自動處理 Enter/Space 觸發、焦點和輔助技術語義。只有在無法使用原生元素時,才需要加入⼿動鍵盤處理。

<!-- ❌ 非互動元素僅有點擊:不可聚焦,無鍵盤觸發 -->
<div class="card" onclick="handleAction()">開啟</div>

<!-- ✅ 最佳做法:使用原生按鈕 -->
<button type="button" onclick="handleAction()">開啟</button>
// ✅ 當你「必須」使用非互動元素時(例如帶有 role="button" 的 div),
// 使其可聚焦並處理鍵盤觸發。不要在原生 <button> 上執行此操作 — 
// Enter/Space 已經會觸發 click,這樣會導致雙重觸發。
element.setAttribute('role', 'button');
element.setAttribute('tabindex', '0');
element.addEventListener('click', handleAction);
element.addEventListener('keydown', (e) => {
  if (e.key === 'Enter' || e.key === ' ') {
    e.preventDefault();
    handleAction();
  }
});

沒有鍵盤陷阱。 使用者必須能夠使用 Tab 鍵進入和退出每個元件。對於對話框,請使用模態焦點陷阱模式—原生的 <dialog> 元素會自動處理此問題。

焦點可見 (2.4.7)

/* ❌ 永遠不要移除焦點外框 */
*:focus { outline: none; }

/* ✅ 使用 :focus-visible 來實現僅限鍵盤的焦點 */
:focus {
  outline: none;
}

:focus-visible {
  outline: 2px solid currentColor; /* 繼承文字顏色 → 已經過對比度檢查 */
  outline-offset: 2px;
}

/* ✅ 或者選擇品牌顏色,並驗證其與所有著陸背景的對比度 ≥3:1 */
button:focus-visible {
  box-shadow: 0 0 0 3px rgba(0, 95, 204, 0.5);
}

焦點未被遮蔽 (2.4.11) — WCAG 2.2 新增

當元素收到鍵盤焦點時,不能完全被其他作者建立的內容(例如固定頁首、頁尾或重疊的面板)隱藏。在 AAA 等級 (2.4.12) 中,焦點元素的任何部分都不得被隱藏。

/* ✅ 在捲動到焦點元素時,考慮固定頁首的影響 */
:target {
  scroll-margin-top: 80px;
}

/* ✅ 確保焦點項目避開固定/黏性工具列 */
:focus {
  scroll-margin-top: 80px;
  scroll-margin-bottom: 60px;
}

跳轉連結 (2.4.1)

提供跳轉連結,讓鍵盤使用者可以跳過重複的導航。有關完整的標記和樣式,請參閱跳轉連結模式。

目標尺寸 (2.5.8) — WCAG 2.2 新增

互動目標的尺寸必須至少為 24 × 24 CSS 像素 (AA)。例外情況:內聯文字連結、瀏覽器控制大小的元素,以及以邊界框為中心的 24px 圓形未與另一個目標重疊的目標。

/* ✅ 最小目標尺寸 */
button,
[role="button"],
input[type="checkbox"] + label,
input[type="radio"] + label {
  min-width: 24px;
  min-height: 24px;
}

/* ✅ 舒適的目標尺寸(建議 44×44) */
.touch-target {
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

拖曳動作 (2.5.7) — WCAG 2.2 新增

任何需要拖曳的動作都必須有單一指標的替代方案(例如按鈕、輸入)。有關可排序清單的範例,請參閱拖曳動作模式。

時間限制 (2.2)

// 允許使用者延長時間限制
function showSessionWarning() {
  const modal = createModal({
    title: '工作階段即將到期',
    content: '您的工作階段將在 2 分鐘後到期。',
    actions: [
      { label: '延長工作階段', action: extendSession },
      { label: '登出', action: logout }
    ],
    timeout: 120000
  });
}

動作 (2.3)

/* 尊重減少動作的偏好 */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

可理解 (Understandable)

頁面語言 (3.1.1)

<!-- ❌ 未指定語言 -->
<html>

<!-- ✅ 已指定語言 -->
<html lang="en">

<!-- ✅ 頁面內的語言變更 -->
<p>法語中的「你好」是 <span lang="fr">bonjour</span>。</p>

一致的導航 (3.2.3)

<!-- 導航應在各頁面間保持一致 -->
<nav aria-label="Main">
  <ul>
    <li><a href="/" aria-current="page">首頁</a></li>
    <li><a href="/products">產品</a></li>
    <li><a href="/about">關於</a></li>
  </ul>
</nav>

一致的說明 (3.2.6) — WCAG 2.2 新增

如果某個說明機制(聯絡資訊、聊天小工具、常見問題連結、自助選項)在多個頁面上重複出現,則每次必須以相同的相對順序出現。依賴一致位置的用戶不應該在每個頁面上搜尋協助。

表單標籤 (3.3.2)

每個輸入都需要一個程式碼關聯的標籤。有關明確、隱含和指示性範例,請參閱表單標籤模式。

錯誤處理 (3.3.1, 3.3.3)

使用 role="alert" 或 aria-live 向螢幕閱讀器宣布錯誤,在無效欄位上設定 aria-invalid="true",並在提交時將焦點放在第一個錯誤上。有關完整的標記和 JS,請參閱錯誤處理模式。

冗餘輸入 (3.3.7) — WCAG 2.2 新增

不要強迫使用者重新輸入他們在同一工作階段中已提供的資訊。從先前的步驟自動填入,或讓使用者從先前輸入的值中選擇。例外情況:安全重新確認和已過期的內容。

<!-- ✅ 從帳單地址自動填入送貨地址 -->
<fieldset>
  <legend>送貨地址</legend>
  <label>
    <input type="checkbox" id="same-as-billing" checked>
    與帳單地址相同
  </label>
  <!-- 勾選時自動填入欄位 -->
</fieldset>

可存取的驗證 (3.3.8) — WCAG 2.2 新增

登入流程不得依賴認知功能測試(例如記住密碼、解決謎題),除非至少符合以下條件之一:

  • 提供複製貼上或自動填入機制
  • 存在替代方法(例如通行金鑰、SSO、電子郵件連結)
  • 測試使用物體辨識或個人內容(僅 AA;AAA 移除此例外)
<!-- ✅ 允許在密碼欄位貼上 -->
<input type="password" id="password" autocomplete="current-password">

<!-- ✅ 提供無密碼替代方案 -->
<button type="button">使用通行金鑰登入</button>
<button type="button">寄送登入連結給我</button>

穩健 (Robust)

ARIA 使用 (4.1.2)

優先使用原生元素:

<!-- ❌ 在 div 上使用 ARIA 角色 -->
<div role="button" tabindex="0">點擊我</div>

<!-- ✅ 原生按鈕 -->
<button>點擊我</button>

<!-- ❌ ARIA 核取方塊 -->
<div role="checkbox" aria-checked="false">選項</div>

<!-- ✅ 原生核取方塊 -->
<label><input type="checkbox"> 選項</label>

當需要 ARIA 時, 使用正確的角色和狀態。有關完整的頁籤清單範例,請參閱 ARIA 頁籤模式。

即時區域 (4.1.3)

使用 aria-live 區域來宣布動態內容變更,而無需移動焦點。有關標記和 showNotification() 輔助程式,請參閱即時區域模式。


測試檢查清單

自動化測試

優先使用能夠直接將失敗的渲染節點回傳給代理程式的即時 Lighthouse 稽核。使用 Chrome DevTools MCP 時,這是 lighthouse_audit。否則:

# Lighthouse 無障礙稽核
npx lighthouse https://example.com --only-categories=accessibility

# axe-core
npm install @axe-core/cli -g
axe https://example.com

手動測試

  • 鍵盤導航: 使用 Tab 鍵瀏覽整個頁面,使用 Enter/Space 鍵觸發
  • 螢幕閱讀器: 使用 VoiceOver (Mac)、NVDA (Windows) 或 TalkBack (Android) 進行測試
  • 縮放: 在 200% 縮放下內容可用
  • 高對比度: 使用 Windows 高對比度模式測試
  • 減少動作: 使用 prefers-reduced-motion: reduce 進行測試
  • 焦點順序: 符合邏輯並遵循視覺順序
  • 目標尺寸: 互動元素符合 24×24px 的最小要求

請參閱螢幕閱讀器指令參考,了解 VoiceOver 和 NVDA 的快捷鍵。


依影響程度分類的常見問題

嚴重(立即修復)

  1. 缺少表單標籤
  2. 缺少圖片替代文字
  3. 色彩對比不足
  4. 鍵盤陷阱
  5. 沒有焦點指示器

重要(上線前修復)

  1. 缺少頁面語言
  2. 缺少標題結構
  3. 無描述性的連結文字
  4. 自動播放媒體
  5. 缺少跳轉連結

中度(盡快修復)

  1. 圖示上缺少 ARIA 標籤
  2. 導航不一致
  3. 缺少錯誤識別
  4. 時間限制無控制項
  5. 缺少地標區域

參考資料

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

相關技能