ベストプラクティス

Angularにおけるアクセシビリティ

ウェブは、視覚または運動障害のある人々を含む、さまざまな人々によって利用されています。 これらのグループがウェブベースのソフトウェアアプリケーションとより簡単にやり取りできるようにする、さまざまな支援技術が利用可能です。 また、アプリケーションをよりアクセシブルに設計することで、一般的にすべてのユーザーのユーザー体験が向上します。

アクセシブルなアプリケーションの設計に関する問題とテクニックの包括的な紹介については、Googleのweb.dev アクセシビリティを学ぶコースを参照してください。

このページでは、支援技術に依存する人々を含むすべてのユーザーにとって適切に機能するAngularアプリケーションを設計するためのベストプラクティスについて説明します。

アクセシビリティ属性

アクセシブルなウェブエクスペリエンスを構築することは、多くの場合、Accessible Rich Internet Applications (ARIA)属性を設定して、そうでなければ欠落しているセマンティックな意味を提供することを伴います。 属性バインディングテンプレート構文を使用して、アクセシビリティ関連属性の値を制御します。

AngularでARIA属性にバインドする場合、attr.プレフィックスを使用する必要があります。ARIA仕様は、DOM要素のプロパティではなく、特にHTML属性に依存します。

      
<!-- ARIA属性にバインドする際はattr.を使用する --><button [attr.aria-label]="myActionLabel">…</button>

注: この構文は、属性バインディングの場合にのみ必要です。 静的ARIA属性には、追加の構文は必要ありません。

      
<!-- 静的ARIA属性には、追加の構文は必要ありません --><button aria-label="Save document">…</button>

HELPFUL: 慣習的に、HTML属性は小文字の名前を使用します (tabindex)、一方プロパティはcamelCaseの名前を使用します (tabIndex)。

属性とプロパティの違いの詳細については、バインディング構文ガイドを参照してください。

Angular UIコンポーネント

Angularチームが保守しているAngular Materialライブラリは、完全なアクセシビリティを目指した、再利用可能なUIコンポーネントのスイートです。 Component Development Kit (CDK)には、アクセシビリティのさまざまな領域をサポートするためのツールを提供するa11yパッケージが含まれています。 例えば:

  • LiveAnnouncerは、aria-live領域を使用して、スクリーンリーダーユーザーにメッセージを発表するために使用されます。 aria-live領域の詳細については、W3Cのドキュメントを参照してください。

  • cdkTrapFocusディレクティブは、Tabキーのフォーカスを要素内に閉じ込めておきます。 モーダルダイアログなど、フォーカスを制限する必要があるコンポーネントのアクセシブルなエクスペリエンスを作成するために使用します。

これらのツールやその他のツールの詳細については、Angular CDKアクセシビリティの概要を参照してください。

ネイティブ要素の拡張

ネイティブHTML要素は、アクセシビリティにとって重要な、いくつかの標準的な相互作用パターンを捉えています。 Angularコンポーネントを作成する際には、サポートされている動作を再実装するのではなく、可能な限りこれらのネイティブ要素を直接再利用する必要があります。

たとえば、新しい種類のボタンのカスタム要素を作成するのではなく、ネイティブ<button>要素で属性セレクターを使用するコンポーネントを作成します。 これは、<button><a>に最もよく適用されますが、他の多くのタイプの要素で使用できます。

このパターンの例は、Angular Materialで見ることができます: MatButtonMatTabNav、およびMatTable

ネイティブ要素のためのコンテナの使用

ネイティブ要素を使用するには、コンテナ要素が必要になる場合があります。 たとえば、ネイティブの<input>要素は子を持たせることができないため、カスタムテキスト入力コンポーネントは<input>を余分な要素でラップする必要があります。 <input>をカスタムコンポーネントのテンプレートに含めるだけで、コンポーネントのユーザーは<input>要素に任意のプロパティや属性を設定できません。 代わりに、コンテンツプロジェクションを使用してコンポーネントのAPIにネイティブコントロールを含む、コンテナコンポーネントを作成します。

MatFormFieldは、このパターンの例として見ることができます。

ケーススタディ: カスタムプログレスバーの構築

次の例は、ホストバインディングを使用してアクセシビリティ関連属性を制御することで、プログレスバーをアクセシブルにする方法を示しています。

  • コンポーネントは、標準のHTML属性roleとARIA属性の両方を持つ、アクセシビリティ対応の要素を定義します。 ARIA属性aria-valuenowは、ユーザーの入力にバインドされます。
  • テンプレートでは、aria-label属性により、コントロールはスクリーンリーダーにとってアクセシブルになります。
      
1import {Component, Input} from '@angular/core';23/**4 * Example progressbar component.5 */6@Component({7  standalone: true,8  selector: 'app-example-progressbar',9  template: '<div class="bar" [style.width.%]="value"></div>',10  styleUrls: ['./progress-bar.component.css'],11  host: {12    // Sets the role for this component to "progressbar"13    role: 'progressbar',1415    // Sets the minimum and maximum values for the progressbar role.16    'aria-valuemin': '0',17    'aria-valuemax': '100',1819    // Binding that updates the current value of the progressbar.20    '[attr.aria-valuenow]': 'value',21  },22})23export class ExampleProgressbarComponent {24  /** Current value of the progressbar. */25  @Input() value = 0;26}2728
      
1<h1>Accessibility Example</h1>2<label for="progress-value">3  Enter an example progress value4  <input id="progress-value" type="number" min="0" max="100"5      [value]="progress" (input)="setProgress($event)">6</label>78<!-- The user of the progressbar sets an aria-label to communicate what the progress means. -->9<app-example-progressbar [value]="progress" aria-label="Example of a progress bar">10</app-example-progressbar>1112

ルーティング

ナビゲーション後のフォーカス管理

UIにおけるフォーカスの追跡と制御は、アクセシビリティを考慮する上で重要な要素です。 Angularルーティングを使用する場合は、ページナビゲーション時にページフォーカスがどこに移動するかを決定する必要があります。

視覚的な手がかりだけに頼らないようにするには、ルーティングコードがページナビゲーション後にフォーカスを更新することを確認する必要があります。 NavigationEndイベントをRouterサービスから使用して、フォーカスを更新するタイミングを把握します。

次の例は、ナビゲーション後にDOM内のメインコンテンツヘッダーを見つけてフォーカスする方法を示しています。

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

実際のアプリケーションでは、フォーカスを受け取る要素は、特定のアプリケーションの構造とレイアウトによって異なります。 フォーカスされる要素は、ユーザーを、ちょうどビューにルーティングされたメインコンテンツにすぐに移動できる位置に置く必要があります。 ルート変更後にフォーカスがbody要素に戻るような状況は避ける必要があります。

アクティブリンクの識別

RouterLinkActiveなど、アクティブなRouterLink要素に適用されるCSSクラスは、アクティブなリンクを視覚的に識別するための手がかりを提供します。 残念ながら、視覚的な手がかりは、盲人または視覚障害のあるユーザーには役立ちません。 要素にaria-current属性を適用すると、アクティブなリンクを識別するのに役立ちます。 詳細については、Mozilla Developer Network (MDN) aria-currentを参照してください。

RouterLinkActiveディレクティブは、リンクがアクティブになるとaria-currentを指定された値に設定するariaCurrentWhenActive入力を提供します。

次の例は、アクティブなリンクにactive-pageクラスを適用する方法と、アクティブになったときに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>

詳細情報

書籍

  • "A Web for Everyone: Designing Accessible User Experiences", Sarah Horton and Whitney Quesenbery
  • "Inclusive Design Patterns", Heydon Pickering