Angular 無障礙性

2022-07-13 10:34 更新

Angular 中的無障礙功能

Web 會被各種各樣的人使用,包括有視覺或運動障礙的人。有多種輔助技術能使這些人更輕松地和基于 Web 的軟件應用進行交互。另外,將應用設計得更易于訪問通常也能改善所有用戶的體驗。

關于如何設計無障礙應用的問題和技術的深入介紹,參閱 Google 網(wǎng)絡基礎知識無障礙功能部分。

本頁討論了設計 Angular 應用的最佳實踐,這些實踐對所有用戶(包括依賴輔助技術的用戶)都適用。

本頁中所講的范例程序,參閱現(xiàn)場演練 / 下載范例

無障礙屬性(Attribute)

建立無障礙的 Web 體驗通常會涉及設置 ARIA 屬性(Attribute) 以提供可能會丟失的語義。使用 Attribute 綁定模板語法來控制與無障礙性相關的屬性(Attribute)值。

在 Angular 中綁定 ARIA 屬性(Attribute)時,必須使用 ?attr.? 前綴,因為 ARIA 規(guī)范針對的是 HTML 屬性(Attribute),而不是 DOM 元素的屬性(Property)。

<!-- Use attr. when binding to an ARIA attribute -->
<button [attr.aria-label]="myActionLabel">…</button>
注意
此語法僅對于屬性(Attribute)綁定是必需的。靜態(tài) ARIA 屬性(Attribute)不需要額外的語法。
<!-- Static ARIA attributes require no extra syntax -->
<button aria-label="Save document">…</button>

按照約定,HTML 屬性(Attribute)使用小寫名稱(?tabindex?),而 Property 使用 camelCase 名稱(?tabIndex?)。

Angular UI 組件

由 Angular 團隊維護的 Angular Material 庫是旨在提供完全無障礙的一組可復用 UI 組件。組件開發(fā)工具包(CDK)中包括 a11y 軟件包,該軟件包提供了支持無障礙領域的各種工具。比如:

  • ?LiveAnnouncer ?用于使用 ?aria-live? 區(qū)域向屏幕閱讀器用戶朗讀消息。關于 aria-live 領域的更多信息,參閱 W3C 文檔。
  • ?cdkTrapFocus ?指令能將 Tab 鍵焦點捕獲在元素內。使用它可為必須限制焦點的模態(tài)對話框之類的組件創(chuàng)建無障礙體驗。

關于這些工具和其它工具的完整詳細信息,參閱 Angular CDK 無障礙功能概述。

增強原生元素

原生 HTML 元素捕獲了許多對無障礙性很重要的標準交互模式。在制作 Angular 組件時,應盡可能直接復用這些原生元素,而不是重新實現(xiàn)已獲良好支持的行為。

比如,你可以創(chuàng)建一個組件,它使用屬性(Attribute)選擇器指向原生 ?<button>? 元素,而不是為各種新按鈕創(chuàng)建自定義元素。通常這適用于 ?<button>? 和 ?<a>?,但也可以用于許多其它類型的元素。

你可以在 Angular Material 中看到此模式的范例:MatButton,MatTabNavMatTable。

將容器用于原生元素

有時要使用的原生元素需要一個容器元素。比如,原生 ?<input>? 元素不能有子元素,因此任何自定義的文本輸入組件都需要用其它元素來包裝 ?<input>?。盡管你可能只在自定義組件的模板中包含 ?<input>?,但這將使該組件的用戶無法為 ?input ?元素設置任意 Property 和 Attribute。相反,你可以創(chuàng)建一個使用內容投影的容器組件,以將原生控件包含在組件的 API 中。

你可以把 MatFormField 作為該模式的例子。

案例研究:構建自定義進度條

以下范例顯示如何通過使用宿主(host)綁定來控制與無障礙性相關的屬性(Attribute),來把進度條無障礙化。

  • 該組件使用標準的 HTML 屬性(Attribute)?role ?和 ARIA 屬性(Attribute)來定義要啟用無障礙支持的元素。ARIA 屬性(Attribute)?aria-valuenow? 綁定到用戶的輸入。
  • import { Component, Input } from '@angular/core';
    
    /**
     * Example progressbar component.
     */
    @Component({
      selector: 'app-example-progressbar',
      template: '<div class="bar" [style.width.%]="value"></div>',
      styleUrls: ['./progress-bar.component.css'],
      host: {
        // Sets the role for this component to "progressbar"
        role: 'progressbar',
    
        // Sets the minimum and maximum values for the progressbar role.
        'aria-valuemin': '0',
        'aria-valuemax': '100',
    
        // Binding that updates the current value of the progressbar.
        '[attr.aria-valuenow]': 'value',
      }
    })
    export class ExampleProgressbarComponent  {
      /** Current value of the progressbar. */
      @Input() value = 0;
    }
  • 在模板中,?aria-label? 屬性(Attribute)可以確保屏幕閱讀器能訪問該控件。
  • <label>
      Enter an example progress value
      <input type="number" min="0" max="100"
          [value]="progress" (input)="setProgress($event)">
    </label>
    
    <!-- The user of the progressbar sets an aria-label to communicate what the progress means. -->
    <app-example-progressbar [value]="progress" aria-label="Example of a progress bar">
    </app-example-progressbar>

路由

導航后的焦點管理

在設計無障礙性時,在 UI 中跟蹤和控制焦點是很重要的考慮因素。使用 Angular 路由時,你需要確定頁面焦點在導航上的位置。

為了避免僅僅依靠視覺提示,你需要確保路由代碼會在頁面導航之后更新焦點。使用 ?Router ?服務中的 ?NavigationEnd ?事件可以知道何時該更新焦點。

以下范例顯示了導航后如何在 DOM 中查找并把焦點移動到主體內容的頭部。

router.events.pipe(filter(e => e instanceof NavigationEnd)).subscribe(() => {
  const mainHeader = document.querySelector('#main-content-header')
  if (mainHeader) {
    mainHeader.focus();
  }
});

在實際的應用程序中,哪些元素獲得焦點將取決于該應用特有的結構和布局。獲得焦點的元素應使用戶能夠立即移動到剛剛進入視野的主要內容。你應該避免當路由變化后焦點重新回到 ?body ?元素的情況。

活動鏈接標識

用在活躍 ?RouterLink ?元素上的 CSS 類(一般通過 ?RouterLinkActive ?來指定)提供了有關哪個鏈接正處于活躍狀態(tài)的視覺指示。此類指示不適用于盲人或視障用戶,為了提供此類信息,還要將 ?aria-current? 屬性應用于此元素(有關更多信息,參閱MDN aria-current)。

?RouterLinkActive ?指令提供了 ?ariaCurrentWhenActive ?輸入屬性,該輸入屬性會在鏈接變?yōu)榛钴S狀態(tài)時將 ?aria-current? 設置為指定的值。

以下示例展示了如何將 ?active-page? 類應用于活躍鏈接,以及如何在它們處于活躍狀態(tài)時將它們的 ?aria-current? 屬性設置為 ?"page"? :

<nav>
  <a routerLink="home"
     routerLinkActive="active-page"
     ariaCurrentWhenActive="page">
    Home
  </a>
  <a routerLink="about"
     routerLinkActive="active-page"
     ariaCurrentWhenActive="page">
    About
  </a>
  <a routerLink="shop"
     routerLinkActive="active-page"
     ariaCurrentWhenActive="page">
    Shop
  </a>
</nav>


以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號