打造更容易使用的 Angular 應用程式

1. 事前準備

黑色 Angular 標誌

無障礙設計是網頁開發的重要一環,可確保使用者能夠感知、理解、瀏覽及與應用程式互動。事實上,每 4 位美國成人中,就有 1 位有影響主要生活活動的障礙。全球約有 15% 的人口 (超過 10 億人) 具有某些形式的身心障礙,約 2% 至 4% 則受嚴重困難。

影響使用者使用網路的常見情況包括失明或視障、失聰或聽障、動作技巧受限、認知障礙和色盲等,這只是其中一部分。

在本課程中,a11y 是無障礙的簡寫字詞。請注意,a 後面接著 11 個字元和一個 y

如要深入瞭解設計無障礙應用程式時會遇到的問題和技巧,請參閱「無障礙功能」。

建構項目

  • 在示範 Dumpling Shop Angular 應用程式時,使用最佳做法和內建技巧解決常見的網站無障礙問題
  • 符合所有無障礙規範 (WCAG 2.0 和 ARIA 1.2),並通過軸線和 Lighthouse 無障礙稽核措施。

以粉紅色和紅色為主題的 Dumpling Time 商店網站 以紫色和綠色為主題的 Dumpling Time 商店網站

課程內容

您將瞭解 Angular 應用程式中八個常見的無障礙問題,以及如何識別及修正這些問題。具體來說,你是:

  • 使用 Google Chrome 開發人員工具、Lighthouse 和 axe 檢查應用程式的無障礙功能
  • 透過獨特的網頁標題解決單頁應用程式 (SPA) 陷阱
  • 修正低視力使用者的低色彩對比問題
  • 使用語意式 HTML,確保螢幕閱讀器能正確瀏覽網頁
  • 使用 Angular Material 和解除巢狀結構控制項,確保螢幕閱讀器能夠存取所有控制項
  • 為螢幕閱讀器新增 ARIA 支援
  • 匯入及使用 Angular CDK a11y 套件
  • 使用 FocusTrap 為自訂元件螢幕閱讀器導覽功能
  • 透過 CDK LiveAnnouncer 廣播通知
  • 偵測使用高對比模式的使用者,並實作高對比主題

軟硬體需求

2. 做好準備

取得程式碼

本專案所需的所有內容都位於 GitHub 存放區中。如要開始使用,請複製程式碼,然後在您偏好的開發環境中開啟程式碼。

複製存放區並提供應用程式

建議您使用 VSCode 或本機 IDE 完成本程式碼研究室。

  1. 開啟新的瀏覽器分頁,然後前往 https://github.com/googlecodelabs/angular-accessibility
  2. 分支並複製存放區,然後將 cd angular-accessibility/ 複製到存放區。
  3. 請查看範例程式碼分支 git checkout get-started
  4. 在 VSCode 或您偏好的 IDE 中開啟程式碼。
  5. 執行 npm install 以安裝執行伺服器所需的依附元件。
  6. 執行 ng serve 來執行伺服器。
  7. 開啟瀏覽器分頁並前往 http://localhost:4200

3. 建立基準

從哪裡開始?

您要從專為本次程式碼研究室所設計的基本餐廳應用程式開始。程式碼經過簡化,可顯示本程式碼研究室中的概念,但功能有限。

以紫色和綠色為主題的 Dumpling Time 商店網站

探索示範模式

如要開始使用,請逐步操作應用程式的三項功能:

  1. 使用導覽列查看「我們的商店」、「我們的品牌故事」和「查看我們的位置」路線,並查看餃子公司的詳細資料。
  2. 變更主題,切換淺色和深色模式。
  3. 自訂訂單的餃子內餡、數量和顏色。
  4. 選取「Purchase」(購買) 即可在控制台中記錄您的自訂訂單。

使用 Angular 解決常見的網站無障礙問題

在本程式碼研究室中,您將著重於這個應用程式現有功能的無障礙性。您將先找出應用程式中的 a11y 問題,然後導入解決方案,將「🛑?」變更為「✅」。

