セマンティックHTMLの実践:アクセシビリティ向上のためのマークアップ
ウェブサイトのアクセシビリティを確保する上で、基盤となるのがセマンティックなHTML構造です。見た目が同じでも、適切なHTML要素を使用しているかどうかが、スクリーンリーダーを含む様々な支援技術の利用者にとっての理解度や操作性に大きな影響を与えます。この記事では、なぜセマンティックHTMLが重要なのかを改めて確認し、具体的なマークアップの実践方法をコード例と共に解説します。
セマンティックHTMLとは何か、なぜ重要か
セマンティックHTMLとは、要素の役割や意味を正確に伝えるHTMLマークアップのことです。例えば、見出しには<h1>
から<h6>
を使用し、段落には<p>
を使用する、リストには<ul>
や<ol>
、<li>
を使用するなどです。これに対して、<div>
や<span>
のみで全ての構造を表現しようとするマークアップは、セマンティクス(意味)に乏しいと言えます。
セマンティックHTMLがアクセシビリティに重要な理由は以下の通りです。
- 支援技術による構造理解: スクリーンリーダーなどの支援技術は、HTMLのセマンティクスを解釈して、ウェブページの構造やコンテンツの関係性をユーザーに伝えます。例えば、
<h1>
を適切に使うことで、ページの大見出しであることをユーザーに明示できます。ナビゲーションは<nav>
、主要なコンテンツは<main>
でマークアップすることで、ユーザーはページ内の主要エリア間を容易に移動できます。 - ナビゲーションの容易さ: 多くの支援技術では、見出しやランドマーク(主要な構造を示す要素、例:
<nav>
,<main>
,<footer>
など)をジャンプポイントとして使用できます。セマンティックなマークアップがされていれば、ユーザーはページ全体を線形に読み上げさせることなく、目的の情報が含まれるセクションへ素早く移動できます。 - コンテンツの関係性理解: 例えば、
<figure>
と<figcaption>
を使うことで、画像とキャプションが関連付けられていることを明確に伝えられます。<label>
と<input>
を関連付けることで、フォームコントロールの目的が利用者にはっきり分かります。 - 保守性と拡張性: セマンティックなコードは人間にとっても読みやすく、他の開発者が構造を理解しやすいため、長期的な保守や機能追加が容易になります。
WCAG (Web Content Accessibility Guidelines)においても、情報の構造や関係性をプログラムが解釈できるようにすることが求められています(WCAG 2.1達成基準 1.3.1 情報及び関係性)。セマンティックHTMLは、この達成基準を満たすための基本的な手段です。
具体的なセマンティックHTMLの実装例
1. 基本的なページ構造
ページの主要なセクションには、HTML5で導入されたセマンティック要素を使用します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>実践Webアクセシビリティ</title>
</head>
<body>
<header>
<h1>サイトのタイトル</h1>
<nav>
<h2>ナビゲーション</h2>
<ul>
<li><a href="/">ホーム</a></li>
<li><a href="/about">サイトについて</a></li>
<li><a href="/articles">記事一覧</a></li>
</ul>
</nav>
</header>
<main>
<article>
### 記事タイトル
<p>これは記事の導入部分です...</p>
<section>
#### サブセクションの見出し
<p>このセクションの内容です...</p>
</section>
<section>
#### 別のサブセクション
<p>このセクションの内容です...</p>
</section>
</article>
<aside>
### 関連情報
<p>サイドバーの内容です...</p>
</aside>
</main>
<footer>
<p>© 2023 実践Webアクセシビリティ</p>
</footer>
</body>
</html>
<header>
: ページの導入部分やセクションのヘッダーに使用します。サイト全体のヘッダーにはサイトタイトルやグローバルナビゲーションが含まれることが多いです。<nav>
: ナビゲーションリンクのブロックに使用します。主要なナビゲーション(グローバルナビ、目次など)に適用します。<main>
: ドキュメントの主要なコンテンツを示します。ページ内に1つだけ存在し、そのページ固有のコンテンツを含みます。<article>
: 自己完結したコンテンツ(記事、ブログ投稿、フォーラムの投稿など)に使用します。<section>
: ドキュメント内の汎用的なセクションです。見出しを持つべきです。セクションごとにテーマが分かれる場合に使用します。単なるスタイル目的のコンテナには<div>
を使用します。<aside>
: メインコンテンツからわずかに切り離されたコンテンツ(サイドバー、引用、広告など)に使用します。<footer>
: ページのフッターやセクションのフッターに使用します。著作権情報、関連リンクなどが含まれることが多いです。
これらの要素は、それぞれが持つデフォルトのARIAロール(例: <nav>
はrole="navigation"
, <main>
はrole="main"
, <footer>
はrole="contentinfo"
など)により、支援技術にその役割を伝えます。特別な理由がない限り、これらのネイティブ要素を使用することが推奨されます。
2. 見出し構造
見出しはページの構造を示す上で非常に重要です。<h1>
から<h6>
を階層的に使用し、視覚的なデザインのためだけに見出しレベルをスキップしたり、<div>
などで代替したりしないでください。
<h1>ページ全体のタイトル</h1>
<section>
## セクションの大見出し
<p>このセクションの導入...</p>
<section>
### サブセクションの見出し
<p>このサブセクションの内容...</p>
</section>
</section>
<section>
## 別のセクションの大見出し
<p>このセクションの導入...</p>
</section>
支援技術の利用者は、見出しリストを使ってページをブラウズすることが多いため、適切な見出し構造はナビゲーションの効率に直結します。
3. リスト
複数の項目をリストとして表現する場合、適切なリスト要素(<ul>
, <ol>
, <dl>
)を使用します。
### 箇条書きリスト
<ul>
<li>項目1</li>
<li>項目2</li>
<li>項目3</li>
</ul>
### 番号付きリスト
<ol>
<li>最初のステップ</li>
<li>次のステップ</li>
<li>最後のステップ</li>
</ol>
### 定義リスト
<dl>
<dt>HTML</dt>
<dd>HyperText Markup Language</dd>
<dt>CSS</dt>
<dd>Cascading Style Sheets</dd>
</dl>
CSSでリストマーカーを非表示にしても、セマンティクスは失われません。スクリーンリーダーはこれらをリストとして認識し、項目数を読み上げたり、リスト内のナビゲーションを提供したりします。<div>
などでリストを模倣すると、これらの機能が失われます。
4. ARIA属性による補強
ネイティブのHTML要素で適切なセマンティクスが得られない場合や、カスタムコンポーネントを作成する場合に、ARIA属性を使用してセマンティクスや状態、プロパティを補強します。ただし、可能な限りHTML要素を使用すること(Use native HTML elements or make elements accessible with WAI-ARIA (Implicit WAI-ARIA Semantics))が最優先です。
- ARIAロール (role): 要素の役割を明示します。ネイティブ要素の持つロールと同じロールを
role
属性で明示的に指定することは通常不要です(例:<nav role="navigation">
は冗長)。カスタム要素に役割を持たせる際に使用します(例:role="button"
,role="dialog"
,role="tablist"
など)。 - ARIA状態 (state)・プロパティ (property): 要素の現在の状態(例:
aria-expanded="true/false"
,aria-hidden="true/false"
,aria-selected="true/false"
)やプロパティ(例:aria-label
,aria-labelledby
,aria-describedby
,aria-controls
など)を伝えます。これらはJavaScriptによって動的に変化することが多いです。
例:ARIA aria-labelledby
と aria-describedby
の使用
特定の要素のラベルや説明を提供するために使用します。特に、フォームの入力フィールドではない要素に名前を付けたい場合や、補足的な説明が必要な場合に有効です。
<div id="dialog1" role="dialog" aria-labelledby="dialog1_title" aria-describedby="dialog1_desc">
<h2 id="dialog1_title">設定の変更</h2>
<p id="dialog1_desc">以下の設定項目を変更できます。</p>
<!-- ダイアログの内容 -->
<button>閉じる</button>
</div>
<div id="status_message" role="status">
<p>ファイルが正常にアップロードされました。</p>
</div>
この例では、ダイアログ要素(role="dialog"
)のラベルをdialog1_title
というIDを持つ要素のテキストで提供し、説明をdialog1_desc
を持つ要素のテキストで提供しています。role="status"
は、重要な状態メッセージが更新された際に、支援技術に自動的に通知させるARIAライブリージョンの一種です。
例: role="none"
/ role="presentation"
の使用
CSSのスタイリングのためにHTML構造を崩すことなく、要素が持つデフォルトのセマンティクスを打ち消したい場合に使用します。これは、リスト構造を使いつつ、視覚的にはリストマーカーやインデントを表示しない、といった場合に、不要なリストセマンティクスを支援技術に伝えないために使うことがあります。
<!-- スタイリングのためにリスト構造を使っているが、意味的なリストではない場合 -->
<ul role="none">
<li role="none">
<div><img src="..." alt=""></div>
<div>
### 見出し
<p>説明</p>
</div>
</li>
<li role="none">
<div><img src="..." alt=""></div>
<div>
### 見出し
<p>説明</p>
</div>
</li>
</ul>
この例では、リスト項目がそれぞれ独立したカードのようなコンポーネントとして表示され、リストであること自体に意味がない場合に、role="none"
またはrole="presentation"
を使用することで、リストセマンティクスを支援技術に伝えないようにしています。ただし、この使用は慎重に行う必要があり、本当にリストとしての意味がない場合に限定すべきです。
実装時の注意点とよくある落とし穴
<div>
の乱用: スタイルやレイアウトのために安易に<div>
を使わず、コンテンツの意味や役割に合ったセマンティック要素を選びましょう。- 見出しレベルのスキップ:
<h1>
,<h2>
,<h3>
, ... の順序を正しく守りましょう。見た目の大きさのためだけにレベルを飛ばしてはいけません。 - ARIAはあくまで補強: まず適切なHTML要素を探し、それが難しい場合にARIAを使用するという原則を守りましょう。不適切あるいは過剰なARIAの使用は、かえって混乱を招く可能性があります。
- ビジュアルとセマンティクスの乖離: CSSで要素の表示順序を変えたり、一部を非表示にしたりしても、HTMLのソースコード上の順序や構造は変わりません。支援技術は多くの場合、ソースコードの順序に基づいて情報を伝えます。視覚的なデザインとソースコード上の構造が一致しているか確認しましょう。
- カスタムコンポーネント: JavaScriptで独自のUIコンポーネント(例: カスタムドロップダウン、スライダーなど)を作成する場合、キーボード操作への対応に加え、ARIAロール、状態、プロパティを適切に設定する必要があります。
実装したセマンティクスをテストする方法
- 見出しマップ/ランドマークナビゲーションの確認: 各ブラウザの拡張機能(例: Web Developerツールバーの見出しアウトライン機能、Accessibility Insights for Webなど)を使用して、ページの見出し構造やランドマークロールが正しく認識されているかを確認します。スクリーンリーダーの機能(例: NVDAの見出しリスト/ランドマークリスト表示機能)でも確認できます。
- スクリーンリーダーでの操作: 実際にスクリーンリーダー(NVDA, JAWS, VoiceOverなど)を使用して、コンテンツがどのように読み上げられるか、見出しやランドマークを使って移動できるかを確認します。
- アクセシビリティ評価ツール: Lighthouse、Axe DevTools、Waveなどの自動評価ツールを実行し、セマンティックに関する問題を検出します。ただし、自動ツールは検出できる問題に限りがあるため、手動での確認も必須です。
- HTMLバリデーター: W3C Markup Validation Serviceなどを利用して、HTML構文自体にエラーがないかを確認します。構文エラーは支援技術の解釈を妨げる可能性があります。
まとめ
セマンティックHTMLは、見た目だけでなく、そのコンテンツが持つ意味や役割を明確にすることで、アクセシビリティの基盤を築く非常に重要な要素です。適切なHTML要素を使い分け、必要に応じてARIA属性で補強することで、支援技術の利用者がウェブサイトの構造を容易に理解し、効率的に情報を得たり操作したりできるようになります。
この記事で紹介した基本的な構造要素やリスト、見出しの使い方を日々のマークアップで実践し、さらにARIA属性の活用、そして様々なツールやスクリーンリーダーでのテストを組み合わせることで、より多くの人にとって使いやすいウェブサイトを実現できるでしょう。まずは小さなコンポーネントやページの一部からでも、セマンティックなマークアップを意識して取り組んでみてください。