Modern HTML 1-7|HTMLとアクセシビリティ|セマンティクス・キーボード操作・ARIAの基本
HTMLを順番に学びたい方へ
この記事は、ToshiLabのWEBプログラミング学習記事の一部です。
HTMLを基礎から順番に確認したい方は、WEBプログラミングの入口から進められます。
- この回で分かること
- 前回のミニチェック|Modern HTML 1-6 回答・解説
- セマンティックHTMLがアクセシビリティの土台
- 見出しは見た目ではなく階層で選ぶ
- リンクとボタンは役割で使い分ける
- フォームではラベルと説明の関係を伝える
- キーボード操作とフォーカスを考える
- 発展|スキップリンクで主要コンテンツへ移動する
- ARIAはHTMLで不足する情報を補う
- 動的な更新はライブリージョンで伝える
- aria-hiddenで装飾を支援技術から除外する
- ARIAはネイティブHTMLの置き換えではない
- 実務ではどこで使う?
- アクセシビリティはHTMLだけで完結しない
- 今回できるようになったこと
- Modern HTML 1-7 ミニチェック
- まとめ
- 前回を確認する
- 次に読む
この回で分かること
Modern HTML 1-6では、
画像・レスポンシブ画像・音声・動画をHTMLで扱う方法を学びました。
Modern HTML 1-7では、
HTMLとアクセシビリティ
について整理します。
アクセシビリティというと、
「特別な属性をたくさん追加する」
というイメージを持つかもしれません。
しかし、最初に考えたいのはARIAではありません。
まず、
・意味に合ったHTML要素を使う
・見出しを論理的に整理する
・リンクとボタンを役割で使い分ける
・フォームへ適切なラベルを付ける
・キーボードでも操作できるようにする
・フォーカス位置を分かるようにする
といった、
意味に合ったHTMLを使うこと
がアクセシビリティの土台になります。
そのうえでHTMLだけでは不足する情報を、
ARIAなどで補います。
前回のミニチェック|Modern HTML 1-6 回答・解説
Modern HTML 1-6では、画像・レスポンシブ画像・音声・動画について学びました。
Q1|ページのかなり下にある画像の読み込みを遅らせたい場合は?
答えは、
loading=”lazy”
です。
画面を開いた直後には必要のない画像へ指定することで、画像が必要になるまで読み込みを遅らせ、初期表示の負荷を抑えられます。
ただし、
すべての画像へloading=”lazy”を付ければよいわけではありません。
ページ上部の重要な画像など、最初から表示する必要がある画像では通常の読み込みを検討します。
Q2|複数の画像候補と表示幅のヒントをブラウザへ伝える属性は?
答えは、
srcsetとsizes
です。
srcsetでは、
480w・800w・1200wなど複数の画像候補を指定できます。
sizesでは、
現在のレイアウトで画像がどれくらいの幅で表示される予定なのかをブラウザへ伝えます。
ブラウザはこれらの情報などを使って、適切な画像候補を選択します。
Q3|会話だけでなく効果音や話者などの情報も文字で伝えたい場合は?
答えは、
captions
が目的に合います。
subtitlesは主に会話内容を別の言語などで提供するために使います。
captionsでは、
会話だけでなく、
・効果音
・音楽
・話者
・重要な音声情報
なども含めて、音を聞かなくても内容を理解しやすくします。
前回まで扱ってきた、
HTML標準の機能を先に使う
という考え方は、今回のアクセシビリティでも非常に重要です。
アクセシビリティのために、最初からARIAを増やす必要はありません。
まず、
意味と動作を持つネイティブHTMLを正しく使う
ことから始めます。
それでもHTMLだけでは伝えられない情報がある場合に、ARIAを補助として追加します。
Native HTML Firstは、アクセシビリティでも基本となる考え方です。
PR:Modern HTML 学習の最初の参考書として、必要な方だけ見てください。
出版社自身が「HTMLの基本を一度学んだ人が再入門・ステップアップする本」と位置づけており、内容もHTML仕様、セマンティクス、主要要素、フォーム、インタラクティブ要素、WAI-ARIAまで扱っています。今回の「初心者HTMLをやり直すのではなく、現在のHTMLへ知識をアップデートする」というシリーズ方針とかなり近いです。
※価格や在庫、版数は変わるため、最終確認はリンク先でお願いします。
セマンティックHTMLがアクセシビリティの土台
HTMLには、
コンテンツが何なのかをブラウザへ伝えるための要素があります。
例えば、
・header
・nav
・main
・article
・section
・aside
・footer
などです。
適切な要素を使うことで、
見た目だけではなく、
ページのどこに何があるのか
という構造をHTMLとして表現できます。
支援技術は、こうしたHTMLの意味や見出し、ランドマークなどを手がかりとしてページを理解します。

セマンティックなページ構造を確認します。
<header>
<p>
<a href="/">ToshiLab</a>
</p>
<nav>
<a href="/">ホーム</a>
<a href="/web-programming/">WEBプログラミング</a>
</nav>
</header>
<main id="main-content">
<article>
<h1>HTMLとアクセシビリティ</h1>
<section>
<h2>セマンティックHTML</h2>
<p>
意味に合ったHTML要素を使ってページ構造を表します。
</p>
</section>
</article>
<aside>
<h2>関連記事</h2>
<p>Modern HTMLシリーズの関連記事を紹介します。</p>
</aside>
</main>
<footer>
<p>© ToshiLab</p>
</footer>HTMLランドマークはページ内を移動する手がかりになる
mainやnavなどには、支援技術がページ内の主要な領域を把握するための手がかりとなる意味があります。
例えばmainは、
そのページの主要コンテンツ
を表します。
navは、
主要なナビゲーション
を表します。
asideは、
本文と関連する補足的な内容
などに使用できます。
headerやfooterも、配置される文脈によって意味が変わります。
例えばページ全体を表すheaderはbannerランドマークとして扱われますが、
articleやsection内部のheaderは、そのセクションの導入部分を表し、
同じbannerランドマークにはなりません。
footerも同様に、ページ全体のfooterと、
articleなどの内部にあるfooterでは役割が異なります。
大切なのは、
「ランドマークを増やせばアクセシブルになる」
ということではありません。
ページ構造に合ったHTMLを使うことが基本です。
section・article・divも役割から選ぶ
Modern HTML 1-2で学んだ、
section・article・divの違いもアクセシビリティにつながっています。
articleは、
それ単体でも成立する内容
が候補です。
sectionは、
テーマを持つ内容のまとまり
に使います。
divは、
特別な意味を持たない汎用コンテナ
です。
アクセシビリティのために、
divをすべてsectionへ変更する
という考え方ではありません。
なお、sectionを使っただけで必ずランドマークになるわけではありません。
sectionにaria-labelledbyやaria-labelなどでアクセシブルな名前が与えられている場合には、regionランドマークとして扱われます。
例えば、aria-labelledbyでsection内の見出しを関連付け、
その見出しをregionの名前として利用できます。
ただし、ランドマークを増やすこと自体を目的にsectionへ名前を付ける必要はありません。
まず内容の意味から要素を選びます。
今回も、
この内容は何なのか
から要素を選びます。
見出しは見た目ではなく階層で選ぶ
h1からh6は、
文字サイズを変えるための要素ではありません。
ページ内の情報が、
どのような階層になっているのかを表します。
基本形として、
ページ全体の主題をh1、
その大きな区切りをh2、
h2の中の小さな区切りをh3、
というように整理します。
論理的な見出し階層の例で確認します。
<h1>HTMLとアクセシビリティ</h1>
<h2>セマンティックHTML</h2>
<h3>ランドマークの考え方</h3>
<h3>見出し階層</h3>
<h2>キーボード操作</h2>
<h3>フォーカス</h3>HTML見た目を大きくしたいから、
h2の次にh4を選ぶ
といった使い方は避けます。
見た目はCSSで調整し、
HTMLでは情報の階層を表します。
見出しは、単なる大きな文字ではありません。
支援技術を利用するユーザーが、
ページ内の見出しを一覧したり、
見出しから見出しへ移動したりするための手がかりにもなります。
そのため、
文章構造に沿った見出し階層
を作ることが重要です。
リンクとボタンは役割で使い分ける
リンクとボタンは、
見た目を似せることができます。
しかしHTMLとしての役割は異なります。
基本的には、
別のページや場所へ移動する → a
何かを実行する → button
と考えます。
リンクとボタンの配置例で確認します。
<a href="/help/">
ヘルプを見る
</a>
<button type="button">
保存する
</button>HTML例えば、
「ヘルプページを見る」
ならリンクが自然です。
一方、
「保存する」
「メニューを開く」
「フォームを送信する」
などの操作はbuttonが候補になります。
クリックできる見た目を作りたいからといって、
divへクリック処理だけを追加する方法を基本形にしません。
buttonには、
ボタンであるという意味やキーボード操作など、ブラウザが標準で持っている機能があります。
フォームではラベルと説明の関係を伝える
Modern HTML 1-4では、
label・input・fieldset・legendなどを使ったフォーム設計を学びました。
これらもアクセシビリティと深く関係しています。
例えば、
入力欄には見えるlabelを用意し、
forとidで関連付けます。
さらに、
「ハイフンなし7桁で入力してください」
のような補足説明がある場合には、
aria-describedbyを使って入力欄と説明文を関連付けることができます。
label+aria-describedbyをコードで確認します。
<label for="email">
メールアドレス
</label>
<input
type="email"
id="email"
name="email"
aria-describedby="email-help"
>
<p id="email-help">
仕事で使用しているメールアドレスを入力してください。
</p>HTMLここで大切なのは、
aria-describedbyはlabelの代わりではない
ということです。
labelは、
「この入力欄は何なのか」
を伝えます。
aria-describedbyは、
「入力するときに追加で知ってほしい説明」
を関連付けます。
役割が異なります。
キーボード操作とフォーカスを考える
マウスやタッチ操作だけでなく、
キーボードだけでも操作できることはWebアクセシビリティの重要な土台です。
button・hrefを持つa・input・select・textareaなど、多くのネイティブHTML要素には、ブラウザが標準でキーボード操作やフォーカスの仕組みを持っています。