如何知道要修正哪些問題?

首先,請同時執行手動和自動測試,從中找出無障礙功能問題。

在網路的現行狀態下,你必須手動測試 Google 的無障礙程度。

您有可識別無障礙問題的工具,但沒有任何工具可以保證應用程式完全符合無障礙設計。手動測試可確保您測試的 a11y 概念範圍廣泛,包括邏輯內容順序和功能相容性。

手動測試

如要手動測試本課程中的無障礙功能,請開啟電腦內建的螢幕閱讀器,然後使用鍵盤導覽應用程式。詳情請參閱「語意和螢幕閱讀器」。

開啟螢幕閱讀器並瀏覽畫面,練習操作。

你可以使用 macOS 內建的 VoiceOver。依序點選「系統偏好設定」>「輔助使用」>「VoiceOver」>「啟用 VoiceOver 即可啟用」。如要切換 VoiceOver,請按住 Command 鍵,然後快速按三下 Touch ID。

在本課程中,您主要會手動測試問題,並使用自動化工具協助檢查特定可自動化功能。

自動化測試

您也可以使用幾個開發工具來自動化及稽核應用程式。這些工具可讓您檢查圖片是否有替代文字,或文字顏色的對比度。您可以將這些工具視為 lint 工具;雖然這些工具可以辨識是否有替代文字,但您必須手動檢查內容是否合乎邏輯且提供價值。

Lighthouse 和 Chrome 開發人員工具

  1. 開啟 Chrome 開發人員工具。
  2. 勾選「Lighthouse」分頁標籤,然後勾選「無障礙設定」核取方塊。
  3. 按一下「產生報表」,執行 11y Lighthouse 稽核。

Lighthouse 範例分頁,其中包含在 Chrome 開發人員工具分頁中產生報表的按鈕

斧頭

  1. 安裝 axe 開發人員工具擴充功能。您可能需要重新啟動瀏覽器才能看到擴充功能。
  2. 開啟 Chrome 開發人員工具。
  3. 選取「axe 開發人員工具」分頁標籤,然後選取「Scan all of my page」執行 axe 開發人員工具掃描。

Linting

您可以使用 Angular ESLint 規則檢查程式碼,以便自動化 a11y 屬性。

eslint.json 中新增下列適用於無障礙功能的內容:

"@angular-eslint/template/accessibility-alt-text": 2,
"@angular-eslint/template/accessibility-elements-content": 2,
"@angular-eslint/template/accessibility-label-for": 2,
"@angular-eslint/template/no-positive-tabindex": 2,
"@angular-eslint/template/accessibility-table-scope": 2,
"@angular-eslint/template/accessibility-valid-aria": 2,
"@angular-eslint/template/click-events-have-key-events": 2,
"@angular-eslint/template/mouse-events-have-key-events": 2,
"@angular-eslint/template/no-autofocus": 2,
"@angular-eslint/template/no-distracting-elements": 2

詳情請參閱 GitHub 上的最新 ESLint 規則。

您的起點

您可以使用新的測試方法,透過 Lighthouse 和 axe 稽核以及手動 VoiceOver 來找出應用程式中的下列問題:

Chrome 開發人員工具 Lighthouse 稽核分數為 82

無障礙稽核:

  • 🛑? 所有網頁的網頁標題都相同
  • 🛑? 元素必須有足夠的色彩對比
  • 🛑? HTML 應有邏輯順序、名稱和角色
  • 🛑? 螢幕閱讀器無法選取巢狀核取方塊
  • 🛑? 螢幕閱讀器無法讀取滑桿值
  • 🛑? 顏色挑選器的螢幕閱讀器焦點會離開對話方塊
  • 🛑? 不會顯示變更、錯誤和通知
  • 🛑? 高對比模式未啟用

4. 定義獨特網頁標題

提供獨特且簡潔的網頁標題,有助於使用 a11y 服務的使用者快速瞭解網頁內容和用途。網頁標題對於視覺障礙使用者至關重要,因為這是螢幕閱讀軟體朗讀的第一個網頁元素。

Angular 是單頁應用程式,因此大部分的轉場效果 (例如移至新頁面) 都不會重新載入網頁。這意味著每個網頁都有相同的網頁標題,無法提供任何資訊,讓使用者瞭解網頁的內容或用途。

在 Angular 14 中,Router 新增了內建方法,可在開箱即用模式下定義不重複的網頁標題。輕鬆確保開發人員遵循網頁標題最佳做法。

本節結束時,應用程式就會通過下列稽核:

  • 🛑? 所有網頁的網頁標題都相同

你可以在註解下方找到以下各個步驟:TODO: #4. Define unique page titles.

找出問題

如要找出這個問題,請開啟螢幕閱讀器,並在「我們的商店」、「我們的故事」和「尋找我們」分頁之間查看網頁標題:

  1. 開啟旁白功能。
  2. 使用分頁導覽功能瀏覽不同頁面。
  3. 確認網頁標題在 Angular 中一律為 a11y。

這是因為網頁標題必須是唯一的,讓使用者不必瀏覽網頁,就能快速瞭解網頁內容。

Chrome 瀏覽器上有三個分頁開啟,頁面標題相同:「a11y in Angular」

加入有意義的網頁標題

如果您希望管理頁面標題或檢視變更,就必須妥善管理頁面標題。如要修正這個問題,請使用 Angular 內建的 Router.title 屬性,為每個網頁定義專屬的標題。

  1. 為三個已定義的路徑分別新增標題:

src/app/app-routing.module.ts

const routes: Routes = [
  { path: 'shop', component: ShopComponent, title: 'Our Shop – a11y in Angular' },
  { path: 'about', component: AboutComponent, title: 'Our Story - a11y in Angular' },
  { path: 'locate', component: LocationComponent, title: 'Find Us - a11y in Angular' },
  { path: '',   redirectTo: '/shop', pathMatch: 'full' },
  { path: '**', component: ShopComponent },
];

這會自動匯入並使用 Router's Title Service,管理導覽中頁面標題的變更作業,以便與路徑中定義的標題屬性相符。您也可以使用自訂 TitleStrategy 管理更複雜的網頁標題。

驗證變更

重新開啟螢幕閱讀器,並驗證變更。網頁現在應該有獨特的標題!

Chrome 瀏覽器,開啟三個分頁,每個分頁都有獨特的頁面標題:「Our Shop - a11y in Angular」、「Our Story - a11y in Angular」、「Find Us - a11y in Angular」

無障礙稽核:

  • 所有網頁都有獨特的網頁標題
  • 🛑? 元素必須有足夠的色彩對比
  • 🛑? HTML 應有邏輯順序、名稱和角色
  • 🛑? 螢幕閱讀器無法選取巢狀核取方塊
  • 🛑? 螢幕閱讀器無法讀取滑桿值
  • 🛑? 顏色挑選器的螢幕閱讀器焦點會離開對話方塊
  • 🛑? 不會顯示變更、錯誤和通知
  • 🛑? 高對比模式未啟用

5. 確保充足的色彩對比

您的設計也許看起來很酷,但這並不適合視障人士 (例如色盲) 使用者閱讀您的內容。無障礙網頁內容規範 (WCAG 2.0) 定義了一系列色彩對比度比率,確保內容可供存取。在 Angular 和網頁版中,您可以定義調色盤,確保元件符合這些標準,當低視能和色盲使用者都能看到。

完成本節後,您的應用程式將通過以下稽核:

  • 🛑? 元素必須有足夠的色彩對比

您可以在註解下方找到這些步驟:TODO: #5. Ensure adequate color contrast.

使用 Chrome 開發人員工具找出低對比問題

如要找出這個問題,請使用 Chrome 開發人員工具檢查應用程式中的元素。

  1. 使用檢查工具查看選單圖示按鈕。您可以看到對比度為 1.85,遠低於 WCAG 規定

Chrome 開發人員工具檢查主畫面按鈕的元素 (對比度偏低)

  1. 在 Lighthouse 或 ax 的掃描中執行無障礙稽核,查看對比率問題。

