実践Webアクセシビリティ

実践!アクセシブルなフォーカスインジケーターのスタイリングと実装

Tags: アクセシビリティ, CSS, フォーカスインジケーター, :focus-visible, キーボード操作

ウェブサイトやアプリケーションにおいて、キーボードで操作する際に現在どの要素にフォーカスがあるかを示す「フォーカスインジケーター」は、アクセシビリティの観点から極めて重要です。多くのユーザー、特にキーボードユーザーやロービジョンユーザーは、この視覚的な手がかりに頼ってコンテンツを操作します。

しかし、デザイン上の理由から、デフォルトのフォーカスインジケーター(主にブラウザの outline スタイル)をリセットしたり、見えにくいカスタムスタイルに変更したりするケースが散見されます。これはユーザー体験を著しく損ない、アクセシビリティの低下につながります。

この記事では、アクセシブルなフォーカスインジケーターの実装方法、特にCSSによる具体的なスタイリング手法に焦点を当てて解説します。

なぜフォーカスインジケーターが必要なのか?

ウェブコンテンツを利用する全ての人がマウスやタッチ操作を行うわけではありません。以下のようなユーザーは、主にキーボードやその他の代替入力デバイスを使用して操作します。

WCAG (Web Content Accessibility Guidelines) 2.x の Success Criterion 2.4.7 Focus Visible は、「操作可能なユーザーインタフェースコンポーネントにキーボードフォーカスがあることが視覚的に示されている」ことを要求しています。これは、フォーカスインジケーターが表示されることがアクセシビリティの必須要件であることを示しています。

デフォルトの outline をリセットする問題点

ブラウザはデフォルトで、フォーカス可能な要素(リンク、ボタン、フォーム部品など)がフォーカスを受け取った際に outline プロパティによるスタイルを適用します。これはユーザーエージェントスタイルシートによって提供される最も基本的なフォーカスインジケーターです。

/* 多くのブラウザのデフォルトに近いスタイル */
:focus {
  outline: 2px solid #000; /* ブラウザによって色は異なります */
  outline-offset: 2px;
}

しかし、デザイン上の理由で、この outlinenone0 に設定してしまう例がよく見られます。

/* 絶対に避けるべき例 */
*:focus {
  outline: none; /* または outline: 0; */
}

この記述があると、要素がフォーカスされても視覚的な変化が一切なくなり、キーボードユーザーは現在操作している要素を見失ってしまいます。これはWCAG 2.4.7違反であり、非常に深刻なアクセシビリティの問題を引き起こします。

デフォルトの outline を残す場合の注意点

デフォルトの outline をそのまま使用することは、アクセシビリティの観点からは推奨されるアプローチの一つです。しかし、デザインによっては見た目が不自然になったり、要素の形状によっては見えにくくなったりすることがあります。また、異なるブラウザやOSで表示されるスタイルが異なるため、統一感を損なう可能性もあります。

可能であれば、デフォルトの outline をリセットするのではなく、後述する :focus-visible を利用しつつ、明確で視覚的に優れたカスタムスタイルに置き換えることを検討すべきです。

アクセシブルなカスタムフォーカスインジケーターの実装

デフォルトの outline をリセットする必要がある場合(例えば、カスタムデザインと衝突する場合や、より明確なスタイルを適用したい場合)は、必ず同等かそれ以上の視覚的なインジケーターを代替として提供する必要があります。

:focus 擬似クラスと :focus-visible 擬似クラス

以前は :focus 擬似クラスだけが存在しましたが、これには問題がありました。マウスやタッチでクリックした場合にも :focus スタイルが適用されてしまい、視覚的に不要なインジケーターが表示されることがあるためです。これが、開発者が安易に :focus { outline: none; } と書いてしまう大きな原因の一つでした。

そこで登場したのが :focus-visible 擬似クラスです。:focus-visible は、ユーザーエージェントが判断した「フォーカスインジケーターを表示すべき」と判断した場合にのみスタイルが適用されます。具体的には、キーボード操作やプログラムによるフォーカス移動時には有効になりますが、多くの場合マウスやタッチによるクリック時には有効になりません。

この :focus-visible を使用することで、マウス/タッチ操作時にはインジケーターを表示せず、キーボード操作時のみ表示するといった、より洗練されたアクセシブルなフォーカススタイリングが可能になります。

実装例:

デフォルトの outline をリセットし、カスタムスタイルを適用する場合の推奨されるコードです。

/* デフォルトの outline をリセットする場合の基本的な考え方 */
/* `:focus-visible` がサポートされていないブラウザ向けのフォールバックとして `:focus` を残しつつ、
   後続の `:focus-visible` でスタイルを上書きします。 */

/* または、特定の要素に対してのみ outline: none を設定し、他の要素はデフォルトのままにする */
a:focus, button:focus, input:focus, select:focus, textarea:focus {
    /*
     * WARNING: デフォルトの outline を無効にする場合は、
     * 必ず `:focus-visible` などで代替手段を提供してください。
     * ここで outline: none を設定すると、古いブラウザや特定の条件下で
     * フォーカスインジケーターが完全に消える可能性があります。
     * 可能であれば、デフォルトの outline は残し、後述の `:focus-visible` で上書きすることを推奨します。
     */
     /* outline: none; */
}


/* 推奨されるアプローチ: デフォルトの outline を残しつつ、より明確な `:focus-visible` スタイルで上書きする */
/* もしくは、特定の要素の outline を none にした場合の代替スタイル */
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible {
  /* カスタムフォーカスインジケーターのスタイルをここに記述 */
  outline: 3px solid #007bff; /* 例: 目立つ色の境界線 */
  outline-offset: 3px;       /* 要素から少し離して表示 */
  box-shadow: 0 0 0 4px rgba(0, 123, 255, 0.5); /* 例: 光彩効果 */
}

