実践Webアクセシビリティ

display: none、visibility: hidden、aria-hidden のアクセシビリティへの影響と適切な使い分け

Tags: CSS, ARIA, HTML, アクセシビリティ, 実装

ウェブサイトやウェブアプリケーションを開発する上で、要素を一時的あるいは永続的に画面から非表示にしたい場面は多く存在します。例えば、タブパネルの非アクティブなコンテンツ、モーダルダイアログが開いている際の背景要素、一時的なメッセージ表示領域などが挙げられます。これらの要素を非表示にする方法として、CSSの display: none;visibility: hidden;、そしてARIA属性の aria-hidden="true" などが一般的に使用されます。

しかし、これらの非表示方法は視覚的な表示だけでなく、アクセシビリティツール(特にスクリーンリーダー)による要素の認識や操作性にも異なる影響を与えます。適切な方法を選択しないと、コンテンツがスクリーンリーダー利用者にとって利用できなくなったり、逆に不要な情報を読み上げてしまったりといった問題が発生します。

本記事では、display: none;visibility: hidden;aria-hidden="true" がそれぞれアクセシビリティにどのような影響を与えるかを解説し、それぞれの特徴を踏まえた適切な使い分けの方法について、具体的なコード例を交えて説明します。

なぜ非表示の方法によってアクセシビリティが変わるのか

要素の非表示方法がアクセシビリティに影響するのは、それぞれの方法がブラウザのレンダリングプロセスや、アクセシビリティツリーの構築に異なる作用を及ぼすためです。

スクリーンリーダーは、主にこのアクセシビリティツリーを読み取って利用者に情報を提供します。したがって、アクセシビリティツリーに含まれるかどうかが、スクリーンリーダー利用者にとってその要素が存在するかどうかに直結します。

display: none; の特徴とアクセシビリティ

display: none; は、指定された要素とそのすべての子孫要素を、レンダリングツリーから完全に削除します。

実装例

.hidden-display {
  display: none;
}
<div class="hidden-display">
  <p>このコンテンツは完全に非表示になります。</p>
  <a href="#">このリンクもアクセスできません。</a>
</div>

アクセシビリティへの影響

display: none; が適用された要素は、レンダリングツリーから除外されるだけでなく、多くの場合、アクセシビリティツリーからも除外されます。

適切な使用例

visibility: hidden; の特徴とアクセシビリティ

visibility: hidden; は、要素を視覚的に非表示にしますが、その要素が本来占めるべきスペースは確保されたままになります。

実装例

.hidden-visibility {
  visibility: hidden;
}
<div class="hidden-visibility" style="border: 1px solid red;">
  <p>このコンテンツは視覚的に非表示ですが、スペースは確保されます。</p>
  <button>このボタンはhiddenですが、Tabキーでフォーカスされる場合があります(ブラウザによる)</button>
</div>

アクセシビリティへの影響

visibility: hidden; が適用された要素は視覚的には非表示ですが、アクセシビリティツリーには通常残ります

適切な使用例

visibility: hidden; はアクセシビリティの観点から見て、要素を完全に隠したい場合には推奨されません。視覚的には非表示にしつつ、スクリーンリーダーには読み上げさせたいという特殊なケース(非常に稀です)以外では、display: none; または aria-hidden="true" の使用を検討すべきです。

aria-hidden="true" の特徴とアクセシビリティ

aria-hidden="true" は、要素をアクセシビリティツリーから除外します。視覚的な表示には一切影響しません。

実装例

<div>
  <img src="icon.png" alt="設定" aria-hidden="true">
  <button>設定</button> <!-- 画像は単なる装飾なのでaria-hiddenで隠し、ボタンテキストで意味を伝える -->
</div>

<div aria-hidden="true">
  <!-- このdiv内のすべてのコンテンツ(画像、テキスト、リンクなど)はスクリーンリーダーから隠される -->
  <p>このテキストはスクリーンリーダーには読み上げられません。</p>
  <a href="#">このリンクもスクリーンリーダーからはアクセスできません。</a>
</div>

アクセシビリティへの影響

aria-hidden="true" が適用された要素は、アクセシビリティツリーから除外されます。

適切な使用例

適切な使い分けのガイドライン

これらの違いを踏まえると、以下のような使い分けが推奨されます。

  1. 要素を視覚的にも完全に非表示にし、スペースも占有させず、スクリーンリーダーからも隠したい場合:

    • display: none; を使用します。要素がレンダリングツリーとアクセシビリティツリーの両方から除外されるため、最もクリーンな方法です。動的なコンテンツの表示/非表示切り替えに広く使われます。
  2. 要素を視覚的には表示したまま、スクリーンリーダーからのみ隠したい場合:

    • aria-hidden="true" を使用します。ただし、この要素内にインタラクティブ要素(リンク、ボタン、フォーム部品など)を含めないように細心の注意が必要です。含めてしまうと、キーボード操作でフォーカスできるのにスクリーンリーダーが読み上げないという問題が発生します。装飾的なアイコンなど、インタラクティブでない要素に主に適用します。
  3. 要素を視覚的に非表示にしたいが、アクセシビリティツリーには残したい場合:

    • これは非常に稀なケースであり、通常は推奨されません。visibility: hidden; はアクセシビリティツリーに残るためスクリーンリーダーに読み上げられてしまう可能性が高く、キーボードフォーカスも問題となるため、要素を完全に隠す目的では避けるべきです。
  4. 要素を視覚的には非表示にしつつ、スクリーンリーダーには読み上げさせたい場合(オフスクリーンテキストなど):

    • これは通常、要素を画面外の表示領域(オフスクリーン)にCSSで配置することで実現します。視覚的には見えませんが、DOM上には存在し、アクセシビリティツリーにも含まれるため、スクリーンリーダーが読み上げることができます。特定の目的(例:アイコンボタンにテキストラベルを付けるが、アイコンだけ表示したい場合)で使用されます。これは display: none;, visibility: hidden;, aria-hidden="true" とは異なるテクニックです。

    css .visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; border: 0; padding: 0; clip: rect(0, 0, 0, 0); /* older browsers */ clip-path: inset(50%); /* current browsers */ overflow: hidden; white-space: nowrap; } このクラスは、要素を視覚的には隠しつつ、スクリーンリーダーが内容を読み取れるようにするための標準的な手法です。

実装時の注意点

テスト方法

実装した非表示の方法が期待通りに機能しているかを確認するには、以下の方法を試してください。

  1. スクリーンリーダーでの確認: 実際に主要なスクリーンリーダー(NVDA, JAWS for Windows, VoiceOver for macOS/iOS, TalkBack for Androidなど)を使用して、非表示にした要素の内容が読み上げられないこと、または意図通りに読み上げられることを確認します。特に、キーボード(Tabキーなど)で操作し、非表示にしたはずの要素にフォーカスが移動しないか確認してください。
  2. アクセシビリティ評価ツール: ブラウザのDeveloper Toolsに内蔵されているアクセシビリティツリービューアや、Web Accessibility Evaluation Tool (WAVE), axe DevToolsなどのツールを使用して、非表示にした要素がアクセシビリティツリーに含まれているか、あるいは除外されているかを確認します。

まとめ

要素を非表示にする方法は複数あり、それぞれアクセシビリティに与える影響が異なります。

これらの違いを理解し、それぞれの状況に応じて適切な方法を選択することで、視覚的なデザインとアクセシビリティの両立を図ることができます。実装後は必ず、スクリーンリーダーなどでのテストを行い、意図通りに動作することを確認してください。