Chrome 開發人員工具 Lighthouse 稽核結果顯示錯誤:「背景和前景顏色沒有足夠的對比度」

變更 Material 主題顏色

元件色彩配置是在自訂 Material Design 主題中定義。您將根據色彩對比度規範更新主題值。

更新 Material Design 主題,使用顏色較深的文字顏色,提高圖示的對比度:

src/styles.scss

$light-primary: mat.define-palette(mat.$pink-palette, $default: A100, $lighter: 100, $text: 900);

此外,您也可以使用 Chrome 開發人員工具內建的無障礙工具,尋找符合標準的顏色,或是在 Sass 中更新個別色彩值。

驗證變更

再次檢查元素並確認變更,我們的主題現在應該具有足夠的色彩對比率!

Chrome 開發人員工具:檢查主畫面按鈕的元素,但對比度足夠

無障礙稽核

  • 所有網頁都有不重複的網頁標題
  • 顏色的對比度充足
  • 🛑? HTML 應有邏輯順序、名稱和角色
  • 🛑? 螢幕閱讀器無法選取巢狀核取方塊
  • 🛑? 螢幕閱讀器無法讀取滑桿值
  • 🛑? 顏色挑選器的螢幕閱讀器焦點會離開對話方塊
  • 🛑? 不會顯示變更、錯誤和通知
  • 🛑? 未啟用高對比模式

6. 使用語意 HTML

原生 HTML 元素可擷取多種對無障礙設計至關重要的標準互動模式。雖然段落可以設為 span 樣式,div 可以設為按鈕樣式,但語意 HTML 元素可確保螢幕閱讀器和鍵盤導覽功能瞭解 HTML 的互動和控制項。

編寫 Angular 元件時,請盡可能直接重複使用這些原生元素,而非重新實作已廣泛支援的行為。這可確保網頁具有良好的內容結構和自然的內容流程,且分頁排列順序合理,有助使用者有效運用鍵盤瀏覽網站。

完成本節後,您的應用程式將通過以下稽核:

  • 🛑? HTML 應有邏輯順序、名稱和角色

你可以在留言下方找到以下各項步驟:TODO: #6. Use Semantic HTML.

找出問題

  1. 開啟「旁白」。
  2. 使用分頁導覽前往「我們的故事」分頁。
  3. 請注意,分頁順序並非依序排列。
  4. 按一下「購買」
  5. 請注意,系統並未將該按鈕視為按鈕。

Chrome 開發人員工具 Lighthouse 稽核結果有誤:標題元素並未依序以遞減順序排列。排序正確且未略過層級的標題可傳達網頁的語意結構,讓使用者在運用輔助技術時更容易瀏覽及理解。瞭解詳情。

將 <div> 變更為 <button>

將自訂的 <div> 替換為 Material 按鈕:

src/app/shop/shop.component.html

<button mat-flat-button 
  color="primary" 
  class="purchase-button"
  (click)="fauxPurchase()">
  Purchase
</button>

依序使用標題元素

重新排序文字,使用語意式 HTML,並套用 Angular Material 字體排版

src/app/about/about.component.html

<h2>Who are we?</h2>
<p class="mat-subheading-2">Have you ever thought, "wow, I love dumplings"?</p>
<p class="right mat-subheading-1">Who hasn't.</p>
<p class="center mat-subheading-1">We took it one step further and created Dumpling Dumpling,</p> 
<p class="center mat-subheading-1">double the dumpling, double the fun.</p>
<div class="spacer"></div>
<h2>How are we different?</h2>
<p class="mat-subheading-2">Handmade in San Francisco, California, we craft fully customizable dumplings. Glitter? Rainbows? Vegan? We do it all.</p>
<p class="right mat-subheading-2">This shop is concept only.</p>

驗證變更

再次開啟螢幕閱讀器,確認變更內容。VoiceOver 現在可以辨識按鈕,文字會依邏輯順序讀出!