/* 要素の種類やデザインに合わせて個別にスタイルを調整 */
button:focus-visible {
    outline: 3px dashed #dc3545; /* ボタンには破線にするなど */
}

この例では、:focus-visible 擬似クラスを使用して、より視覚的に分かりやすい outlinebox-shadow を適用しています。

スタイリングのポイント

アクセシブルなフォーカスインジケーターをデザイン・実装する際は、以下の点を考慮してください。

  1. 視覚的な明瞭さ:

    • 色: 背景色や周囲の要素と十分なコントラストを持つ色を選択してください。WCAG 2.2 SC 1.4.11 Non-text Contrast では、フォーカスインジケーターのようなUIコンポーネントの状態を示す視覚的な表示について、少なくとも 3:1 のコントラスト比を推奨しています。
    • 太さ・スタイル: 細すぎる線や、点線・破線でコントラストが低いものは見えにくい場合があります。ある程度の太さがあり、要素の形状に沿って明確に表示されるスタイル(例: 実線、太い線、光彩 box-shadow)を検討してください。
    • 要素からの距離: outline-offset を使用すると、インジケーターを要素の境界線から少し離して描画できます。これにより、要素自体のスタイルと混同されにくく、より明確に見えます。
  2. 一貫性: ウェブサイト全体で、フォーカスインジケーターのスタイルを統一してください。異なる要素やコンポーネントでスタイルがばらばらだと、ユーザーは混乱します。ただし、要素の種類(リンク、ボタン、入力欄など)によって異なるスタイルを適用することは、視覚的な区別に役立ちます。

  3. 隠蔽しない: フォーカスインジケーターが、他のコンテンツ(モーダルウィンドウ、ツールチップなど)によって隠されたり、表示領域外にはみ出して見えなくなったりしないように注意してください。

  4. アニメーション: フォーカスの移動にアニメーションを使用する場合は、動きが速すぎたり、不必要な装飾アニメーションで注意を散漫させたりしないように注意してください。点滅するアニメーションは、てんかん発作を誘発する可能性があるため避けるべきです (WCAG 2.2 SC 2.3.1 Three Flashes or Below Threshold)。

:focus:focus-visible のポリフィル

古いブラウザや一部の環境では :focus-visible がサポートされていない場合があります。このような場合のために、JavaScriptによるポリフィルを利用することも検討できます。

:focus-visible の公式なポリフィルとして、WhatWGによって提供されているものが存在します。https://github.com/WICG/focus-visible

このポリフィルを導入することで、:focus-visible をサポートしていないブラウザでも、CSSの :focus-visible セレクターが期待通りに動作するようになります。

実装後のテスト方法

アクセシブルなフォーカスインジケーターが正しく実装されているかを確認するために、以下のテストを実施してください。

  1. キーボード操作:

    • マウスを使わず、キーボードの Tab キーでウェブサイト上の全ての操作可能な要素(リンク、ボタン、フォーム部品、カスタムコントロールなど)を順番に移動してみてください。
    • 各要素にフォーカスが当たった際に、明確なフォーカスインジケーターが表示されることを確認してください。
    • Shift + Tab で逆順に移動する場合も確認してください。
    • 矢印キーで操作するコンポーネント(例: ラジオボタン、チェックボックスグループ、メニュー、タブリストなど)についても、矢印キーでフォーカスが移動し、インジケーターが表示されることを確認してください。
    • Enter キーや Space キーで要素を操作(ボタンをクリック、リンクを開く、チェックボックスを切り替えるなど)した後も、フォーカスが見えなくなるなどの問題が発生しないか確認してください。
  2. 様々な要素で確認:

    • a 要素 (リンク)
    • button 要素
    • input (text, checkbox, radio, submit, etc.)
    • textarea
    • select
    • カスタムコンポーネント (JavaScriptで tabindex="0" や ARIA Role を設定しているもの)
    • tabindex="-1" が設定されているが、JavaScriptでフォーカスを当てる要素 (例: モーダルを開いた際のコンテナ、エラーメッセージ領域など)
  3. アクセシビリティ評価ツールの利用:

    • 自動評価ツール (Lighthouse, AXE DevToolsなど) は、outline: none のような明らかな問題を検出するのに役立ちます。ただし、カスタムスタイルの視覚的な明瞭さ(コントラストなど)の評価は手動での確認が必要です。
  4. コントラストの確認:

    • フォーカスインジケーターの色と、それが表示される背景色(要素自体の背景、隣接する要素の色など)とのコントラスト比をカラーコントラストチェッカーツール(WebAIM Contrast Checkerなど)を使用して確認してください。WCAG 2.2 SC 1.4.11を満たしているか確認します。

まとめ

フォーカスインジケーターは、ウェブサイトのアクセシビリティにおいて基本的ながらも非常に重要な要素です。安易にデフォルトのスタイルをリセットせず、やむを得ずカスタムスタイルを適用する場合は、:focus-visible を活用し、視覚的に明確でコントラストの高いデザインを実装することが必須です。

この記事で紹介した具体的な実装方法とテスト手順を参考に、あなたのウェブサイトのフォーカスインジケーターが全てのユーザーにとって利用しやすいものになっているか、ぜひ確認・改善を行ってください。これは、キーボードユーザーだけでなく、誰もが快適にコンテンツを利用できるための第一歩となります。