CSSが十分でない場合:アクセシブルなコンポーネントのJavaScript要件
公開: 2022-03-10ModernCSS.devの作成者として、私はCSSソリューションの大きな支持者です。 そして、私は人々が本当にすぐに使えるデザインと双方向性のためにCSSを使用する巧妙な方法を見るのが大好きです! ただし、「チェックボックスハック」などの方法を使用して「CSSのみ」のコンポーネントを宣伝する傾向に気づきました。 残念ながら、このようなハッキングにより、かなりの数のユーザーがインターフェースを使用できなくなります。
この記事では、いくつかの一般的なコンポーネントと、JavaScriptの要件を詳しく説明することでアクセシビリティをカバーするのにCSSでは不十分な理由について説明します。 これらの要件は、Webコンテンツアクセシビリティガイドライン(WCAG)とアクセシビリティの専門家による追加の調査に基づいています。 JavaScriptソリューションやデモCSSを規定するのではなく、各コンポーネントを作成するときに何を考慮する必要があるかを調べます。 JavaScriptフレームワークは確かに使用できますが、説明したイベントや機能を追加するために必要ではありません。
リストされている要件は、概してオプションではなく、コンポーネントのアクセシビリティを確保するために必要です。
フレームワークまたはコンポーネントライブラリを使用している場合は、この記事を使用して、提供されているコンポーネントがアクセシビリティ要件を満たしているかどうかを評価できます。 記載されている項目の多くは、aXeなどの自動アクセシビリティテストツールでは完全にはカバーされないため、手動テストが必要であることを知っておくことが重要です。 または、サイプレスなどのテストフレームワークを使用して、必要な機能のテストを作成できます。
この記事は、各インターフェースコンポーネントのJavaScriptに関する考慮事項を通知することに焦点を当てていることに注意してください。 これは、必要なariaやマークアップなど、完全にアクセス可能なコンポーネントを作成するためのすべての実装の詳細に関する包括的なリソースではありません。 各コンポーネントの幅広い考慮事項についてさらに学習するのに役立つリソースが、タイプごとに含まれています。
CSSのみが適切な解決策であるかどうかの判断
CSSのみのソリューションに進む前に、いくつか質問する必要があります。 ここで紹介する用語のいくつかを、関連するコンポーネントとともに、より多くのコンテキストで説明します。
- これはあなた自身の楽しみのためですか?
次に、CSSに完全に取り組み、限界を押し広げ、言語で何ができるかを学びましょう。 - この機能には、コンテンツの表示と非表示が含まれていますか?
次に、JSが少なくともariaを切り替え、Esc
で閉じることができるようにする必要があります。 状態も変化する特定のタイプのコンポーネントの場合、ARIAライブリージョン内で更新をトリガーすることによって変更を伝達する必要がある場合もあります。 - 自然なフォーカスの順序が最も理想的ですか?
自然な順序でトリガーとトリガーされた要素の関係が失われた場合、またはキーボードユーザーが自然なタブの順序でコンテンツにアクセスできない場合は、フォーカス管理を支援するJSが必要です。 - 定型化されたコントロールは、機能に関する正しい情報を提供しますか?
スクリーンリーダーなどの支援技術のユーザーは、セマンティクスとARIAに基づいた情報を受け取り、コントロールの機能を判断するのに役立ちます。 また、音声認識のユーザーは、コントロールの操作に使用するフレーズを理解するために、コンポーネントのラベルまたはタイプを識別できる必要があります。 たとえば、コンポーネントがタブのようなスタイルであるが、ラジオボタンを使用してタブのように「機能」する場合、スクリーンリーダーに「ラジオボタン」が聞こえ、音声ユーザーが「タブ」という単語を使用して操作しようとする場合があります。 このような場合、適切なコントロールとセマンティクスを使用して目的の機能を実現できるようにするには、JSが必要です。 - 効果はホバーやフォーカスに依存していますか?
次に、特にタッチスクリーンユーザーや200%以上のデスクトップズームまたは拡大ソフトウェアを使用しているユーザーに、コンテンツへの同等のアクセスまたは永続的なアクセスを提供するための代替ソリューションを支援するためにJSが必要になる場合があります。
クイックヒント:カスタマイズされたコントロールを作成する際のもう1つのリファレンスは、W3の「ARIAの使用」ガイドのカスタムコントロールでアクセス可能な開発チェックリストです。 これは、いくつかの追加の設計とセマンティックの考慮事項とともに、上記のいくつかのポイントに言及しています。
ツールチップ
ツールチップの定義を絞り込むのは少し注意が必要ですが、このセクションでは、トリガー要素の近くでマウスホバーに表示される小さなテキストラベルについて説明します。 それらは他のコンテンツをオーバーレイし、インタラクションを必要とせず、ユーザーがホバーまたはフォーカスを削除すると消えます。
ここでのCSSのみのソリューションは完全に問題ないように見えるかもしれませんが、次のような方法で実行できます。
<button class="tooltip-trigger">I have a tooltip</button> <span class="tooltip">Tooltip</span> .tooltip { display: none; } .tooltip-trigger:hover + .tooltip, .tooltip-trigger:focus + .tooltip { display: block; }
ただし、これはアクセシビリティの懸念事項のかなりのリストを無視し、多くのユーザーがツールチップコンテンツにアクセスすることを除外します。
除外されるユーザーの大規模なグループは、タッチスクリーンを使用しているユーザーです。タッチスクリーンでは、 :hover
イベントが:focus
イベントと同期してトリガーされるため、: :hover
がトリガーされない可能性があります。 これは、ボタンやリンクなど、トリガー要素に接続されている関連アクションが、表示されているツールチップと一緒に起動することを意味します。 これは、ユーザーがツールチップを見逃したり、その内容を読む時間がない可能性があることを意味します。
ツールチップがイベントのないインタラクティブな要素にアタッチされている場合、ツールチップは表示されますが、別の要素がフォーカスを取得するまで閉じられない場合があり、その間、コンテンツがブロックされ、ユーザーがタスクを実行できなくなる場合があります。
さらに、ナビゲートするためにズームまたは拡大ソフトウェアを使用する必要があるユーザーは、ツールチップを使用することへのかなりの障壁も経験します。 ツールチップはホバー時に表示されるため、これらのユーザーが画面をパンしてツールチップを読み取ることで視野を変更する必要がある場合は、ツールチップが表示されなくなる可能性があります。 ツールチップは、ツールチップが事前に表示されることをユーザーに通知するものがない場合が多いため、ユーザーからの制御も削除します。 コンテンツのオーバーレイにより、タスクを実行できなくなる可能性があります。 フォームフィールドに関連付けられたツールチップなどの状況では、モバイルまたはその他のオンスクリーンキーボードがツールチップのコンテンツを覆い隠す可能性があります。 また、トリガー要素に適切に接続されていない場合、一部の支援技術ユーザーは、ツールチップが表示されたことさえ知らない可能性があります。
ツールチップの動作に関するガイダンスは、WCAG Success Criterion 1.4.13 —ホバーまたはフォーカスに関するコンテンツから得られます。 この基準は、弱視のユーザーやズームおよび倍率ソフトウェアを使用しているユーザーを支援することを目的としています。 ツールチップ(およびホバーとフォーカスに表示されるその他のコンテンツ)の基本原則は次のとおりです。
- 却下可能
ホバーやフォーカスを移動せずにツールチップを閉じることができます - ホバブル
表示されたツールチップのコンテンツは、消えることなくホバーできます - 持続的
追加のコンテンツはタイムアウトに基づいて消えることはありませんが、ユーザーがホバーまたはフォーカスを削除するか、その他の方法でコンテンツを閉じるのを待ちます
これらのガイドラインを完全に満たすには、特にコンテンツを却下できるようにするために、JavaScriptの支援が必要です。
- 支援技術のユーザーは、却下の動作がJavaScriptリスナーを必要とするEscキーに関連付けられていると想定します。
- 次のセクションで説明するSarahHigleyの調査によると、ツールチップ内に表示可能な「閉じる」ボタンを追加するには、JavaScriptがその閉じるイベントを処理する必要もあります。
- ユーザーがマウスを動かしているときにツールチップのコンテンツを閉じることなく、ユーザーがツールチップのコンテンツにカーソルを合わせることができるように、JavaScriptでスタイリングソリューションを拡張する必要がある場合があります。
ツールチップの代替
ツールチップは最後の手段である必要があります。 ツールチップの使用を思いとどまらせることに特に情熱を持っているアクセシビリティの専門家であるSarahHigleyは、次の簡単なテストを提供しています。
「なぜこのテキストをUIに追加するのですか? 他にどこに行けますか?」
—プレゼンテーション「ツールチップ:4つの部分への調査」のSarah Higley
サラがマイクロソフトでの役割のために関与した調査に基づくと、代替ソリューションは専用の「トグレティップ」です。 基本的に、これは、ユーザーが追加のコンテンツの表示と非表示を意図的にトリガーできるようにする追加の要素を提供することを意味します。 ツールチップとは異なり、トグルチップは表示されたコンテンツ内の要素のセマンティクスを保持できます。 また、ユーザーはそれらを切り替える制御を取り戻すことができ、より多くのユーザー、特にタッチスクリーンユーザーによる発見可能性と操作性を維持できます。
title
属性が存在することを覚えている場合は、CSSのみのソリューションで指摘したのと同じ問題が発生することを知っておいてください。 言い換えると、許容できるツールチップソリューションであるという前提でtitle
を使用しないでください。
詳細については、YouTubeでのSarahのプレゼンテーションと、ツールチップに関する彼女の広範な記事を確認してください。 ツールチップとトグルチップの詳細、およびtitle
を使用しない理由の詳細については、「包括的コンポーネント:ツールチップとトグルチップ」のHeydonPickeringの記事を参照してください。
モーダル
モーダル(ライトボックスまたはダイアログとも呼ばれます)は、トリガーアクションの後に表示されるページはめ込みウィンドウです。 それらは他のページコンテンツをオーバーレイし、追加のアクションを含む構造化された情報を含む場合があり、モーダルウィンドウをページの他の部分と区別するのに役立つ半透明の背景を持つことがよくあります。
私はCSSのみのモーダルのいくつかのバリエーションを見てきました(そして私のポートフォリオの古いバージョンのためにそれを作った罪を犯しています)。 彼らは「チェックボックスハック」を使用したり、 :target
の動作を利用したり、 :focus
からそれを作り上げようとしたりする可能性があります(これはおそらく、変装した非常に大きなツールチップです)。
HTML dialog
要素については、包括的にアクセスできるとは見なされないことに注意してください。 したがって、カスタムソリューションの前にネイティブHTMLを使用することを強くお勧めしますが、残念ながら、これはその考えを破ります。 HTML dialog
にアクセスできない理由について詳しく知ることができます。
ツールチップとは異なり、モーダルは構造化されたコンテンツを許可することを目的としています。 これは、見出し、一部の段落コンテンツ、およびリンク、ボタン、さらにはフォームなどのインタラクティブな要素を意味する可能性があります。 ほとんどのユーザーがそのコンテンツにアクセスするには、キーボードイベント、特にタブを使用できる必要があります。 より長いモーダルコンテンツの場合、矢印キーもスクロール機能を保持する必要があります。 また、ツールチップと同様に、 Escキーを使用して閉じる必要があります。CSSのみでこれを有効にする方法はありません。
モーダル内のフォーカス管理にはJavaScriptが必要です。 モーダルはフォーカスをトラップする必要があります。つまり、フォーカスがモーダル内に入ると、ユーザーはその後ろのページコンテンツにタブアウトできないようにする必要があります。 しかし、最初に、焦点はモーダルの内部に入る必要があります。これには、完全にアクセス可能なモーダルソリューションのためのJavaScriptも必要です。
JavaScriptで管理する必要のあるモーダル関連イベントのシーケンスは次のとおりです。
- ボタンのイベントリスナーがモーダルを開きます
- フォーカスはモーダル内に配置されます。 どの要素がモーダルコンテンツに基づいて変化するか(決定木を参照)
- フォーカスは、却下されるまでモーダル内に閉じ込められます
- 好ましくは、ユーザーは、専用の閉じるボタンまたはモーダルコンテンツの確認が必要な場合は「キャンセル」などの破壊的なボタンアクションに加えて、 Escキーを使用してモーダルを閉じることができます。
- Escが許可されている場合、モーダル背景をクリックするとモーダルも閉じられます
- 却下時に、ナビゲーションが発生しなかった場合、フォーカスはトリガーボタン要素に戻ります
モーダルフォーカスデシジョンツリー
WAI-ARIAオーサリングプラクティスのモーダルダイアログの例に基づいて、モーダルが開いたときにフォーカスを配置する場所の簡略化された決定木を次に示します。 ここでは、コンテキストによって常に選択が決まります。理想的には、フォーカスは単に「最初のフォーカス可能な要素」よりもさらに管理されます。 実際、フォーカスできない要素を選択する必要がある場合があります。
- モーダルの主な主題はフォームです。
最初のフォームフィールドにフォーカスします。 - モーダルコンテンツは長さが重要であり、モーダルアクションを視野から外します。
見出しが存在する場合はその見出し、または最初の段落に焦点を合わせます。 - モーダルの目的は、複数の使用可能なアクションを使用した手続き型(例:アクションの確認)です。
コンテキストに基づいた「最も破壊的でない」アクションに焦点を合わせます(例:「OK」)。 - モーダルの目的は、1つのアクションで手続き型です。
最初のフォーカス可能な要素に焦点を合わせる
クイックヒント:見出しや段落など、フォーカスできない要素にフォーカスする必要がある場合は、 tabindex="-1"
を追加します。これにより、要素をJSでプログラムでフォーカスできるようになりますが、DOMタブの順序には追加されません。 。
ARIAを設定するための他の要件の詳細と、フォーカスを追加する要素を選択する方法の詳細については、WAI-ARIAモーダルデモを参照してください。 デモには、フォーカス管理を行う方法を例示するJavaScriptも含まれています。
すぐに使えるソリューションとして、Kitty Giraudelは、説明した機能要件を含むa11yダイアログを作成しました。 Adrian Roselliはまた、モーダルダイアログのフォーカスの管理を研究し、デモを作成し、さまざまなブラウザーとスクリーンリーダーの組み合わせがフォーカスされた要素をどのように伝達するかについての情報をまとめました。
タブ
タブ付きインターフェースには、対応するコンテンツパネルを一度に1つずつ表示する一連のトリガーが含まれます。 これらのCSSの「ハック」には、定型化されたラジオボタンまたは:target
の使用が含まれ、どちらも一度に1つのパネルしか表示できません。
JavaScriptを必要とするタブ機能は次のとおりです。
-
aria-selected
属性を現在のタブの場合はtrueに、選択されていないタブの場合はfalseに切り替えます。 - タブの選択とフォーカスを区別するためのロービングタブインデックスの作成
- 矢印キーイベント(およびオプションで
Home
とEnd
)に応答して、タブ間でフォーカスを移動します
オプションで、タブの選択をフォーカスに従わせることができます。つまり、タブがフォーカスされると、タブも選択され、関連するタブパネルが表示されます。 WAI-ARIAオーサリングプラクティスは、選択が焦点に従うべきかどうかを選択するためのこのガイドを提供します。
選択をフォーカスに従わせることを選択するかどうかに関係なく、JavaScriptを使用して矢印キーイベントをリッスンし、タブ要素間でフォーカスを移動します。 これは、ロービングタブインデックス(次に説明)を使用すると自然なキーボードタブのフォーカス順序が変わるため、タブオプションのナビゲーションを可能にする代替パターンです。
ロービングtabindex
について
ロービングタブインデックスの概念は、タブインデックス値の値がプログラムで制御され、要素のtabindex
順序を管理することです。 タブに関しては、これは、 tabindex="0"
を設定することにより、選択されたタブのみがフォーカス順序の一部になり、選択されていないタブはtabindex = "-1"に設定され、 tabindex="-1"
のキーボードフォーカス順序から削除されることを意味します。
これは、タブが選択されたときに、次のタブが関連するタブパネル内にユーザーのフォーカスを移動させるためです。 tabindex="0"
を割り当てることにより、タブパネルである要素をフォーカス可能にすることを選択できます。または、タブパネル内にフォーカス可能な要素が保証されている場合は、それは必要ない場合があります。 タブパネルのコンテンツがより可変的または複雑になる場合は、モーダルについて確認した決定木に従ってフォーカスを管理することを検討してください。
タブパターンの例
タブを作成するためのいくつかの参照パターンは次のとおりです。
- Deque大学のTabpanelデモ
- Scott O'Haraのタブウィジェットテスト(いくつかの機能パターンをテスト)
- Heydon Pickeringの包括的コンポーネントのタブ付きインターフェイス。これは、タブが目次のプログレッシブエンハンスメントになる方法を示しています。
カルーセル
スライドショーまたはスライダーとも呼ばれるカルーセルには、制御メカニズムを含む一連の回転するコンテンツパネル(別名「スライド」)が含まれます。 これらは、さまざまなコンテンツを含む多くの構成で見つかります。 それらは、悪いデザインパターンと見なされることで有名です。
CSSのみのカルーセルのトリッキーな部分は、コントロールを提供しない場合や、予期しないコントロールを使用してカルーセルの動きを操作する場合があることです。 たとえば、「チェックボックスハック」を再度使用してカルーセルを移行させることはできますが、チェックボックスを使用すると、支援技術のユーザーにインタラクションに関する誤ったタイプの情報が提供されます。 さらに、チェックボックスのラベルを前後の矢印として視覚的に表示するようにスタイル設定すると、音声認識ソフトウェアのユーザーに、カルーセルを制御するために何を言うべきかについて間違った印象を与える可能性があります。
最近では、スクロールスナップのネイティブCSSサポートが導入されました。 最初は、これは完璧なCSSのみのソリューションのようです。 ただし、自動化されたアクセシビリティチェックでさえ、インタラクティブな要素を介してナビゲートする方法がない場合に備えて、キーボードユーザーがナビゲートできないものとしてこれらにフラグを立てます。 この機能のデフォルトの動作には、他にもアクセシビリティとユーザーエクスペリエンスの問題があり、その一部はSmolCSSのスクロールスナップデモに含まれています。
カルーセルの外観にはさまざまなものがありますが、いくつかの共通の特徴があります。 1つのオプションは、タブマークアップを使用してカルーセルを作成することです。これは、視覚的な表現が変更された同じ基本的なインターフェイスであるためです。 タブと比較すると、カルーセルは前と次の追加のコントロールを提供し、カルーセルが自動再生されている場合は一時停止することもあります。
以下は、カルーセル機能に応じたJavaScriptの考慮事項です。
- ページ化されたコントロールの使用
番号の付いたアイテムを選択したら、プログラムで関連するカルーセルスライドに焦点を合わせます。 これには、現在のスライドに焦点を合わせることができるが、画面外のスライドへのアクセスを防ぐことができるように、ロービングタブインデックスを使用してスライドコンテナを設定することが含まれます。 - 自動再生の使用
一時停止コントロールを含め、スライドにカーソルを合わせたり、スライド内のインタラクティブ要素にフォーカスを合わせたりしたときに一時停止を有効にします。 さらに、JavaScript内でprefers-reduced-motion
チェックして、スライドショーを一時停止状態でロードし、ユーザーの好みを尊重することができます。 - 前/次のコントロールの使用
aria-live="polite"
とマークされた視覚的に非表示の要素を含め、これらのコントロールがアクティブになったら、「スライド2/4」などの現在の位置の表示をライブ領域に入力します。
アクセス可能なカルーセルを構築するためのリソース
- 実装の詳細と考慮事項、およびカルーセルに関するW3CWebアクセシビリティチュートリアルの完全なコード例
- タブインターフェイスをカルーセルに拡張するDeque大学の例
- 自動回転画像カルーセルのWAI-ARIAオーサリングプラクティスの例
- Smashingのアクセス可能なコンポーネントのまとめにおけるカルーセルリソースの選択
ドロップダウンメニュー
これは、ボタンがトグルしてリンクのリストを開くコンポーネントを指し、通常はナビゲーションメニューに使用されます。 :hover
または:focus
にメニューを表示するのをやめるCSS実装は、いくつかの重要な詳細を見逃しているだけです。
確かに、新しい:focus-within
プロパティを使用することで、CSSのみのソリューションを安全に実装できるとさえ思っていました。 CSSドロップダウンメニューに関する私の記事が修正され、必要なJavaScriptに関するメモとリソースが含まれていることがわかります(そのソリューションを求める他の人もJSの実装を完了できるように、タイトルを保持しました)。 具体的には、CSSのみに依存するということは、ツールチップで学習したWCAG成功基準1.4.13:ホバーまたはフォーカスに関するコンテンツに違反することを意味します。
この時点でおなじみのように聞こえるはずのいくつかのテクニックのためにJavaScriptを追加する必要があります。
- ariaの切り替え-
click
イベントをリッスンすることにより、メニューボタンでtrue
とfalse
の間aria-expanded
- Escキーを使用して開いているメニューを閉じ、フォーカスをメニュートグルボタンに戻す
- できれば、フォーカスがメニューの外に移動したときに開いているメニューを閉じる
- オプション:メニュートグルボタンとドロップダウン内のリンクの間のキーボードナビゲーション用に、矢印キーと
Home
キーおよびEnd
キーを実装します
クイックヒント:追加のJS-の存在に基づいてメニュー表示を行うのではなく、メニュー表示を.dropdown-toggle[aria-expanded=
"
true
"
] + .dropdown
のセレクターに関連付けることにより、ドロップダウンメニューが正しく実装されていることを確認します。 active
のようなクラスを追加しました。 これにより、JSソリューションの複雑さも軽減されます。
これは「開示パターン」とも呼ばれ、詳細については、WAI-ARIAオーサリングプラクティスの開示ナビゲーションメニューの例を参照してください。
アクセシブルなコンポーネントの作成に関する追加リソース
- アクセシブルなフロントエンドコンポーネントへのSmashingの完全ガイド
- Carie Fisherの記事Good、Better、Best:アクセス可能なパターンの複雑な世界を解き明かす
- WAI-ARIAオーサリングプラクティス1.2から入手できる一般的なデザインパターンとウィジェットに関するデモと情報
- Deque大学のコードライブラリ
- スコットオハラのアクセシブルなコンポーネント
- ヘイドンピカリングの包括的コンポーネント