見出しタグ(h1〜h6)は、ページの 目次構造そのもの です。「ここの文字を大きくしたいから h2 を使う」という運用をしていると、検索エンジンとスクリーンリーダーの両方に誤解を与え、SEOとアクセシビリティを同時に落としてしまいます。
見た目は CSS で整えるものであって、見出しレベルはあくまで 文書構造 を表すためのものです。この区別ができていないサイトはいまだに多く、WordPressのテーマでも記事タイトルと本文がどちらも h1 になっていたり、目次プラグインで自動生成されたアンカーIDが衝突していたりします。
この記事では、見出しタグを正しく設計するための判断軸を、SEOとアクセシビリティの両面から整理します。最後に公開前のセルフレビュー手順もまとめています。
h1の使い方
基本は「ページに1つ」
HTML5の仕様上は複数の h1 が許容されますが、SEOとアクセシビリティの観点では1つに絞るのが無難です。
- 検索エンジンはページの主題を
h1から拾う - スクリーンリーダーはランドマークとして
h1を使う
WordPressのテーマでよくある事故は、記事タイトルと記事本文の最初の見出しがどちらもh1になっているケースです。本文側は h2 から始めるのが正しい運用で、記事タイトルが h1 として出力される以上、本文に h1 を書くと主題が2つあるページに見えてしまいます。
サイトロゴはh1にしない
トップページ以外では、サイトロゴをページ共通で <h1> に入れるとすべてのページで同じ h1 になります。ロゴは <p> や <div> で扱い、各ページの主題(記事タイトル・カテゴリ名など)を <h1> にするのが構造としては正しいです。
トップページに関しては、サイトトップが主題であるという考え方から、ロゴや大見出しを h1 にするのは自然です。
階層ジャンプ(h2 → h4)はなぜダメか
スクリーンリーダーと検索エンジンが混乱する
<!-- NG: h3 を飛ばしている -->
<h2>スライダーの実装</h2>
<h4>Swiperを使う場合</h4>
スクリーンリーダーは見出しレベルを階段として読み上げます。h2 の次にいきなり h4 が来ると、ユーザーは「親項目がどこか」を見失います。
検索エンジンも、h2 と h4 の関係を正しく解釈できません。h3 が省略されているのか、あるいは意図的な階層ジャンプなのかの判断がつかず、ページ構造の評価が安定しなくなります。
正しい書き方
<h2>スライダーの実装</h2>
<h3>Swiperを使う場合</h3>
<h3>Splideを使う場合</h3>
上位レベルが存在する前提で下位レベルを使うのが基本です。
一段だけ飛ぶのもNG
h1 → h3 も階層ジャンプです。上位が存在しないのに下位レベルを使うパターンで、見た目のサイズを揃えるためにh3を選んだ結果として発生しがちです。
見た目とレベルを分離したい場合は、CSSで h2.is-small のような装飾クラスを用意するか、<h3> の見た目を h2 と揃えるクラスを当てる方が、文書構造としては正しくなります。
同一見出しの重複
何が起きるか
<h3>注意点</h3>
<!-- ... -->
<h3>注意点</h3>
<!-- ... -->
<h3>注意点</h3>
- アウトラインとして意味が取りにくい(どの「注意点」か文脈なしで判別できない)
- アンカーリンクが壊れる(目次プラグインがIDを自動生成する場合、同じIDが複数生まれる or 連番で上書きされる)
- 目次からクリックしても 最初の項目にしか遷移しない 現象が起きる
対処法
- 文脈で書き分ける(一番推奨)
注意点→インストール時の注意点/運用時の注意点
- 連番を付ける
注意点 (1)注意点 (2)
書き分けが可能なら常に1を選びます。2の連番は、章の内容自体が似通っているサインなので、章分けの設計そのものを見直すきっかけ にもなります。
アンカーIDの決め方
目次や #id 付きリンクを張る場合、アンカーID(<h2 id="...">)の命名規則も重要です。
推奨パターン
- 英数とハイフンのみ:
installationautoplay-settings - 日本語はそのまま使わない: URLエンコードで
%E3%81%AA...のような長い文字列になり、シェア先での見た目が悪くなる
日本語を含む見出しからIDを決める場合は、意味を保つ英単語に置き換えるか、ローマ字化するのが一般的です。
自動生成されたIDの衝突に注意
WordPressの「目次」プラグインや、FigmaのエクスポートSVGのように 自動生成されたIDを含むHTML を記事に混在させると、ID衝突が起きやすくなります。特にFigma由来の id="clip0_1_2" のようなIDを複数配置すると、CSSやJSの動作が壊れることがあります。
セルフレビューの手順
公開前に、記事の見出し構造を確認する手順です。
1. 記事本文のHTMLを取得する
WordPressなら公開プレビューで右クリック → 検証から <article> 部分のHTMLをコピーします。DevToolsのコンソールで document.querySelector('article').innerHTML を実行するのも手です。
ヘッダー・フッターを含めず、記事本文の範囲だけを取得するのがコツです。全体を取ると、サイト共通のナビ見出しが混ざって解析が汚れます。
2. 見出しレベルを一覧する
目視で確認する場合は、ブラウザの開発者ツールのコンソールで以下を実行します。
document.querySelectorAll('h1, h2, h3, h4, h5, h6').forEach(h => {
console.log(h.tagName, h.textContent.trim());
});
レベルとテキストが一覧できます。これで以下を確認します。
- h1が1つだけか
- h2の次にh4が来ていないか(階層ジャンプ)
- 同じテキストの見出しが繰り返されていないか
- 空の見出しが残っていないか
3. アウトラインを目視でレビューする
一覧を眺めて、アウトラインとして意味が通るかを確認します。
- h2が1つしかない → 記事の構造が浅い。h2を追加して章分けする
- 特定のh2にh3が10個以上ぶら下がっている → 章を分割する
- h4やh5まで深く掘っている → 章立てを再設計する
「目次だけ読んで何の記事かわかるか」が判断基準です。
4. アンカーIDの衝突確認
目次プラグインを使っている場合、生成されたIDに重複がないか確認します。
const ids = [...document.querySelectorAll('[id]')].map(el => el.id);
const dups = ids.filter((id, i) => ids.indexOf(id) !== i);
console.log('重複ID:', dups);
公開前チェックリスト
- ページ内の
h1が1つだけ h2が最低2〜3個あり、章分けができている- 階層ジャンプ(
h2→h4など)が発生していない - 同一テキストの見出しが重複していない(書き分けができている)
- 空の見出しが残っていない
- アンカーIDに日本語やスペースが混ざっていない
- 記事タイトル(WordPressなら自動で
h1)と本文の最上位見出しレベルが衝突していない
この7項目が通れば、見出し構造の観点では公開OKです。
まとめ
見出しタグはページの骨格です。見た目を揃えるために選ぶものではなく、目次としての階層を正しく表すもの として選びます。
- h1は基本1つ、記事タイトルと本文最上位の競合に注意
- 階層ジャンプはSEOとアクセシビリティの両方を損なう
- 重複見出しはアンカーリンクを壊す
- アンカーIDは英数ハイフンで統一
手元の記事HTMLを貼り付けて階層ジャンプや重複を一覧確認したい場合は Heading Outline Generator のようなツールを使うと、見出しのレベル・テキスト・アンカー候補・階層ジャンプ警告を一画面で確認できます。metaタグの最終確認を合わせて行うなら Meta Tag Generator も参考にしてみてください。