無障礙稽核:

  • 所有網頁都有獨特的網頁標題
  • 顏色的對比度充足
  • 語意式 HTML 可確保邏輯互動
  • 🛑? 螢幕閱讀器無法選取巢狀核取方塊
  • 🛑? 螢幕閱讀器無法讀取滑桿值
  • 🛑? 顏色挑選器的螢幕閱讀器焦點會離開對話方塊
  • 🛑? 不會顯示變更、錯誤和通知
  • 🛑? 高對比模式未啟用

7. 使用 Angular Material 建立可選取的控制項

巢狀控制項,是無障礙服務的一種複雜互動模式。建議您考慮選單子項目或巢狀核取方塊,如何向使用者表示您可以選取子選項群組或前往上層選單項目?

在 Angular 中,盡可能簡化控制項,以便建立可供瀏覽的元件。在這個範例中,您會使用 Angular Material 的 listbox 建立一個互動模式的範例。

完成本節後,您的應用程式將通過以下稽核:

  • 🛑? 螢幕閱讀器無法選取巢狀核取方塊

您可以在註解下方找到這些步驟:TODO: #7. Create selectable controls with Angular Material.

找出問題

為了找出這個問題,我們會開啟螢幕閱讀器,並嘗試選取巢狀核取方塊。

  1. 開啟旁白功能。
  2. 選取不同的內餡口味。
  3. 請注意,當 VoiceOver 朗讀時,上層核取方塊不會指定子項。您是否知道,先前未勾選「Bok Choy」核取方塊,但未勾選「Vegan」核取方塊?

含有選項的 [填充式] 核取方塊選單:供應純素肉醬起司薯條和柴燒雞肉

Angular Material 中的 A11y

您可以將語意核取方塊替換為 Angular Material 核取方塊,後者內建此互動模式的知識。請注意,將元件替換為 Material Design 無法保證無障礙功能。如同任何其他元件,您必須手動測試,因為無錯導入 Material 的方法有很多種。

以 Material 核取方塊取代核取方塊

  1. 首先,請新增內餡清單和變數,用來儲存所選內餡口味:

src/app/shop/shop.component.ts

@Component(...)
export class ShopComponent implements OnInit {
  fillings: string[] = ['Bok Choy & Chili Crunch', 'Tofu & Mushroom', 'Chicken & Ginger', 'Impossible Meat & Spinach'];
  selectedFillings: string[] = [];

  fauxPurchase(): void {
    let flavor = '';
    this.selectedFillings.forEach(filling => {
      flavor = flavor + " " + filling
    })
  }
}
  1. 新增 <mat-selection-list> 以取代這個混亂的 HTML 核取方塊:

src/app/shop/shop.component.html

<mat-selection-list [(ngModel)]="selectedFillings" 
  aria-label="Dumpling fillings">
  <mat-list-option *ngFor="let flavor of fillings" 
    [value]="flavor" 
    color="primary">
    {{ flavor }}
  </mat-list-option>
</mat-selection-list>

TODO 註解也會顯示您可以在 src/app/shop/shop.component.scss 中移除哪些未使用的 Sass,以便清理樣式。

驗證變更

再次開啟螢幕閱讀器,確認變更內容。核取方塊現在可供選取,螢幕閱讀器使用起來更加直覺!

實況盒子菜單內含品項:炸蔬菜牛肉和辣椒三明治豆腐,

無障礙稽核:

  • 所有網頁都有獨特的網頁標題
  • 顏色的對比度充足
  • 語意式 HTML 可確保邏輯互動
  • 螢幕閱讀器可存取所有控制項
  • 🛑? 螢幕閱讀器無法讀取滑桿值
  • 🛑? 顏色挑選器的螢幕閱讀器焦點會離開對話方塊
  • 🛑? 不會顯示變更、錯誤和通知
  • 🛑? 未啟用高對比模式

8. 使用 ARIA 提供控制項標籤

您修改了 Angular 應用程式的語意 HTML 和 Material 元件,但部分元件需要特定屬性,才能讓螢幕閱讀器完整瀏覽。

Web Accessibility Initiative 的無障礙互動式網頁應用程式規格 (WAI-ARIA 或 ARIA) 可協助解決無法透過原生 HTML 管理的問題。它可讓您指定屬性,以修改元素轉換為無障礙樹狀結構的方式。

完成本節後,您的應用程式將通過以下稽核:

  • 🛑? 螢幕閱讀器無法讀取滑桿值

您可以在註解下方找到這些步驟:TODO: #8. Provide control labels with ARIA.

找出問題

如要找出這個問題,請開啟螢幕閱讀器並移動滑桿:

  1. 開啟「旁白」。
  2. 前往數量滑桿並變更值。
  3. 請注意,值標籤已遺失。

Chrome 開發人員工具 Lighthouse 稽核結果顯示錯誤:ARIA 輸入欄位沒有可解讀的名稱。如果沒有可解讀的輸入欄位名稱,螢幕閱讀器只會讀出通用名稱,這樣仰賴螢幕閱讀器的使用者就無法使用這個輸入欄位。瞭解詳情。

使用 ARIA 屬性

使用 aria-label 來控制標籤:<mat-slider>

src/app/shop/shop.component.html

<mat-slider
  aria-label="Dumpling order quantity slider"
  id="quantity"
  name="quantity"
  color="primary"
  class="quantity-slider"
  [max]="13"
  [min]="1"
  [step]="1"
  [tickInterval]="1"
  thumbLabel
  [(ngModel)]="quantity">
</mat-slider>

驗證變更

重新開啟螢幕閱讀器,並驗證變更。您現在可以移動滑桿了!

Chrome 開發人員工具 Lighthouse 稽核,通過螢幕閱讀器 ARIA 控制項稽核。

無障礙稽核:

  • 所有網頁都有獨特的網頁標題
  • 顏色的對比度充足
  • 語意式 HTML 可確保邏輯互動
  • 螢幕閱讀器可存取所有控制項
  • 滑桿使用 ARIA 屬性提供標籤
  • 🛑? 色彩挑選器中的螢幕閱讀器焦點會退出對話方塊
  • 🛑? 不會顯示變更、錯誤和通知
  • 🛑? 高對比模式未啟用

9. 加入 @angular/cdk/a11y 的強大功能

到目前為止,您一直是使用內建的 Angular 工具來修正常見的 a11y 問題。接下來,我們來看看 CDK 的 a11y 模組,以及它如何協助我們解決更複雜的 Angular 相關問題。

在本節結束後,您將繼續學習 Angular a11y 模組工具。

您可以在註解下方找到這些步驟:TODO: #9. Add the power of @angular/cdk/a11y.

匯入模組

將模組新增至應用程式:

src/app/app.module.ts

import { A11yModule } from '@angular/cdk/a11y';

@NgModule({
  declarations: [...],
  imports: [
    A11yModule
  ],
  providers: [...],
  bootstrap: [...]
})

'@angular/cdk/a11y' 的作用

a11y 模組提供多種工具來改善無障礙功能,特別適合元件作者使用。

在後續章節中,您將新增三項常見服務:FocusTrap、LiveAnnouncer 和 HighContrast。

如要進一步瞭解 @angular/cdk/a11y 提供的所有其他服務,請參閱「無障礙」一文。

10. 使用 FocusTrap 控制焦點

開啟對話方塊或模態時,使用者只能在其中進行互動。允許焦點逃離對話方塊會混淆情境,並導致使用者不知道自己在頁面上的所在位置。

在 Angular 中,cdkTrapFocus 指令會在元素中擷取 tab- 按鍵焦點。這項功能可用於建立可供存取的體驗,適用於必須限制焦點的元件,例如模式對話方塊。

完成本節後,您的應用程式將通過以下稽核:

  • 🛑? 顏色挑選器的螢幕閱讀器焦點會離開對話方塊

您可以在留言下方找到相關步驟:TODO: #10. Control focus with FocusTrap.

找出問題

如要找出這項問題,請開啟螢幕閱讀器,然後開啟顏色挑選器對話方塊。

  1. 開啟旁白功能。
  2. 使用分頁導覽功能變更顏色。
  3. 請查看色彩挑選器中的直覺焦點順序和焦點陷阱。

