填寫這份《一分鐘調查》,幫我們(開發組)做得更好!去填寫Home

Angular 中的無障礙功能

Accessibility in Angular

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

The web is used by a wide variety of people, including those who have visual or motor impairments. A variety of assistive technologies are available that make it much easier for these groups to interact with web-based software applications. In addition, designing an application to be more accessible generally improves the user experience for all users.

關於如何設計無障礙應用的問題和技術的深入介紹,請參閱 Google 網路基礎知識無障礙功能部分。

For an in-depth introduction to issues and techniques for designing accessible applications, see the Accessibility section of the Google's Web Fundamentals.

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

This page discusses best practices for designing Angular applications that work well for all users, including those who rely on assistive technologies.

本頁所描述的範例程式,參閱現場演練 / 下載範例

For the sample app that this page describes, see the現場演練 / 下載範例.

無障礙屬性(Attribute)

Accessibility attributes

建立無障礙的 Web 體驗通常會涉及設定 ARIA 屬性(Attribute) 以提供可能會丟失的語義。使用 [Attribute 繫結](guide/attribute-binding範本語法來控制與無障礙性相關的屬性(Attribute)值。

Building accessible web experience often involves setting ARIA attributes to provide semantic meaning where it might otherwise be missing. Use attribute binding template syntax to control the values of accessibility-related attributes.

在 Angular 中繫結 ARIA 屬性(Attribute)時,必須使用 attr. 字首,因為 ARIA 規範針對的是 HTML 屬性(Attribute),而不是 DOM 元素的屬性(Property)。

When binding to ARIA attributes in Angular, you must use the attr. prefix, as the ARIA specification depends specifically on HTML attributes rather than properties of DOM elements.

<!-- Use attr. when binding to an ARIA attribute --> <button [attr.aria-label]="myActionLabel">...</button>
      
      <!-- Use attr. when binding to an ARIA attribute -->
<button [attr.aria-label]="myActionLabel">...</button>
    

注意,此語法僅對於屬性(Attribute)繫結是必需的。靜態 ARIA 屬性(Attribute)不需要額外的語法。

Note that this syntax is only necessary for attribute bindings. Static ARIA attributes require no extra syntax.

<!-- Static ARIA attributes require no extra syntax --> <button aria-label="Save document">...</button>
      
      <!-- Static ARIA attributes require no extra syntax -->
<button aria-label="Save document">...</button>
    

注意:

NOTE:

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

By convention, HTML attributes use lowercase names (tabindex), while properties use camelCase names (tabIndex).

關於 Attribute 和 Property 之間差異的更多背景資訊,請參閱[範本語法](guide/html-attribute-vs-dom-property一章。

See the Binding syntax guide for more background on the difference between attributes and properties.

Angular UI 元件

Angular UI components

由 Angular 團隊維護的 Angular Material 函式庫是旨在提供完全無障礙的一組可複用 UI 元件。元件開發工具套件(CDK)中包括 a11y 軟體套件,該軟體套件提供了支援無障礙領域的各種工具。例如:

The Angular Material library, which is maintained by the Angular team, is a suite of reusable UI components that aims to be fully accessible. The Component Development Kit (CDK) includes the a11y package that provides tools to support various areas of accessibility. For example:

  • LiveAnnouncer 用於使用 aria-live 區域向螢幕閱讀器使用者朗讀訊息。關於 aria-live 領域的更多資訊,請參閱 W3C 文件。

    LiveAnnouncer is used to announce messages for screen-reader users using an aria-live region. See the W3C documentation for more information on aria-live regions.

  • cdkTrapFocus 指令能將 Tab 鍵焦點捕獲在元素內。使用它可為必須限制焦點的模態對話方塊之類別的元件建立無障礙體驗。

    The cdkTrapFocus directive traps Tab-key focus within an element. Use it to create accessible experience for components like modal dialogs, where focus must be constrained.

關於這些工具和其它工具的完整詳細資訊,請參閱 Angular CDK 無障礙功能概述

For full details of these and other tools, see the Angular CDK accessibility overview.

增強原生元素

Augmenting native elements

原生 HTML 元素捕獲了許多對無障礙性很重要的標準互動模式。在製作 Angular 元件時,應儘可能直接複用這些原生元素,而不是重新實現已獲良好支援的行為。

Native HTML elements capture a number of standard interaction patterns that are important to accessibility. When authoring Angular components, you should re-use these native elements directly when possible, rather than re-implementing well-supported behaviors.

例如,你可以建立一個元件,它使用屬性(Attribute)選擇器指向原生 <button> 元素,而不是為各種新按鈕建立自訂元素。通常這適用於 <button><a>,但也可以用於許多其它型別的元素。

For example, instead of creating a custom element for a new variety of button, you can create a component that uses an attribute selector with a native <button> element. This most commonly applies to <button> and <a>, but can be used with many other types of element.

你可以在 Angular Material 中看到此模式的範例:MatButtonMatTabNavMatTable

You can see examples of this pattern in Angular Material: MatButton, MatTabNav, MatTable.

將容器用於原生元素

Using containers for native elements

有時要使用的原生元素需要一個容器元素。例如,原生 <input> 元素不能有子元素,因此任何自訂的文字輸入元件都需要用其它元素來包裝 <input>。儘管你可能只在自訂元件的範本中包含 <input>,但這將使該元件的使用者無法為 input 元素設定任意 Property 和 Attribute。相反,你可以建立一個使用內容投影的容器元件,以將原生控制元件包含在元件的 API 中。

Sometimes using the appropriate native element requires a container element. For example, the native <input> element cannot have children, so any custom text entry components need to wrap an <input> with additional elements. While you might just include the <input> in your custom component's template, this makes it impossible for users of the component to set arbitrary properties and attributes to the input element. Instead, you can create a container component that uses content projection to include the native control in the component's API.

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

You can see MatFormFieldas an example of this pattern.

案例研究:建構自訂進度條

Case study: Building a custom progress bar

以下範例顯示如何透過使用宿主(host)繫結來控制與無障礙性相關的屬性(Attribute),來把簡單的進度條無障礙化。

The following example shows how to make a simple progress bar accessible by using host binding to control accessibility-related attributes.

  • 該元件使用標準的 HTML 屬性(Attribute)role 和 ARIA 屬性(Attribute)來定義要啟用無障礙支援的元素。ARIA 屬性(Attribute)aria-valuenow 繫結到使用者的輸入。

    The component defines an accessibility-enabled element with both the standard HTML attribute role, and ARIA attributes. The ARIA attribute aria-valuenow is bound to the user's input.

    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; }
    src/app/progress-bar.component.ts
          
          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)可以確保螢幕閱讀器能訪問該控制元件。

    In the template, the aria-label attribute ensures that the control is accessible to screen readers.

    <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>
    src/app/app.component.html
          
          <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>
        

路由和焦點管理

Routing and focus management

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

Tracking and controlling focus in a UI is an important consideration in designing for accessibility. When using Angular routing, you should decide where page focus goes upon navigation.

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

To avoid relying solely on visual cues, you need to make sure your routing code updates focus after page navigation. Use the NavigationEnd event from the Router service to know when to update focus.

以下範例顯示了導航後如何在 DOM 中查詢並把焦點移動到主體內容的頭部。

The following example shows how to find and focus the main content header in the DOM after navigation.

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

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

In a real application, the element that receives focus will depend on your specific application structure and layout. The focused element should put users in a position to immediately move into the main content that has just been routed into view. You should avoid situations where focus returns to the body element after a route change.

額外資源

Additional resources

圖書

Books

  • "A Web for Everyone: Designing Accessible User Experiences", Sarah Horton and Whitney Quesenbery

  • "Inclusive Design Patterns", Heydon Pickering

關於無障礙性的更多資訊

More on accessibility

你可能也對以下內容感興趣:

You may also be interested in the following: