見出しタグ設計の基本:h1〜h6の階層・飛び・重複をセルフレビューする手順

見出しタグ(h1h6)は、ページの 目次構造そのもの です。「ここの文字を大きくしたいから 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)はなぜダメか

スクリーンリーダーと検索エンジンが混乱する

HTML
<!-- NG: h3 を飛ばしている -->
<h2>スライダーの実装</h2>
<h4>Swiperを使う場合</h4>

スクリーンリーダーは見出しレベルを階段として読み上げます。h2 の次にいきなり h4 が来ると、ユーザーは「親項目がどこか」を見失います

検索エンジンも、h2h4 の関係を正しく解釈できません。h3 が省略されているのか、あるいは意図的な階層ジャンプなのかの判断がつかず、ページ構造の評価が安定しなくなります。

正しい書き方

HTML
<h2>スライダーの実装</h2>
<h3>Swiperを使う場合</h3>
<h3>Splideを使う場合</h3>

上位レベルが存在する前提で下位レベルを使うのが基本です。

一段だけ飛ぶのもNG

h1 → h3 も階層ジャンプです。上位が存在しないのに下位レベルを使うパターンで、見た目のサイズを揃えるためにh3を選んだ結果として発生しがちです。

見た目とレベルを分離したい場合は、CSSで h2.is-small のような装飾クラスを用意するか、<h3> の見た目を h2 と揃えるクラスを当てる方が、文書構造としては正しくなります。

同一見出しの重複

何が起きるか

HTML
<h3>注意点</h3>
<!-- ... -->
<h3>注意点</h3>
<!-- ... -->
<h3>注意点</h3>
  • アウトラインとして意味が取りにくい(どの「注意点」か文脈なしで判別できない)
  • アンカーリンクが壊れる(目次プラグインがIDを自動生成する場合、同じIDが複数生まれる or 連番で上書きされる)
  • 目次からクリックしても 最初の項目にしか遷移しない 現象が起きる

対処法

  1. 文脈で書き分ける(一番推奨)
    • 注意点インストール時の注意点 / 運用時の注意点
  2. 連番を付ける
    • 注意点 (1) 注意点 (2)

書き分けが可能なら常に1を選びます。2の連番は、章の内容自体が似通っているサインなので、章分けの設計そのものを見直すきっかけ にもなります。

アンカーIDの決め方

目次や #id 付きリンクを張る場合、アンカーID(<h2 id="...">)の命名規則も重要です。

推奨パターン

  • 英数とハイフンのみ: installation autoplay-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. 見出しレベルを一覧する

目視で確認する場合は、ブラウザの開発者ツールのコンソールで以下を実行します。

JavaScript
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に重複がないか確認します。

JavaScript
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個あり、章分けができている
  • 階層ジャンプ(h2h4 など)が発生していない
  • 同一テキストの見出しが重複していない(書き分けができている)
  • 空の見出しが残っていない
  • アンカーIDに日本語やスペースが混ざっていない
  • 記事タイトル(WordPressなら自動で h1)と本文の最上位見出しレベルが衝突していない

この7項目が通れば、見出し構造の観点では公開OKです。

まとめ

見出しタグはページの骨格です。見た目を揃えるために選ぶものではなく、目次としての階層を正しく表すもの として選びます。

  • h1は基本1つ、記事タイトルと本文最上位の競合に注意
  • 階層ジャンプはSEOとアクセシビリティの両方を損なう
  • 重複見出しはアンカーリンクを壊す
  • アンカーIDは英数ハイフンで統一

手元の記事HTMLを貼り付けて階層ジャンプや重複を一覧確認したい場合は Heading Outline Generator のようなツールを使うと、見出しのレベル・テキスト・アンカー候補・階層ジャンプ警告を一画面で確認できます。metaタグの最終確認を合わせて行うなら Meta Tag Generator も参考にしてみてください。

read next