以紫色和綠色為主題的 Dumpling Time 商店網站,其中顯示對話方塊,可用來選取餃子的包裝顏色

新增 FocusTrap

cdkFocusTrap 可用於在自訂元件中擷取及控管焦點順序。只要使用 mat-dialog-content,即可在對話方塊中捕捉焦點,解決大多數問題。新增屬性 cdkFocusInitial,以定義顏色挑選器對話方塊中的傾印包裝函式顏色 <mat-selection-list> 的初始焦點區域。

src/app/shop/color-picker/color-picker-dialog/color-picker-dialog.component.html

<mat-selection-list #colors aria-label="Dumpling wrapper color" multiple="false" cdkFocusInitial>
  ...
</mat-selection-list>

驗證變更

再次開啟螢幕閱讀器,確認變更內容。對話方塊中的「焦點」選項現已設為「變更顏色」

無障礙稽核:

  • 所有網頁都有獨特的網頁標題
  • 顏色的對比度充足
  • 語意式 HTML 可確保邏輯互動
  • 螢幕閱讀器可存取所有控制項
  • 滑桿使用 ARIA 屬性提供標籤
  • 顏色挑選器有正確的焦點陷阱
  • 🛑? 不會顯示變更、錯誤和通知
  • 🛑? 未啟用高對比模式

11. 透過 LiveAnnouncer 宣布變更消息

當頁面內容有所變更時,需要通知螢幕閱讀器。想像一下,嘗試提交表單或完成購買,卻不知道彈出式視窗為何導致無法提交表單。這太讓人困擾了!

LiveAnnouncer 會使用 aria-live 區域,為螢幕閱讀器使用者朗讀訊息,確保螢幕閱讀器能收到通知和即時網頁變更的通知。如要進一步瞭解 aria-live 區域,請參閱 W3C 的 WAI-ARIA。在 Angular 中,呼叫 LiveAnnouncer 做為服務,比 aria-live 屬性更容易測試。

完成本節後,您的應用程式將通過以下稽核:

  • 🛑? 不會顯示變更、錯誤和通知

您可以在留言下方找到這些步驟:TODO: #11. Announce changes with LiveAnnouncer.

找出問題

如要找出這個問題,請開啟螢幕閱讀器,然後在表單欄位內選取「購買」

  1. 開啟「旁白」。
  2. 使用分頁導覽功能變更顏色,並進行假購買交易。
  3. 請注意,當您關閉對話方塊且未讀取購買交易時,系統不會顯示所選顏色。

以粉紅色和紅色主題的 Dumpling Time 網站網站顯示對話方塊,供使用者選擇餃子包裝顏色

在程式碼中加入 LiveAnnouncer

新增 LiveAnnouncer,然後以字串宣告顏色選項和假購買交易。在實際導入作業中,系統可能會在您前往第三方付款系統或發生表單錯誤時讀取這項資訊。

  1. 在選取顏色時新增公告:

src/app/shop/color-picker/color-picker-dialog/color-picker-dialog.component.ts

import { LiveAnnouncer } from '@angular/cdk/a11y';

@Component(...)
export class ColorPickerDialogComponent implements OnInit {
  constructor(
    public dialogRef: MatDialogRef<ColorPickerDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: ColorDialogData,
    private liveAnnouncer: LiveAnnouncer) { }

  public changeColor(color: string): void {
    this.liveAnnouncer.announce(`Select color: ${color}`);
    this.dialogRef.close();
  }
}
  1. 在假購買交易發生時新增通知:

src/app/shop/shop.component.ts

import { LiveAnnouncer } from '@angular/cdk/a11y';

@Component(...)
export class ShopComponent implements OnInit {

  constructor(private liveAnnouncer: LiveAnnouncer) { }

  fauxPurchase(): void {
    let flavor = '...';
    const fakePurchase = `Purchase ${this.quantity} ${flavor}dumplings in the color ${this.color}!`;

    this.liveAnnouncer.announce(fakePurchase);
  }
}

