WCAG 達成基準 · Level A
WCAG 2.1.1: キーボード
WCAG 2.1.1 は、マウスやポインターで利用可能なすべての機能が、キーボードのみでも同様に操作可能であり、キー入力に特定のタイミングを必要としないことを求めています。この基準はマウスを使用できないユーザーにとって基盤となるものであり、あらゆるウェブサイトやアプリケーション上で、ナビゲーション、操作、タスクの完了を行えることを保証します。
- Level A
- Wcag
- Wcag 2 2 a
- 操作可能
- アクセシビリティ
このルールの意味
WCAG 2.1.1(Keyboard)は、ウェブページやアプリケーション上のあらゆる機能がキーボードインターフェイスで操作可能でなければならないと定めています。つまり、ユーザーがマウスでボタンをクリックしたり、項目をドラッグしたり、ホバーしてメニューを表示したり、その他の要素とマウスでやり取りできるのであれば、同じ操作をキーボード入力だけで行える必要があります。通常はTab、Shift+Tab、Enter、Space、矢印キーが使われます。
この達成基準は、すべてのインタラクティブ要素に適用されます。リンク、ボタン、フォームコントロール、カスタムウィジェット、モーダルダイアログ、ドロップダウンメニュー、アコーディオン、カルーセル、日付ピッカー、ドラッグ&ドロップインターフェイス、canvas ベースのインタラクション、その他ユーザー入力に反応するあらゆるコンポーネントが対象です。コンテンツが、ユーザーに描画パス(終点だけでなくパス自体が入力となるもの)を要求する場合のみ、WCAG で正式に認められた例外となります。この狭い例外を除き、その他すべての機能はキーボードでアクセス可能でなければなりません。
適合(pass)とは、キーボードのみのユーザーが Tab や矢印キーによるナビゲーションであらゆるインタラクティブ要素に到達でき、Enter または Space でそれを起動でき、どの段階でもマウスを必要とせずに意図した操作を完了できる状態を意味します。不適合(fail)となるのは、次のいずれかに該当する場合です。インタラクティブ要素がまったくフォーカスを受け取らない、フォーカスは受け取るが要素を起動できない、onmouseover や ondblclick などのマウスイベントのみで機能がトリガーされキーボード等価がない、スクロール可能なコンテナがキーボードで到達できず、その中のコンテンツが閉じ込められている、などです。
WCAG 2.1.1 と WCAG 2.1.2(No Keyboard Trap)を区別することが重要です。達成基準 2.1.1 は、キーボードユーザーがすべてのものに到達し利用できることを保証します。一方、達成基準 2.1.2 は、キーボードユーザーがコンポーネントの内部に閉じ込められないことを保証します。完全なレベル A 準拠のためには、両方を満たす必要があります。
なぜ重要か
キーボードアクセシビリティはニッチな問題ではありません。アメリカでは推定で成人の 4 人に 1 人が何らかの障害とともに生活しており、パーキンソン病、多発性硬化症、脊髄損傷、反復性ストレス障害(RSI)、四肢の差異、振戦などを含む運動障害によって、標準的なマウスやタッチスクリーンを操作できないことが頻繁にあります。これらのユーザーは、キーボード、スイッチコントロール、シップ・アンド・パフ装置、ヘッドポインタ、その他最終的には OS レベルでキーボード入力をエミュレートする支援技術に全面的に依存しています。
NVDA、JAWS、VoiceOver などのスクリーンリーダーに依存する全盲およびロービジョンのユーザーは、完全にキーボードでナビゲートします。要素がキーボードで到達可能でなければ、スクリーンリーダーはそれを読み上げることができず、そのユーザーにとってコンテンツは完全に見えないものになります。世界保健機関によると、世界で少なくとも22 億人が近見または遠見の視覚障害を抱えています。
具体的なシナリオを考えてみましょう。両手に進行した関節リウマチを持つユーザーが、EC サイトのチェックアウトページを訪れます。サイトのカスタム構築された支払い方法セレクタは、スタイル付きの一連の <div> 要素として実装されており、マウスクリックにのみ反応します。ユーザーはコンテナまでは Tab で移動できますが、個々のオプションはフォーカスを受け取らず、Enter を押しても何も起こりません。購入を完了できないのです。これは些細な不便ではなく、商取引からの完全な排除であり、法的リスクであると同時に、事業者にとって大きな収益損失のシナリオでもあります。
障害の有無にかかわらず、キーボードアクセシビリティは、スピードのためにキーボードショートカットを好むパワーユーザー、マウスの使用がポリシーで制限されている企業や官公庁のユーザー、非標準入力デバイスのユーザーにも恩恵をもたらします。また、検索エンジンがより確実に解析できるクリーンでセマンティックな HTML 構造と相関が高く、SEO パフォーマンスの向上やコードベースの長期的な保守性にも寄与します。
関連する Axe-core のルール
- scrollable-region-focusable: このルールは、オーバーフローコンテンツ(つまりスクロール可能)を持つ要素がキーボードで到達可能かどうかをチェックします。コンテナに
overflow: autoやoverflow: scrollといった CSS プロパティが設定されている場合、視覚のあるマウスユーザーはマウスホイールやトラックパッドでスクロールできます。しかしキーボードユーザーは、Tab でコンテナにフォーカスを移すか、矢印キーでスクロールできなければなりません。このルールは、tabindex属性がなく、自然にフォーカス可能な子要素もないスクロール可能領域にフラグを立てます。これは、キーボードのみのユーザーがオーバーフローしているコンテンツにアクセスする手段がないことを意味します。自動検出が信頼できるのは、axe が計算済みスタイルと DOM ツリーを検査し、キーボードフォーカス機能を欠いたスクロールオーバーフロー要素を特定できるためです。 - server-side-image-map: このルールは、サーバーサイドイメージマップ、すなわち
ismap属性を持つ HTML の<img>要素の使用にフラグを立てます。サーバーサイドイメージマップは、マウスクリックの生のピクセル座標をサーバーに送信し、どのリンクが起動されたかを判断します。動作がポインタデバイスから得られるピクセル座標に完全に依存しているため、キーボード等価のメカニズムは存在しません。クライアントサイドイメージマップ(<map>と<area>要素を使用し、キーボードアクセシブルにできるもの)とは異なり、サーバーサイドイメージマップは本質的にキーボードのみのナビゲーションと両立しません。axe はあらゆる<img ismap>要素をキーボードアクセシビリティの不適合としてフラグします。手動検証では、そのイメージマップが基盤となるナビゲーションや機能にアクセスする唯一の手段かどうかを確認する必要があります。
axe-core のような自動ツールは、キーボードアクセシビリティの不備の一部しか検出できないことを理解することが重要です。多くの違反は、カスタム JavaScript イベントリスナー、動的なフォーカス管理、静的解析では完全に評価できない複雑なインタラクションパターンを伴うため、手動テストが必要です。たとえば、click イベントリスナーを持つ <div> として実装されたボタンは、tabindex='0' によってフォーカスを受け取ることはできても、Enter や Space キー押下に反応しない場合があります。これは、インタラクションを実行しない限り axe が常に検出できるとは限らない不適合です。
テスト方法
- axe DevTools または Lighthouse による自動スキャン: Chrome または Firefox 用の axe DevTools ブラウザ拡張機能をインストールします。テスト対象のページに移動し、ページ全体のスキャンを実行します。結果を
wcag2aおよびkeyboardタグ付きのルールでフィルタリングします。特にscrollable-region-focusableとserver-side-image-mapの違反を探します。Lighthouse(Chrome DevTools)では、Accessibility 監査を実行し、「Keyboard」カテゴリを確認します。これらのツールは明らかな構造上の不備を表面化させますが、すべてのカスタムウィジェットの問題を検出できるわけではないことに注意してください。 - 手動によるキーボードナビゲーションテスト: マウスを完全に切断するか、脇に置きます。ブラウザのアドレスバーから開始し、Tab を繰り返し押して、ページ上のすべてのフォーカス可能要素を前方向に移動します。Shift+Tab を押して後方に移動します。リンク、ボタン、入力欄、カスタムドロップダウン、モーダル、スライダーなど、すべてのインタラクティブ要素について、(a) 目に見えるフォーカスインジケータを受け取ること、(b) Enter または Space を押すと期待どおりに起動すること、(c) その結果として表示されるダイアログやパネルもキーボードでナビゲートおよび閉じることができることを確認します。メニュー、タブリスト、ラジオグループ、リストボックスなどの複合パターンを実装するウィジェット内では矢印キーを使用します。
- NVDA と Firefox を用いたスクリーンリーダー+キーボードテスト: NVDA(無料、Windows)を起動し、Firefox を開きます。NVDA のブラウズモード(矢印キー)を使用してページを読み進め、すべてのインタラクティブ要素を特定します。フォーカスモード(Insert+Space またはフォームフィールドで自動)に切り替えてコントロールを操作します。カスタムウィジェットがそのロール、状態、名前を正しくアナウンスし、マウスなしで全機能を完了できることを確認します。スクロール可能なコンテナについては、Tab でそこにフォーカスを移し、矢印キーでスクロールできるかをテストします。
- VoiceOver と Safari(macOS/iOS)によるスクリーンリーダーテスト: VoiceOver を有効にします(macOS では Command+F5)。VO+右矢印でページを直線的にナビゲートします。Tab を使ってインタラクティブ要素間を移動します。スクロール可能な領域に到達できること、キーボードでアクセス可能な代替手段なしにスワイプジェスチャやポインタ操作を要求する機能がないことを確認します。
- JAWS と Chrome のテスト: JAWS を起動した状態で Chrome を開き、ページに移動します。JAWS のバーチャルカーソルでコンテンツを閲覧し、Tab キーでインタラクティブ要素間を移動します。アコーディオン、カルーセル、モーダルダイアログ、カスタムセレクトボックスなど、カスタム JavaScript ウィジェットを特にテストし、Tab でそこに移動してキーボードのみで完全に操作できるかを確認します。フォーカスは受け取るが起動できない要素や、マウスホバーでのみ到達可能な機能をすべて記録します。
- スクロール可能領域に特化したテスト: ページ上の、スクロールバーが見えている、または表示領域より多くのコンテンツを含むすべてのコンテナを特定します。それぞれのコンテナに Tab でフォーカスを移そうとします。Tab でコンテナ内にフォーカスが移動せず、フォーカス可能な子要素もない場合、そのコンテナはキーボードアクセシビリティの不適合である可能性が高いです。コンテナまたは近くの要素にフォーカスがある状態で矢印キーを押し、スクロールが可能かどうかを確認します。
修正方法
シナリオ 1: スクロール可能コンテナ — 不適切な例
<!-- Scrollable div with no tabindex: keyboard users cannot scroll this content -->
<div style='height: 200px; overflow-y: auto;'>
<p>Long list of terms and conditions text...</p>
<p>More text that overflows the container...</p>
</div>
シナリオ 1: スクロール可能コンテナ — 適切な例
<!-- Adding tabindex='0' makes the container focusable so keyboard users
can scroll it with arrow keys once it receives focus -->
<div
tabindex='0'
role='region'
aria-label='Terms and Conditions'
style='height: 200px; overflow-y: auto;'
>
<p>Long list of terms and conditions text...</p>
<p>More text that overflows the container...</p>
</div>
シナリオ 2: サーバーサイドイメージマップ — 不適切な例
<!-- ismap sends pixel coordinates to the server — no keyboard equivalent exists -->
<a href='/map-handler'>
<img src='navigation-map.png' ismap alt='Site navigation map' />
</a>
シナリオ 2: サーバーサイドイメージマップ — 適切な例
<!-- Replace with a client-side image map using <map> and <area> elements.
Each <area> is focusable and activatable by keyboard. -->
<img
src='navigation-map.png'
alt='Site navigation map'
usemap='#site-nav'
/>
<map name='site-nav'>
<area shape='rect' coords='0,0,100,50' href='/home' alt='Home' />
<area shape='rect' coords='100,0,200,50' href='/about' alt='About Us' />
<area shape='rect' coords='200,0,300,50' href='/contact' alt='Contact' />
</map>
シナリオ 3: マウスイベントのみを使用するカスタムウィジェット — 不適切な例
<!-- div acting as a button with only onclick: keyboard users pressing Enter
or Space will get no response -->
<div onclick='submitForm()'>Submit Order</div>
シナリオ 3: マウスイベントのみを使用するカスタムウィジェット — 適切な例
<!-- Option A: Use a native <button> — it handles keyboard activation natively -->
<button type='submit' onclick='submitForm()'>Submit Order</button>
<!-- Option B: If a custom element is required, add tabindex, role, and
a keydown listener for Enter (13) and Space (32) -->
<div
role='button'
tabindex='0'
onclick='submitForm()'
onkeydown='if(event.key==="Enter"||event.key===" "){submitForm();}'
>
Submit Order
</div>
シナリオ 4: ホバーのみのドロップダウンメニュー — 不適切な例
<!-- Menu only appears on CSS :hover — keyboard focus on the parent
does not reveal the submenu -->
<nav>
<ul>
<li class='has-dropdown'>
<a href='/products'>Products</a>
<ul class='dropdown'> <!-- only visible on :hover in CSS -->
<li><a href='/products/a'>Product A</a></li>
<li><a href='/products/b'>Product B</a></li>
</ul>
</li>
</ul>
</nav>
シナリオ 4: ホバーのみのドロップダウンメニュー — 適切な例
<!-- Use a button to toggle the dropdown and manage aria-expanded.
CSS shows the submenu when the button has aria-expanded='true'.
Keyboard users press Enter/Space on the button to open the menu. -->
<nav>
<ul>
<li class='has-dropdown'>
<button
aria-expanded='false'
aria-controls='products-submenu'
onclick='toggleMenu(this)'
>
Products
</button>
<ul id='products-submenu' hidden>
<li><a href='/products/a'>Product A</a></li>
<li><a href='/products/b'>Product B</a></li>
</ul>
</li>
</ul>
</nav>
よくある間違い
- ネイティブでない要素に対して
onclickを唯一のイベントハンドラとして使用し、対応するonkeydownやonkeyupハンドラを追加しないこと。マウスクリックはonclickをトリガーしますが、<div>や<span>のキーボードによる起動はそうではありません。 - カスタムインタラクティブ要素に
tabindex='0'を追加しても、role='button'(または適切なロール)を追加し忘れること。その結果、スクリーンリーダーが要素の目的をユーザーに伝えません。 - CSS の
:hover疑似クラスのみに依存したドロップダウンナビゲーションを構築し、JavaScript によるキーボードトグルを用意しないことにより、サブメニューがキーボードユーザーにとって見えず到達不能になること。 - 並べ替えリスト、かんばんボード、ファイルアップロードゾーンなどのドラッグ&ドロップインターフェイスを、キーボードでアクセス可能な代替メカニズム(キーボードでトリガーされる移動コマンドや別の並べ替えコントロールなど)なしで実装すること。
- 利用規約ボックス、チャットウィンドウ、固定高さラッパー内のデータテーブルなどのスクロール可能コンテナを
tabindex='0'なしで作成し、キーボードユーザーがスクロールしてすべてのコンテンツを閲覧できないようにしてしまうこと。 - レガシーコードベースから引き継いだナビゲーションコンポーネントに
<img ismap>を使用し続け、クライアントサイドイメージマップや標準的なナビゲーションリンクに置き換えないこと。 - インタラクティブ要素に
tabindex='-1'を適用して自然な Tab 順から除外しながら、プログラムによるフォーカス管理戦略を提供しないこと。その結果、キーボードで永久に到達できないコントロールが生じます。 mouseenter、mouseleave、mousemoveイベント(ツールチップ、プレビュー、コンテキストメニューなど)だけで機能をトリガーし、等価なfocus、blur、キーボードイベントの代替を用意しないこと。- モーダルダイアログがフォーカスを自動的に管理すると想定し、ダイアログが開いたときにフォーカスをダイアログ内に移動せず、閉じたときにトリガー要素にフォーカスを戻さないことにより、キーボードユーザーをページ内で迷子にしてしまうこと。
- キーボードでアクセス可能であるべき要素に CSS で
pointer-events: noneを設定すること。これはキーボードの挙動に直接影響しないものの、多くの場合キーボードインタラクションもブロックする JavaScript パターンと組み合わされます。
トルコのアクセシビリティ規制との関係
トルコの大統領通達 2025/10は、2025 年 6 月 21 日付官報第 32933 号で公布され、WCAG 2.1 レベル AA に整合した必須のウェブアクセシビリティ要件を定めています。WCAG 2.1.1(Keyboard)はレベル Aの達成基準であり、最優先の遵守対象に位置づけられます。レベル A 準拠は絶対的な最低ラインであり、サイトがレベル A の達成基準に不適合であれば、他にどれだけ改善がなされていてもアクセシブルとは見なされません。
この通達の下では、遵守期限は主体の種類によって区別されています。公的機関および政府機関は、通達の公布日から1 年以内に準拠を達成する必要があり、規制の対象となる民間部門の事業者には2 年の遵守期限が与えられています。
大統領通達 2025/10 の対象となる主体には、トルコのデジタルサービスの幅広い分野が含まれます。EC プラットフォーム、公的機関および省庁、銀行および金融機関、病院および医療提供者、20 万人以上の加入者を持つ通信会社、認可を受けた旅行代理店、民間輸送会社、そして国民教育省(MoNE)に認可された私立学校が含まれます。
これらすべての主体にとって、WCAG 2.1.1 を満たさないということは、キーボードに依存するユーザー(運動障害のある市民、高齢ユーザー、スクリーンリーダーユーザーを含む)が中核的なデジタルサービスにアクセスできないことを意味します。これは直接的な規制違反です。実務的には、キーボードでチェックアウトフローを完了できない EC サイトや、予約にマウス操作を必要とする病院の患者ポータルは、この通達の要件に違反していることになります。
通達の対象となる組織は、アクセシビリティ改善プログラムの第一歩として、キーボードアクセシビリティ監査を実施すべきです。WCAG 2.1.1 の不適合は、多くの場合、HTML 要素の選択、イベントバインディングパターン、コンポーネントフレームワークのデフォルトといったアーキテクチャ上の問題に根ざしているため、単なる設定変更ではなくコードレベルの修正が必要になることがあります。Accsible のオーバーレイ SDK は、JavaScript レイヤーで一般的なキーボードアクセシビリティのギャップを表面化し、パッチを当てるのに役立ちますが、チームは規制審査に耐えうる堅牢で監査可能な準拠を達成するために、ソースコードにおける構造的な修正も併せて進めるべきです。
