ページのラッパー、ナビゲーション、記事コンテナ、サイドバーなど、すべてに <div> を使い続けてきた方は少なくないはずです。何年もそれがデフォルトの選択でした。しかし HTML5 以降、HTML には適切なセマンティック要素が用意されており、これらを使うことでコードが読みやすくなり、SEO が改善され、アクセシビリティも本質的に向上します。本当に重要な要素を掘り下げてみましょう。
「セマンティック」という言葉は、単にその要素が視覚的な表示を超えた意味を持つことを意味します。<div> は何も意味しません — 汎用的なブロックです。<nav> はブラウザ、検索エンジン、支援技術に「これはナビゲーションリンクを含む」と伝えます。このコンテキストを追加するコストはゼロで、複数の面で効果をもたらします。
セマンティクスが重要な理由
理論ではなく、実際の3つのメリット:
- SEO。検索エンジンはドキュメント構造を使ってコンテンツの階層を理解します。
<main>要素はメインコンテンツを示します。その中の<article>は独立したコンテンツを示します。Google はこれらのシグナルをページのランキングに活用します。 - アクセシビリティ。スクリーンリーダーはランドマーク領域をユーザーに提示します。
<nav>、<main>、<aside>が適切に配置されていれば、キーボードユーザーはページ上のすべてのリンクをタブ移動することなく、目的のセクションに直接ジャンプできます。 - 保守性。テンプレートを読む新しい開発者はページ構造を瞬時に理解できます。
<header>/<main>/<footer>は<div class="top">/<div class="content">/<div class="bottom">では得られない自己文書化ができています。
コアレイアウト要素
これら5つの要素がほとんどのページの外側の骨格を担います。すべてのページで使用するだけで、セマンティクスの戦いの半分は制覇したも同然です:
<body>
<header>
<a href="/" class="logo">MyBlog</a>
<nav>
<ul>
<li><a href="/articles">Articles</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
</header>
<main>
<!-- Primary page content goes here -->
</main>
<aside>
<!-- Sidebar: related links, ads, author bio -->
</aside>
<footer>
<p>© 2026 MyBlog. All rights reserved.</p>
</footer>
</body><header>。ページまたはセクションの導入コンテンツ。通常はロゴ、サイトタイトル、メインナビを含みます。<article>内でも使用でき、記事独自の見出しブロックとして機能します。<nav>。ナビゲーションリンクのセット。すべてのリンクグループに<nav>が必要なわけではありません — サイトナビやページネーションなど主要なナビゲーションブロックに使用してください。<main>。ページの中心的なコンテンツ。1ページに1つだけ存在すべきで、ページをまたいで繰り返されるコンテンツ(ヘッダー、ナビ、フッター)を含めるべきではありません。<aside>。メインコンテンツに間接的に関連するコンテンツ。サイドバー、引用ブロック、関連記事など。スクリーンリーダーはこれを補完的なランドマークとして提示します。<footer>。ページまたはセクションのフッター。著作権情報、サブナビ、問い合わせリンク、簡単な著者メモなどを含めることができます。
<header> と <footer> はページレベルに限定されません。各 <article> や <section> は独自の <header> と <footer> を持つことができます。これはブログ記事の署名欄や記事レベルのメタデータに特に便利です。article と section — どちらを使うか
これが最も混乱を招くポイントです。実際に機能する判断基準は:コンテンツを単独で配信しても意味が通じる場合(たとえば RSS エントリとして公開したり他のサイトで共有できる場合)は <article> です。より大きな全体の一部としてのみ意味をなす場合は <section> です。
<!-- article: self-contained, could stand alone -->
<article>
<header>
<h2>Understanding HTTP/2 Push</h2>
<p>By Alice Chen — <time datetime="2026-03-15">March 15, 2026</time></p>
</header>
<p>HTTP/2 Server Push lets the server send resources...</p>
<footer>
<p>Tagged: <a href="/tags/http">HTTP</a>, <a href="/tags/performance">Performance</a></p>
</footer>
</article>
<!-- section: thematic grouping within a page -->
<section>
<h2>Related Articles</h2>
<ul>
<li><a href="/http3-quic">HTTP/3 and QUIC Explained</a></li>
<li><a href="/cdn-strategy">CDN Strategy for Global Apps</a></li>
</ul>
</section><section> には常に見出し(<h2> から <h6>)が必要です。セクションに見出しがない場合、それは通常 <div> を使うべきサインです。WHATWG 仕様は明確です:<section> はテーマ別グループ化のためであり、任意のレイアウト区分のためではありません。
figure、figcaption、time、address
開発者がよく見落とすが、日常的に必要とする4つの要素:
<!-- figure + figcaption: images, code blocks, diagrams, charts -->
<figure>
<img src="/images/latency-chart.png" alt="P99 latency over 24 hours showing a spike at 14:30">
<figcaption>Figure 1: API latency during the Tuesday incident (UTC).</figcaption>
</figure>
<!-- A code block as a figure (totally valid) -->
<figure>
<pre><code>const result = await db.query('SELECT * FROM users WHERE active = true');</code></pre>
<figcaption>Listing 1: Basic active user query.</figcaption>
</figure>
<!-- time: machine-readable dates and times -->
<p>Published <time datetime="2026-04-16T09:00:00Z">April 16, 2026</time></p>
<p>Sale ends in <time datetime="PT2H30M">2 hours 30 minutes</time></p>
<!-- address: contact info for nearest article or body ancestor -->
<address>
Written by <a href="mailto:[email protected]">Alice Chen</a>.<br>
123 Dev Street, San Francisco, CA.
</address><figure>。メインフローから参照される独立したコンテンツ — 画像、コードリスト、グラフ、動画など。ポイントは:読書の流れを妨げることなく付録に移動できること。<figcaption>。<figure>のキャプション。<figure>の最初または最後の子要素でなければなりません。画像の下の<p>では得られない、キャプションとコンテンツ間のセマンティックな関連付けを提供します。<time>。機械可読なdatetime属性付きの人間可読な日付。datetimeの値は ISO 8601 形式を使います。検索エンジンはイベントマークアップや鮮度シグナルにこれを活用します。<address>。最も近い<article>祖先(または<body>全体)の連絡先情報。汎用的なアドレス要素ではなく、コンテンツの著者またはサイトオーナーの連絡先情報専用です。
「divitis」アンチパターン
「divitis」は HTML のすべての要素が <div> になってしまう状態のことです。問題を示す実際のビフォー/アフターを見てみましょう:
<!-- Before: divitis -->
<div class="page">
<div class="header">
<div class="brand">TechBlog</div>
<div class="nav">
<div class="nav-item"><a href="/posts">Posts</a></div>
</div>
</div>
<div class="post">
<div class="post-title">Why TypeScript Is Worth It</div>
<div class="post-meta">By Bob — Jan 2026</div>
<div class="post-body">TypeScript adds static types to JavaScript...</div>
</div>
</div>
<!-- After: semantic HTML -->
<body>
<header>
<span class="brand">TechBlog</span>
<nav>
<a href="/posts">Posts</a>
</nav>
</header>
<main>
<article>
<header>
<h1>Why TypeScript Is Worth It</h1>
<p>By Bob — <time datetime="2026-01-10">January 10, 2026</time></p>
</header>
<p>TypeScript adds static types to JavaScript...</p>
</article>
</main>
</body>セマンティック版は実際には短く、CSS クラス名も少なく、ブラウザと支援ツールがページ構造を理解するために必要なすべてを提供します。CSS でまったく同じスタイルを適用できます — セマンティック要素はビジュアル上の制約を一切課しません。
ARIA ロール — 最後の手段であり、最初の選択肢ではない
ARIA ロールを使うと、ネイティブに意味を持たない要素にセマンティクスを追加できます。問題は、開発者がセマンティック HTML 要素で十分な場面で ARIA に頼りがちなことです。ARIA の第一のルール:ネイティブ HTML が使えるなら ARIA を使わない。
<!-- Wrong: using ARIA where native HTML works -->
<div role="navigation">
<a href="/home">Home</a>
</div>
<!-- Right: just use the semantic element -->
<nav>
<a href="/home">Home</a>
</nav>
<!-- ARIA is appropriate here: custom widget with no HTML equivalent -->
<div
role="tablist"
aria-label="Code examples"
>
<button role="tab" aria-selected="true" aria-controls="panel-js">JavaScript</button>
<button role="tab" aria-selected="false" aria-controls="panel-py">Python</button>
</div>ネイティブ HTML がカバーしないインタラクティブなウィジェット — タブパネル、コンボボックス、ツリービュー、日付ピッカー — には ARIA を使います。ナビゲーション、ヘッダー、メインコンテンツといった構造的なランドマークには、常にネイティブ要素を使いましょう。
ブログ記事ページの完全な構造
完全にセマンティックなブログ記事ページはこのようになります。これは余分な労力なしにアクセシビリティ監査で高得点を取るサイトで使われているパターンです:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Why TypeScript Is Worth It — TechBlog</title>
</head>
<body>
<header>
<a href="/" class="logo">TechBlog</a>
<nav aria-label="Site navigation">
<ul>
<li><a href="/posts">Posts</a></li>
<li><a href="/topics">Topics</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
</header>
<main>
<article>
<header>
<h1>Why TypeScript Is Worth It</h1>
<address>
By <a rel="author" href="/authors/bob">Bob Martinez</a>
</address>
<p>Published <time datetime="2026-01-10">January 10, 2026</time></p>
</header>
<section>
<h2>The Setup Cost Is Real but Front-Loaded</h2>
<p>TypeScript adds a compilation step and requires type annotations...</p>
<figure>
<pre><code>interface User {
id: number;
name: string;
email: string;
}</code></pre>
<figcaption>Listing 1: A typed User interface catches shape errors at compile time.</figcaption>
</figure>
</section>
<section>
<h2>Where TypeScript Pays Off</h2>
<p>The ROI kicks in as team size and codebase complexity grows...</p>
</section>
<footer>
<p>
Tagged: <a href="/tags/typescript">TypeScript</a>,
<a href="/tags/javascript">JavaScript</a>
</p>
</footer>
</article>
<aside aria-label="Related articles">
<h2>You Might Also Like</h2>
<ul>
<li><a href="/ts-vs-js">TypeScript vs JavaScript — A Practical Comparison</a></li>
<li><a href="/ts-generics">TypeScript Generics Explained</a></li>
</ul>
</aside>
</main>
<footer>
<nav aria-label="Footer navigation">
<a href="/privacy">Privacy</a>
<a href="/terms">Terms</a>
</nav>
<p><small>© 2026 TechBlog</small></p>
</footer>
</body>
</html><header> と <footer> の二重使用 — ページレベルで一度、<article> 内で一度 — に注目してください。これは意図的かつ正しい使い方です。また、異なる aria-label 値を持つ2つの <nav> 要素にも注目してください — これにより、スクリーンリーダーが同一の「navigation」領域を2つリストアップするのを防ぎます。
クイックリファレンス:役立つツール
HTML を扱いマークアップのクリーンアップや検証をしたい場合、HTML フォーマッターでコードを整形できます。HTML バリデーターは閉じていないタグや必須属性の欠落といった構造的なエラーを検出します。より詳細なアクセシビリティ監査には、web.dev/accessibility が優れた診断と説明を提供しています。
まとめ
セマンティック HTML はルールのためにルールに従うことではありません — ブラウザ、検索エンジン、支援ツール、そしてテンプレートを読む次の開発者に明確に伝わるコードを書くことです。核心となる要素はシンプルです:<header>、<nav>、<main>、<article>、<section>、<aside>、<footer> が実際のページ構造の大部分をカバーします。<figure>、<time>、<address> を適切な場所に追加し、ネイティブ HTML が不足する場合のみ ARIA を使えば、本当に気持ちよく作業できるマークアップが完成します。