驗證變更

重新開啟螢幕閱讀器,並驗證變更。系統現在會通知你錯誤!

無障礙稽核:

  • 所有網頁都有獨特的網頁標題
  • 顏色的對比度充足
  • 語意式 HTML 可確保邏輯互動
  • 螢幕閱讀器可存取所有控制項
  • 滑桿使用 ARIA 屬性提供標籤
  • 顏色挑選器已正確設定聚焦陷阱
  • 宣布變更、錯誤和通知
  • 🛑? 高對比模式未啟用

12. 啟用高對比模式

Microsoft Windows 支援「高對比模式」無障礙功能,這個模式會變更所有應用程式 (包括網頁應用程式) 的外觀,以大幅提高對比度。在 Angular 中,您希望應用程式能尊重使用者的偏好設定。

HighContrastModeDetector 可讓您判斷瀏覽器目前是否處於高對比模式。

Internet Explorer、Microsoft Edge 和 Firefox 支援這個模式。Google Chrome 不支援 Windows 高對比模式。這項服務不會偵測 Chrome 高對比瀏覽器擴充功能新增的高對比模式。

本節結束時,應用程式就會通過下列稽核:

  • 🛑? 未啟用高對比模式

您可以在留言下方找到相關步驟:TODO: #12. Enable HighContrast mode.

找出問題

如要找出這個問題,請在 Internet Explorer、Microsoft Edge 或 Firefox 中開啟應用程式,開啟高對比模式,看看是否有變化:

  1. 在 Internet Explorer、Microsoft Edge 或 Firefox 中開啟應用程式。
  2. 開啟高對比模式。
  3. 請注意,應用程式沒有變更。

新增高對比模式支援功能

styles.scss 中,請使用 @angular/cdk/a11y 提供的 cdk-high-contrast 混合函式,在高對比模式下為按鈕新增外框:

src/app/shop/shop.component.scss

@use '@angular/cdk';

.purchase-button {
    border-radius: 5px;
    background-color: mat.get-color-from-palette(mat.$pink-palette, A100);

    @include cdk-high-contrast {
      outline: solid 1px;
      background-color: mat.get-color-from-palette(mat.$pink-palette, 50);
    }
}

:host-context(.dark-theme) {
  .purchase-button {
    background-color: mat.get-color-from-palette(mat.$light-green-palette, A100);

    @include cdk-high-contrast {
      outline: solid 1px;
      background-color: mat.get-color-from-palette(mat.$light-green-palette, 50);
    }
  }
}

驗證變更

請重新整理應用程式並驗證變更。您已在高對比模式中為按鈕加入外框!

「抽樣時間」商品網站以紅色和粉紅色主題顯示,並開啟高對比模式,購買按鈕現在也顯示粗框深的紅色輪廓 藍色和綠色主題的「抽樣時間店」網站,開啟「高對比模式」,購買按鈕現在則顯示粗藍色外框

無障礙稽核:

  • 所有網頁都有獨特的網頁標題
  • 顏色的對比度充足
  • 語意式 HTML 可確保邏輯互動
  • 螢幕閱讀器可存取所有控制項
  • 滑桿使用 ARIA 屬性提供標籤
  • 顏色挑選器已正確設定聚焦陷阱
  • 會發布變更、錯誤和通知
  • 已啟用高對比模式

13. 恭喜!

恭喜!您已解決 Angular 應用程式中常見的網路無障礙問題!🎉

如要查看所有解決方案,請檢查 main 分支。

以紅色和粉紅色為主題的 Dumpling Time 商店網站,顯示在本程式碼研究室中所做的所有變更 藍色和綠色主題的 Dumpling Time Shop 網站顯示本程式碼研究室的所有變更 Chrome 開發人員工具 Lighthouse 稽核,分數為 100/100

您現在已瞭解解決 Angular 應用程式中八個常見 a11y 陷阱的重要步驟。

瞭解詳情

請參閱下列程式碼研究室:

請參閱下列資料: