ARIA 役割ボタン: Guía Completa y Práctica
ARIAの role="button" は、支援技術に汎用コンテナをボタンとして通知させるためのARIAロールですが、動作(挙動)は提供しません。tabindex="0" の追加、Enterキーとスペースキーのハンドリング、および aria-pressed や aria-disabled による状態の反映を実装する必要があります。WAI-ARIA 1.2 仕様では、このロールはウィジェットカテゴリに定義されており、ARIAの第一原則として、可能な限りネイティブの <button> を使用することが推奨されています。
role="button" は、Webインターフェースのアクセシブルなセマンティクスを定義するW3C標準であるWAI-ARIAのロールタクソノミーに属しています。要素に role="button" が付与されると、スクリーンリーダー(NVDA、JAWS、VoiceOver、Narrator)が構築するアクセシビリティツリーにおいて、その要素は汎用的な div や span ではなく、操作可能なコントロールとして提示されます。スクリーンリーダーでナビゲートするユーザーにとって、この違いは絶大です。ロールがない場合、ユーザーには「グループ」または単なるテキストとして聞こえますが、ロールがあれば「ボタン」と聞こえ、アクティブにできることがわかります。
よくある誤解は、role="button" を指定すれば div が機能的なボタンに変わると思い込むことです。実際にはそうなりません。ロールは通知されるセマンティクスを変更するだけであり、フォーカスの受信、キーボードへの応答、アクションの実行といった「挙動」は、引き続き開発者の責任となります。このセマンティクスと挙動の分離こそが、このロールで犯されるミスの大部分の原因です。
WAI-ARIAはW3Cの勧告として公開されており、バージョン1.2がロール、状態、プロパティの現行のリファレンスとなっています。role="button" は仕様の中で最も古く安定したウィジェットロールの一つであり、ARIA 1.0から存在しています。
role=“button” を使うべき時と使うべきでない時
WAI-ARIAのオーサリングプラクティス(WAI-ARIA Authoring Practices)にまとめられているARIAの第一原則は明確です。必要なセマンティクスと挙動を持つネイティブなHTML要素が存在する場合は、それを使用してください。<button> には、暗黙的なロール、キーボードフォーカス、Enterおよびスペースによる起動、無効状態がすでに備わっています。これらすべてを role="button" で再実装することは、余計な手間であり、バグの温床となります。
しかし、このロールが必要な正当なシナリオも存在します。最も一般的なのは、マークアップがフレームワークやCMSによって制約されており、レイアウトや既存のJavaScriptを壊さずに <button> を導入できない場合です。また、ボタンのように動作させる必要があるが、内部構造的に特定のコンテナを必要とするコンポーネント(一部のサードパーティ製ウィジェットなど)の場合もあります。
関連: — 48 時間で IA が WCAG に最高の瞬間をもたらす.
3つ目の、より議論の分かれるシナリオは、すでに別のネイティブロールを持っており、それをボタンとして提示する必要がある要素です。この場合、デザインが誤ったセマンティクスを強いていないか検討すべきです。見た目がボタンであっても、実際には別のページに遷移するのであれば、正解はボタンではなくリンク <a href> です。
| 状況 | 推奨される解決策 | 理由 |
|---|---|---|
| フォームやインターフェースでのアクション | ネイティブの <button> | ロール、フォーカス、キーボード操作が標準搭載 |
| 他のURLへのナビゲーション | <a href> | 正しいリンクのセマンティクス |
| 変更不可能なコンテナ | role="button" + キーボード操作 + 状態管理 | ロールが有効な唯一のケース |
| 切り替えボタン (on/off) | <button aria-pressed> | 状態がネイティブに公開される |
| 無効化されたボタン | <button disabled> | 状態とフォーカスが管理される |
role=“button” を使ったボタンを正しく実装する方法
role="button" に基づくボタンは、「フォーカス」「キーボード」「状態」「アクセシブルな名前」の4つの側面をカバーする必要があります。どれか一つでも欠けると、「アクセシブルに見えるが、実際のテストでは失敗する」コントロールになります。
フォーカスは tabindex="0" で有効にし、要素を自然なタブ順序に挿入します。tabindex に正の値を決して使用しないでください。ページ全体のタブ順序を乱し、予測不能なジャンプを引き起こします。カスタムインタラクティブ要素には 0 が正解です。
一見の価値があります: — Accesibilidad gestionada: 人間性の見直しと自動化の組み合わせ.
キーボード操作では、Enterキーとスペースキーの2つを処理する必要があります。ネイティブの <button> は両方に反応しますが、ボタンのARIAロールを持つ div は単独では反応しません。keydown イベントをリッスンし、キーが Enter または Space の時にアクションを実行させます。また、スペースキーによるデフォルトのページスクロールを防ぐ必要があります。この詳細は見落とされやすく、マウスでしか動作しないボタンが量産される原因となります。
状態はARIA属性で伝えます。切り替えボタンでは aria-pressed="true" または "false" を使用してアクティブかどうかを示します。無効なボタンでは aria-disabled="true" を使用します。これは状態を通知しますが、それ単体でインタラクションを阻止するわけではないため、コード側でアクションをブロックする必要があります。aria-disabled とネイティブの disabled 属性の違いは重要です。前者は要素をフォーカス可能に保ちますが、後者はタブ順序から除外します。
アクセシブルな名前は、要素の可視テキストで構築するか、テキストがない場合は aria-label または aria-labelledby を使用します。アクセシブルな名前がないボタンは、スクリーンリーダーで単に「ボタン」とだけ読み上げられ、何をするためのものか手がかりが得られません。
<div
role="button"
tabindex="0"
aria-pressed="false"
id="btn-modo"
>
ダークモード
</div>
<script>
const btn = document.getElementById('btn-modo');
function toggle() {
const activo = btn.getAttribute('aria-pressed') === 'true';
btn.setAttribute('aria-pressed', String(!activo));
}
btn.addEventListener('click', toggle);
btn.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
toggle();
}
});
</script>
上記の例は、フォーカス、キーボード、状態、名前をカバーしています。これが、スクリーンリーダーとキーボードで利用可能にするための最小限の実装です。
よくある間違いと検出方法
最も多い間違いは、tabindex なしに role="button" を適用することです。これにより、キーボードで到達不可能なボタンになります。自動ツールでは「フォーカス不可能なインタラクティブロールを持つ要素」として検出され、アクセシビリティ監査で最も多く報告される違反の一つです。
2番目の間違いは、キーボード操作を管理していないことです。ボタンのARIAロールと tabindex を持つ div でも、キーハンドラがなければフォーカスは当たりますが Enter やスペースに反応しません。キーボードユーザーは、ボタンにフォーカスはできるが起動できないという状況に陥ります。
関連: — La certificación que acredita tu experiencia en accesibilidad.
3番目の間違いは、リンクに role="button" を使用することです。これはナビゲーションのセマンティクスを破壊し、ユーザーがリンクを期待しているところでスクリーンリーダーが「ボタン」と読み上げるため、混乱を招きます。遷移を伴う要素であれば、リンクであるべきです。
4番目の間違いは、切り替えボタンで状態を忘れることです。aria-pressed なしに2つのモードを切り替えるボタンは、ユーザーに現在の状態を知らせることができません。この属性こそが、状態をプログラム的に伝える唯一の方法です。
これらの問題を検出するために、axe、Lighthouse、WAVEなどの自動ツールはロールやフォーカスの違反を指摘しますが、キーボードの挙動や状態のロジックまでは検証しません。そこは手動テストが必要です。Tabでナビゲートし、Enterとスペースで起動し、スクリーンリーダーの出力を確認してください。自動監査と手動テストの組み合わせこそが、カスタムボタンを検証する唯一の信頼できる方法です。
role=“button” のボタンをテストする方法
テストはキーボードから始めます。Tabキーでページを巡回し、ARIAロールボタンに可視フォーカスが当たるか確認します。Enterとスペースを個別に押し、両方でアクションが実行されるか確認してください。スペースキーでボタンが起動せずページがスクロールする場合、preventDefault が不足しています。
2番目のテストはスクリーンリーダーで行います。WindowsのNVDA、macOSのVoiceOver、WindowsのNarratorが一般的です。ボタンにフォーカスした際、ロール(「ボタン」)、アクセシブルな名前、および状態(ある場合)が読み上げられる必要があります。「グループ」と読み上げられたり、状態に言及がない場合は、どこかに不備があります。
3番目のテストはフォーカス順序です。ボタンは視覚的な位置に対応した論理的なタブ順序で現れる必要があります。正の tabindex はこの順序を破壊するため、実装ミスを示す明確な指標となります。
4番目のテストはコントラストと可視フォーカスです。フォーカスインジケーターを outline: none で削除し、代替の可視的な手段を提供しないことは避けてください。フォーカスは当たっているがそれが表示されないボタンは、キーボードユーザーに現在地を知らせることができません。
ボタンロールに代わる現代的な選択肢
2024年においても、またあらゆる新規プロジェクトにおいても、ネイティブの <button> 要素が最良の選択肢です。追加コードなしでロール、フォーカス、キーボード操作、状態を提供し、ブラウザ間で一貫して処理されます。
カスタム要素(Custom Elements)やWeb Componentsも一つの道です。HTMLElement を拡張したコンポーネントでボタンの挙動をカプセル化し、正しいセマンティクスで公開できますが、role="button" と同様にフォーカスとキーボード操作を手動で管理する必要があります。利点は再利用性であり、欠点は実装責任が同じであることです。
ARIA in HTML(どのHTML要素にどのARIAロールが許可されるかを定義するルール)では、ネイティブロールの上書きを推奨していません。<button> に role="button" を適用するのは冗長であり、href 付きの <a> に適用するのは逆効果です。一般的な推奨事項は、独自のセマンティクスを持たないコンテナにのみこのロールを予約しておくことです。
Key Takeaways
role="button"は通知されるセマンティクスのみを変更します。フォーカス、キーボード操作、状態は手動で実装する必要があります。- ARIAの第一原則は、マークアップが許す限りネイティブの
<button>を使用することを推奨しています。 - ARIAロールボタンには、
tabindex="0"、Enterとスペースの処理、アクセシブルな名前、およびaria-pressedまたはaria-disabledによる状態管理が必要です。 - 自動ツールはフォーカスの欠如を検出しますが、キーボードの挙動と状態はスクリーンリーダーを用いた手動テストが必要です。
- 正の
tabindexは決して使用せず、遷移を伴うリンクにrole="button"を適用しないでください。
よくある質問
role=“button” と button 要素の違いは何ですか?
ネイティブの <button> 要素には、暗黙的なロール、キーボードフォーカス、Enterおよびスペースによる起動、無効状態が追加コードなしで含まれています。role="button" 属性は通知されるセマンティクスを提供するだけであり、それ以外の挙動はすべてプログラミングする必要があります。そのため、ARIAの第一原則では可能な限りネイティブ要素の使用を推奨しています。
role=“button” に tabindex は必要ですか?
はい。role="button" を持つ div や span はデフォルトではフォーカス可能ではないため、tabindex="0" がなければタブ順序から外れ、キーボードで到達できなくなります。正しい値は 0 です。正の値はページ全体のタブ順序を変更するため、避けるべきです。
role=“button” を持つ div を Enter とスペースに反応させるにはどうすればいいですか?
keydown イベントをリッスンし、キーが Enter または Space の時にアクションを実行させます。スペースキーの場合は、ページスクロールを防ぐために preventDefault を呼び出すのが適切です。これらのハンドラがないと、ボタンにフォーカスは当たりますが、キーボードで起動できません。
ボタンがアクティブであることや無効であることをどう示しますか?
切り替えボタンの場合は、状態に応じて aria-pressed="true" または "false" を使用します。無効なボタンの場合は aria-disabled="true" を使用します。これは状態を通知しますが、単独でインタラクションをブロックしないため、コード内でアクションを阻止する必要があります。<button> を使用する場合は、ネイティブの disabled 属性が好ましいです。
リンクに role=“button” を使うのは悪い習慣ですか?
はい、そのリンクが別のURLに遷移する場合です。<a href> のロールを role="button" で上書きすると、ナビゲーションのセマンティクスが壊れ、ユーザーがリンクを期待しているところでスクリーンリーダーが「ボタン」と読み上げるため混乱を招きます。遷移する要素であれば、リンクのロールを維持すべきです。
role=“button” のエラーを検出するツールは何ですか?
axe、Lighthouse、WAVEなどの自動ツールは、インタラクティブロールを持つ要素のフォーカス欠如などの違反を指摘します。しかし、キーボードの挙動や状態のロジックは検証できないため、信頼できる検証には自動監査と、NVDA、VoiceOver、Narratorを用いた手動テストを組み合わせることが不可欠です。
よくある質問
役割='ボタン' とボタンの要素の違いは何ですか?
El elemento <button> nativo include el rol implícito、el foco por teclado、la activación con Enter y Espacio y el estado deshabilitado sin codigo adicional.属性 role='button' 意味を明確にするためのソロ ポート。エルレストデルコンポルタミエントデベプログラム。 ARIA は、可能性のある自然な要素を最初に記録することができます。
¿role='button' に tabindex が必要ですか?
シ。 role='button' の範囲を拡張することはできませんが、tabindex='0' では、制御不能なタブ表を作成できません。 El valor は 0 に修正されます。重要な情報は、ページとページのタブラシオンで更新されます。
¿Cómo hago que un div con role='button' 応答します Enter y Espacio?
キーダウン キーを押してイベントを実行してください。スペースを入力してください。 En el casa de Espacio conviene llamar aPreventDefault para vitar el desplazamiento de página.罪はマネハドーレスにあり、私たちは安全な活動を続けることができます。
¿インディコは今、活動を続けていますか?
米国の代替ボタン aria-pressed='true' または 'false' を設定してください。米国の aria-disabled='true' を使用して、単独で相互作用を行うことはできません。 <ボタン> を無効にすることを優先します。
¿ロール = 'ボタン' をアンレースで使用することはできますか?
URL を参照してください。 <a href> でロールを取得し、role='button' を安全に管理するために、パンタラの講義を混乱させ、'ボタン' を使用して安全な状況を確認してください。ナベガの要素、アンレースのデベ保守者。
¿role='button' に関するエラーを検出できますか?
自動斧、灯台、波のセニャラン ヴィオラシオネス、要素、要素、インタラクティブな機能を備えています。禁輸措置が適用されないため、NVDA、VoiceOver、またはナレーターを使用して、検証可能な組み合わせのオーディオ自動処理を有効にすることはできません。
5 分でアクセス可能
簡単な操作で計画を立てるためのウィジェットを無料で利用できます