フォーカスが見える状態を残す
Tabキーでページ内を移動すると、
現在どの要素を操作しているのかを示すフォーカス表示が重要になります。
デザイン上の理由だけで、
outline: none;
としてフォーカス表示を消してしまうと、
キーボード利用者が現在位置を判断しにくくなります。
必要に応じて、
:focus-visible
などを使い、分かりやすいフォーカス表示へ調整します。
見えるフォーカスの例で確認します。
:focus-visible {
outline: 3px solid currentColor;
outline-offset: 3px;
}CSStabindex=”0″は通常のTab順序へ加える
通常、buttonやhrefを持つaなどのネイティブな操作要素には、
わざわざtabindexを追加する必要はありません。
tabindex=”0″を指定すると、
要素を文書の通常の順序に沿ったTab移動へ参加させることができます。
ただし、
tabindex=”0″を付けただけでは、その要素がbuttonになるわけではありません。
EnterやSpaceでの操作や、ボタンとしての意味が自動的に追加されるわけではありません。
そのため、
buttonで作れるものをdiv + tabindexで作り直すのではなく、
まずネイティブHTMLを使います。
tabindex=”-1″はTab順序には入れない
tabindex=”-1″を持つ要素は、
通常のTab移動には入りません。
一方で、JavaScriptなどから必要なタイミングでフォーカスを移動する対象にはできます。
エラー概要など、
処理後にプログラムからフォーカスさせたい領域で使われる場合があります。
tabindex=”-1″の基本形を確認します。
<div
id="error-summary"
tabindex="-1"
>
入力内容を確認してください。
</div>HTMLtabindex="-1"は通常のTab順序には入りませんが、
スクリプトからフォーカス対象にできます。
<!-- 基本的に避ける -->
<div tabindex="1">
内容
</div>HTML正のtabindexで操作順を作らない
tabindex=”1″
tabindex=”2″
のような正の数値を使えば、Tab移動の順序を変更できます。
しかし、
HTMLに書かれている順序と、
画面上の見た目と、
キーボードの操作順がずれる原因になります。
基本的には、
HTMLそのものを論理的な順序で記述する
ことを優先します。
発展|スキップリンクで主要コンテンツへ移動する
ページの先頭には、
ロゴやナビゲーションなど、毎ページ共通する内容が続く場合があります。
キーボード操作で毎回それらをすべて通過するのは負担になることがあります。
そこで、
ページの主要コンテンツへ直接移動できる、
スキップリンク
を用意する方法があります。
スキップリンクをコードで確認します。
<a href="#main-content">
メインコンテンツへ移動
</a>
<header>
<!-- ヘッダー・ナビゲーション -->
</header>
<main id="main-content">
<h1>HTMLとアクセシビリティ</h1>
</main>HTMLmainをスキップリンクの移動先にすることで、繰り返されるナビゲーションを飛ばして
主要コンテンツへ移動できます。
ARIAはHTMLで不足する情報を補う
ARIAは、
Accessible Rich Internet Applications
の略で、
HTMLだけでは十分に伝えられない役割・状態・関係などを支援技術へ伝えるための仕組みです。
ただし、
ARIAを付ければ付けるほどアクセシブルになる
わけではありません。
同じ意味と動作を持つネイティブHTMLがある場合は、
まずHTMLを使用します。

aria-labelでアクセシブルな名前を補う
例えば、
虫眼鏡のアイコンだけを表示した検索ボタン
があるとします。
見た目だけなら検索ボタンだと理解できても、
ボタン内にテキストがなければ、その目的を十分に伝えられない場合があります。
このような場面では、
aria-label
でアクセシブルな名前を補う方法があります。
aria-label+aria-hiddenをコードで確認します。
<button
type="button"
aria-label="検索"
>
<svg
aria-hidden="true"
viewBox="0 0 24 24"
>
<!-- 検索アイコン -->
</svg>
</button>HTMLアイコンだけのbuttonなど、適切な可視ラベルが存在しない場合はaria-labelでアクセシブル名を補えます。
装飾SVGはaria-hidden="true"で支援技術から除外できますが、
フォーカス可能な要素自体へaria-hidden="true"を付けないようにします。
ただし、画面上に適切なラベルを表示できるのであれば、
まず見えるテキストを使う方法を検討します。
aria-labelは、
見えるラベルを何でも非表示にするための仕組みではありません。
aria-describedbyで追加説明を関連付ける
先ほどフォームで確認したaria-describedbyは、
対象となる要素と、
追加の説明文
を関連付けるために使います。
ラベルは対象の名前を伝え、
説明は追加情報を伝える。
この違いを意識すると、
aria-labelとaria-describedbyを使い分けやすくなります。
動的な更新はライブリージョンで伝える
JavaScriptを使ったWebアプリでは、
ページを再読み込みしなくても、
・保存完了
・アップロード完了
・検索結果の更新
・処理状況の変更
などが画面上で変化することがあります。
視覚的には変化が分かっても、
支援技術を利用しているユーザーへ自動的に伝わるとは限りません。
そこで、
aria-live
などのライブリージョンを利用できます。
重要度が通常の通知であれば、
aria-live=”polite”
が候補になります。
ライブリージョンは、
更新が起こる前に領域を用意しておき、その後に内容を変更する
ことが基本です。
aria-liveによる通知をコードの例で確認します。
初期HTMLでは先に空の領域を用意します。
<div
id="save-status"
aria-live="polite"
>
</div>HTML保存処理などが完了したあと、JavaScript側から、
document.getElementById("save-status").textContent =
"保存が完了しました。";JavaScriptのように内容を更新します。
ライブリージョンは更新前から用意しておくのが基本です。
通常の通知にはpoliteが候補になり、緊急性のない通知でassertiveを乱用しません。
保存完了などのステータスメッセージでは、role=”status”を利用する方法もあります。
role=”status”には、暗黙的にaria-live=”polite”とaria-atomic=”true”が設定されます。
そのため、ユーザーの現在の操作を強く中断せずに状態の変化を伝えたい場面に向いています。
aria-hiddenで装飾を支援技術から除外する
アイコンなど、
見た目の装飾だけを目的とし、
同じ意味が別のテキストですでに伝わっている場合があります。
このような操作できない装飾要素では、
aria-hidden=”true”
を使ってアクセシビリティツリーから除外する方法があります。
aria-label+aria-hiddenのSVGアイコンでも、この考え方を使います。
ただし、
フォーカスできる要素へaria-hidden=”true”を設定してはいけません。
また、aria-hiddenはその子要素にも影響するため、
操作可能な要素を含む親へ安易に付けないようにします。
ARIAはネイティブHTMLの置き換えではない
例えば、
<div role="button">
保存する
</div>HTMLと書いただけで、
divがHTMLのbuttonと同じ動作になるわけではありません。
role=”button”は意味を伝えますが、
本来のbuttonが持っているキーボード操作などをすべて自動で追加するものではありません。
buttonを使える場面なら、
buttonが必要ならbuttonを使う。
リンクが必要ならaを使う。
入力欄にはlabelを使う。
ページ構造には意味に合ったHTML要素を使う。
そのうえで不足する情報だけをARIAで補います。
アクセシビリティでも、
Native HTML First
が基本です。
実務ではどこで使う?
WordPressの記事構造
記事タイトル・H2・H3などの見出し階層を整理し、
見た目だけを理由に見出しレベルを選ばないようにします。
グローバルナビゲーション
navを使ってナビゲーションであることを表現します。
複数のnavがある場合は、それぞれを識別できる名前を付けることも検討します。
フォーム
label・fieldset・legendなどを先に使い、
補足説明やエラーとの関連付けが必要な場合にaria-describedbyなどを検討します。
アイコンボタン
検索や閉じる操作など、
アイコンだけでは名前を伝えられないボタンではaria-labelなどを検討します。
JavaScriptで更新されるUI
保存完了や処理結果など、ページを再読み込みせず変化する情報では、
aria-liveやrole=”status”が必要かを検討します。
独自UI
最初からdivとJavaScriptで作るのではなく、
button・details・dialog・popoverなど、
HTML標準の仕組みで実現できないかを先に確認します。
アクセシビリティはHTMLだけで完結しない
今回扱っているのは、
HTMLからできるアクセシビリティ
です。
実際のWebサイトでは、
・文字と背景のコントラスト
・文字サイズ
・フォーカス表示
・レスポンシブデザイン
・アニメーション
・入力エラーの見せ方
・JavaScriptによる状態管理
なども関係します。
これらはModern CSSやModern JavaScriptでも改めて扱います。
HTMLだけですべてを解決するのではなく、
それぞれの技術の役割を組み合わせてWeb体験を作ります。
今回できるようになったこと
- セマンティックHTMLがアクセシビリティの土台になる理由を理解できる
- ランドマークの考え方を理解できる
- 見出しを論理的な階層で整理できる
- リンクとボタンを役割から使い分けられる
- labelとaria-describedbyの違いを理解できる
- キーボード操作を前提にHTMLを考えられる
- 見えるフォーカスを残す理由を理解できる
- tabindex=”0″とtabindex=”-1″の違いを理解できる
- 正のtabindexを避ける理由を説明できる
- ARIAよりネイティブHTMLを優先できる
- aria-labelを使う場面を判断できる
- aria-describedbyで追加説明を関連付けられる
- aria-liveやrole=”status”の目的を理解できる
- aria-hidden=”true”を使う場面と注意点を理解できる
Modern HTML 1-7 ミニチェック
Q1
クリックすると保存処理を実行するUIを作ります。
見た目を自由にしたいから、
divへrole=”button”を付けて作る方法と、
button要素を使う方法があります。
基本形として、まずどちらを選ぶのがよいでしょうか?
Q2
メールアドレス入力欄の下に、
「仕事で使用しているメールアドレスを入力してください」
という補足説明があります。
labelを残したうえで、この補足説明とinputを関連付けたい場合、
どのARIA属性が候補になるでしょうか?
Q3
ユーザーが保存ボタンを押したあと、
ページを再読み込みせずに、
「保存が完了しました」
というメッセージが表示されます。
フォーカスを無理に移動させず、支援技術へこの更新を伝えたい場合、
どのような仕組みが候補になるでしょうか?
ミニチェックの答えは次の記事の冒頭に掲載します。
「Modern HTML|ミニチェック回答・解説」
で確認できるようにします。
回答集では正解だけでなく、
なぜその要素になるのか
まで解説します。
まとめ
Modern HTML 1-7では、
HTMLから考えるWebアクセシビリティについて整理しました。
今回の大きなポイントは、
・意味に合ったHTML要素を使う
・見出しを論理的な階層で構成する
・リンクとボタンを役割から選ぶ
・フォームには適切なラベルを付ける
・キーボードでも操作できる構造にする
・フォーカス位置を分かるようにする
・tabindexで無理に操作順を作らない
・ARIAをネイティブHTMLの代わりにしない
・HTMLだけでは不足する情報をARIAで補う
・動的な更新ではライブリージョンを検討する
という点です。
アクセシビリティを、
「あとから追加する特別な機能」
と考えるのではなく、
HTMLを書く段階から意味と操作を正しく設計する
ことが重要です。
まずネイティブHTML。
それでも足りない部分をARIAで補う。
Modern HTMLシリーズで続けてきた、
Native HTML First
は、アクセシビリティでも重要な基本方針になります。
前回を確認する
Modern HTML 1-6では、
画像・レスポンシブ画像・audio・videoなどのHTMLメディア
について整理しました。

次に読む
次回は、
Modern HTML 1-8|head・メタデータ・SEOとの接続
へ進みます。
ページ本文だけではなく、
title・description・canonical・robots・viewportなど、
ブラウザや検索エンジンへページ情報を伝えるためのHTMLを整理します。


