「ここは目立たせたいから <h2>、そこまで大きくしたくないから <h4>」というように、文字の大きさを基準に見出しタグを選んでいませんか。見た目だけを見れば確かにそれで整いますが、見出し要素が本来担っているのは文書の構造を示すことで、大きさはあくまで結果です。この記事では、<h1> から <h6> までのランクの意味、階層を飛ばしてはいけない理由、<h1> は 1 ページに 1 つという考え方、そしてサブタイトルの書き方までを、コードを見ながら整理します。
目次
見出し要素は文字を大きくするための道具ではない
<h1> の h は heading(見出し)の頭文字で、<h1> から <h6> までの 6 つが用意されています。数字は「その見出しが文書のどの深さにあるか」を表すもので、これをランクと呼びます。数字が小さいほど上位、大きいほど下位です。
ブラウザーはこのランクに応じた既定のスタイルを持っているため、<h1> が大きく、<h6> が小さく表示されます。ただしこれは「そう表示すると分かりやすいから、ブラウザーがそう決めているだけ」であって、要素の意味そのものではありません。文字の大きさは CSS でいくらでも変えられますが、ランクが表す文書構造は CSS では変えられない、という関係になっています。
まずは基本の形を見てください。見出しの下に、その見出しが受け持つ内容が続く、という並びになります。
<h1>お問い合わせフォームの作り方</h1>
<p>この記事ではフォームの基本を解説します。</p>
<h2>入力欄を作る</h2>
<p>input 要素を並べていきます。</p>
<h3>type 属性で入力の種類を変える</h3>
<p>text や email などを指定します。</p>
<h2>送信ボタンを付ける</h2>
<p>button 要素を使います。</p>
このコードには <section> も <div> も出てきませんが、それでも「フォームの作り方」という大きな話の下に「入力欄を作る」と「送信ボタンを付ける」という 2 つの節があり、前者の中に「type 属性で入力の種類を変える」という小節がある、という構造が読み取れます。見出しのランクだけで階層が表現できている状態です。この読み取りをブラウザーや支援技術、検索エンジンも行っている、と考えてください。
h1 から h6 までのランクと使いどころ
6 つのランクがそれぞれどの深さに対応するのかを、一般的なページの構成にあてはめて整理すると次のようになります。要素そのものに「ページタイトル専用」「章専用」といった決まりがあるわけではなく、あくまでその見出しが入れ子構造の何段目にあるかで選びます。
| 要素 | ランク | 典型的な使いどころ |
|---|---|---|
<h1> | 最上位 | そのページ全体を代表する見出し。記事タイトルやサイト名 |
<h2> | 2 段目 | ページを大きく区切る章の見出し |
<h3> | 3 段目 | 章の中をさらに分ける節の見出し |
<h4> | 4 段目 | 節の中の細かい項目の見出し |
<h5> | 5 段目 | 仕様書やマニュアルなど、階層が深い文書で使う |
<h6> | 最下位 | さらに深い階層。通常の Web ページではほとんど出番がない |
実際のところ、ブログ記事やコーポレートサイトのページであれば <h1> から <h3>、深くても <h4> までで足ります。<h5> や <h6> まで必要になっているときは、階層が深すぎて読者が構造を追えなくなっている可能性が高いので、章の分け方そのものを見直したほうがよい、というサインだと考えてください。なお <h6> より下のランクは存在しないため、7 段目が欲しくなった時点で構成に無理があります。
階層を飛ばさずに順番どおり下げる
見出しのランクを下げるときは、1 段ずつ下げます。<h2> の次の階層はかならず <h3> であって、いきなり <h4> にはしません。次のコードは、よくやってしまう飛ばし方の例です。
<h1>料金プラン</h1>
<h2>個人向けプラン</h2>
<p>個人でお使いいただけるプランです。</p>
<!-- h3 を飛ばして h4 にしている(見た目を小さくしたかっただけ) -->
<h4>スタンダード</h4>
<p>月額 980 円のプランです。</p>
ここで <h4> が選ばれた理由は、たいていの場合「<h3> だと文字が大きすぎたから」です。しかし読み取る側は文字の大きさではなく数字を見ているので、この書き方は「<h2> と <h4> の間に、3 段目にあたる見出しが抜け落ちている」という不完全な構造として伝わります。目次を自動生成するツールが空の階層を作ってしまったり、支援技術の利用者が「レベル 3 の見出しを読み飛ばしてしまったのでは」と混乱したりする原因になります。
正しくは次のように、ランクは 1 段ずつ下げ、文字の大きさは CSS で調整します。
<h1>料金プラン</h1>
<h2>個人向けプラン</h2>
<p>個人でお使いいただけるプランです。</p>
<h3>スタンダード</h3>
<p>月額 980 円のプランです。</p>
<h3>プレミアム</h3>
<p>月額 1,980 円のプランです。</p>
<h2>法人向けプラン</h2>
<p>チームでお使いいただけるプランです。</p>
注意したいのは、この「飛ばさない」というルールが下げるときだけのものだという点です。上に戻るときは何段飛ばしても構いません。上のコードでも <h3>「プレミアム」の次に <h2>「法人向けプラン」が来ていますが、これは「3 段目の話が終わって 2 段目に戻った」という意味なので何の問題もありません。<h4> の次に <h2> が来るような書き方も同様に正しい構造です。
h1 を 1 ページに 1 つにする理由
<h1> は、そのページ全体が何のページなのかを表す見出しです。「このページを一言で言うと何か」に対応するものなので、原則として1 ページに 1 つにします。記事ページなら記事タイトル、商品ページなら商品名、といった具合です。
誤解されやすいのですが、<h1> を複数書いても HTML の文法エラーにはなりません。バリデーターも通ります。それでも 1 つに絞ることが勧められるのは、複数あると「このページの主題はどれなのか」が読み取れなくなるからです。支援技術の利用者にとっても、検索エンジンにとっても、最上位の見出しが 2 つ 3 つ並んでいる文書は主題の判断がつきにくい状態になります。
section で囲んでも h1 は自動で降格しない
ここで必ず知っておきたいのが、「<section> や <article> で入れ子にすれば、中の <h1> は自動的に下位の見出しとして扱われる」という誤った情報です。次のようなコードを紹介している解説を見たことがあるかもしれません。
<h1>料金プラン</h1>
<section>
<!-- 入れ子なので h2 相当になる…わけではない -->
<h1>個人向けプラン</h1>
<section>
<!-- さらに入れ子なので h3 相当になる…わけでもない -->
<h1>スタンダード</h1>
</section>
</section>
この書き方をしても、3 つの <h1> はいずれもレベル 1 の見出しのままです。入れ子の深さによってランクが読み替えられることはありません。スクリーンリーダーは「見出しレベル 1」を 3 回読み上げますし、支援技術や解析ツールが見るのも要素のランクそのものです。結果として、階層のない平坦な文書として扱われてしまいます。
なお、ブラウザーの既定スタイルによって入れ子の <h1> の文字が小さく表示されることがありますが、それは見た目だけの話で、ランクが変わったわけではありません。主要ブラウザーはこの既定スタイルを取り除く方向に動いており、Chrome では入れ子にした <h1> について開発者ツールに警告が表示されるようになっています。「小さく表示されたから降格した」と判断しないでください。
実装されなかったアウトラインアルゴリズム
この誤解には出どころがあります。HTML5 が策定されていた時期の仕様には、<section> などのセクショニング要素の入れ子から文書のアウトライン(目次構造)を組み立て、その中で見出しのレベルを決める、というアウトラインアルゴリズムの記述がありました。これが実現していれば、部品を別のページに移植してもレベルが自動調整される、という便利な世界になるはずでした。
しかし、このアルゴリズムはどのブラウザーにも支援技術にも実装されませんでした。実装のないまま仕様だけが存在する状態が長く続き、その間に「section で囲めば h1 でよい」という解説だけが広まってしまった、というのが経緯です。現在の HTML 仕様からはこの記述は取り除かれており、代わりに文書の階層は h1〜h6 のランクで明示的に表現することが求められています。
つまり、実務上の結論はとてもシンプルです。<section> や <article> で構造を囲むこと自体はよいことですが、その中の見出しには、入れ子の深さに合ったランクを自分で書く必要があります。
<h1>料金プラン</h1>
<section>
<h2>個人向けプラン</h2>
<section>
<h3>スタンダード</h3>
</section>
</section>
ランクは HTML、見た目は CSS で決める
ここまで繰り返してきたとおり、見出しタグを選ぶ基準は文書の階層であって、文字の大きさではありません。逆に言えば、大きさや装飾は CSS で自由に決めてよいということです。デザイン上 <h3> を <h2> より大きく見せる必要があるなら、そう書いても構造は壊れません。
下のデモでは、正しい階層でマークアップした見出しに CSS で大きさと装飾を当てています。最後の 1 行に注目してください。ここは「目立たせたいだけの飾り文字」なので、見出しではなく <p> にクラスを付けています。CSS タブの値を変えると、ランクと見た目が独立していることが確かめられます。
<article class="post">
<h1>お問い合わせフォームの作り方</h1>
<p>この記事ではフォームの基本を解説します。</p>
<h2>入力欄を作る</h2>
<p>input 要素を並べていきます。</p>
<h3>type 属性で入力の種類を変える</h3>
<p>text や email などを指定します。</p>
<h2>送信ボタンを付ける</h2>
<p>button 要素を使います。</p>
<p class="note">\ 3分で作れます /</p>
</article>
body {
font-family: sans-serif;
line-height: 1.8;
margin: 16px;
}
/* 見出しのランクは HTML で決め、大きさや装飾は CSS で決める */
.post h1 {
font-size: 22px;
border-bottom: 3px solid #007bff;
padding-bottom: 8px;
}
.post h2 {
font-size: 18px;
border-left: 6px solid #007bff;
padding-left: 10px;
}
.post h3 {
font-size: 15px;
color: #007bff;
}
/* 目立たせたいだけの行は見出しにしない。段落にクラスを当てる */
.note {
font-size: 24px;
font-weight: bold;
text-align: center;
color: #e8710a;
}
マークアップするときの判断はこの順番で行うと迷いません。まず「この行は文書の中で節の始まりを示しているか」を考え、示しているならランクを決めて見出し要素にします。示していない(ただ目立たせたいだけ)なら、見出し要素は使わず、段落などにクラスを当てて CSS で装飾します。デザインカンプの文字サイズからタグを逆算しない、というのがコツです。
header 要素・hgroup とサブタイトルの書き方
見出しの周辺には、名前が紛らわしい要素がいくつかあります。役割の違いを整理しておきましょう。
header は見出しそのものではなく容れ物
<header> は「導入部分をまとめる容れ物」であって、それ自体が見出しになるわけではありません。<header> だけを書いても、支援技術に見出しとして伝わることはありません。見出しはあくまで、その中に置いた <h1>〜<h6> です。
また <header> は 1 ページに 1 つとは限らず、記事ごとの導入部分として <article> の中に置くこともできます。「ページ全体のヘッダー」と「記事のヘッダー」が同じ要素で表せる、と考えると分かりやすいでしょう。
<article>
<header>
<!-- 見出しになるのは header ではなく h1 のほう -->
<h1>お問い合わせフォームの作り方</h1>
<p>公開日: <time datetime="2026-08-12">2026年8月12日</time></p>
</header>
<p>本文が続きます。</p>
</article>
サブタイトルは hgroup の中に p で書く
困るのが、タイトルにキャッチコピーやサブタイトルが添えられているデザインです。よくあるのが、次のようにサブタイトルを <h2> でマークアップしてしまうパターンです。
<h1>Webool</h1>
<!-- サブタイトルなのに、2 段目の節の見出しとして扱われてしまう -->
<h2>コーディングと WordPress の実践メモ</h2>
これだと「コーディングと WordPress の実践メモ」という名前の章がページの先頭にある、という構造になってしまいます。サブタイトルは節の始まりではないので、見出しにしてはいけません。
こうした「タイトルとそれに添える文言」をひとまとまりとして示すための要素が <hgroup> です。現在の仕様では、<hgroup> の中に入れられるのは <h1>〜<h6> のいずれか 1 つと、その前後に置く <p> だけ、と決まっています。見出しを 2 つ入れることはできません。
<hgroup>
<h1>Webool</h1>
<p>コーディングと WordPress の実践メモ</p>
</hgroup>
この書き方なら、見出しは <h1> の「Webool」だけで、サブタイトルは見出しではない添え物である、という関係がマークアップに表れます。<hgroup> を使っても中の <p> が見出しとして扱われるわけではない、という点が重要です。<hgroup> を使わず、単に <h1> の次に <p> を置くだけでも構造としては間違いではありませんが、まとまりを明示したいときや、CSS で 2 行をひとかたまりとして扱いたいときに便利です。
見出しに見えるのに見出しではないマークアップ
ここまでの話の裏返しとして、「画面上は見出しに見えるのに、HTML としては見出しになっていない」という状態があります。CSS フレームワークやデザイン優先の実装でとくに起こりがちで、見た目には何の問題も出ないため気付きにくいのが厄介なところです。
div にクラスを当てただけでは見出しにならない
次のようなコードは、ブラウザーで見れば立派な見出しに見えます。
<div class="title-lg">個人向けプラン</div>
<p>個人でお使いいただけるプランです。</p>
しかし <div> は「意味を持たない容れ物」なので、これは支援技術にとってただのテキストです。クラス名に title や heading と書いてあっても、クラス名に意味を読み取る仕組みは存在しません。結果として、そのページの見出しの一覧からこの行だけがごっそり抜け落ちます。
スクリーンリーダーは見出しで拾い読みする
なぜそれが問題になるのかは、スクリーンリーダーの使われ方を知ると腑に落ちます。スクリーンリーダーの利用者は、ページを頭から最後まで聞くわけではありません。見出しだけを順に飛ばして読み上げさせ、目的の箇所を探してから本文を聞く、という読み方をよくします。晴眼者がページをスクロールしながら太字の行を目で拾っていくのと同じことを、見出し要素を手がかりに行っているわけです。
そのため、見出しであるべき行が <div> で書かれていると、その節はナビゲーションの一覧に現れず、たどり着く手段がなくなります。逆に、見出しではない飾り文字を <h2> で書いてしまうと、章でも何でもない文言が目次に紛れ込んで邪魔になります。どちらも「見た目は正しいのに構造は間違っている」という状態です。
既存のコードをどうしても書き換えられない事情がある場合に限り、<div role="heading" aria-level="2"> のように ARIA 属性で見出しとして扱わせる方法もあります。ただしこれは代替手段であって、素直に <h2> と書けるならそちらを選ぶべきです。ネイティブの要素であれば、ランクの指定漏れや role の書き間違いといった事故も起きません。
空の見出しと、余白のための見出し
もうひとつ避けたいのが、中身のない見出しです。次のように、装飾用の要素だけを入れた見出しや、余白を作る目的で置かれた空の見出しは、読み上げたときに「見出しレベル 2」とだけ告げられて内容が続かない、という不可解な状態になります。
<!-- 余白を作るために置かれた空の見出し -->
<h2></h2>
<!-- 罫線を引くためだけの見出し -->
<h3><span class="line"></span></h3>
余白や罫線は CSS の margin や border で作るものです。アクセシビリティの検査ツールにかけると空の見出しは必ず指摘されるので、リリース前に一度チェックしておくと安心です。ロゴ画像を <h1> に入れる場合も、<img> の alt 属性にサイト名を書いておかないと、中身が空の見出しと同じ扱いになってしまいます。
SEO の観点で見出しをどう書くか
検索エンジンは、ページの内容を理解する手がかりのひとつとして見出しを読んでいます。見出しがきちんと階層になっていれば、どこからどこまでが同じ話題なのか、そのページ全体の主題は何なのかが伝わりやすくなります。ここまで説明してきた「構造を正しく表す」という考え方は、そのまま SEO 上の望ましい書き方と一致します。
逆効果になるのは、キーワードを詰め込もうとして見出しの日本語が壊れるパターンです。「HTML 見出し h1 h2 使い方 SEO 対策」のような羅列は、読者にとって何が書いてあるのか分からず、内容の要約にもなっていません。見出しに求められるのは、その下に続く内容を短く言い表していることだけです。目次だけを読んで記事の流れが分かる状態になっていれば、それが読者にとっても検索エンジンにとっても良い見出しです。
もうひとつ、<title> 要素と <h1> の関係もよく質問されます。この 2 つは役割が違い、<title> はブラウザーのタブや検索結果に出る「ページの外向きの名前」、<h1> はページを開いた読者が最初に目にする「本文の中の最上位の見出し」です。同じ文言にしても構いませんし、<title> だけにサイト名を付け足すといった使い分けもよく行われます。どちらか一方があればよい、というものではないので、両方を書いてください。
まとめ
<h1> から <h6> は文字を大きくするための要素ではなく、文書の階層を表す要素です。数字はランクを表し、選ぶ基準は「その見出しが入れ子構造の何段目にあるか」だけです。ランクを下げるときは 1 段ずつ下げ、<h2> の次にいきなり <h4> を置かないようにします(上に戻るときは何段飛ばしても構いません)。<h1> はページの主題を表すため原則 1 つにし、<section> で入れ子にしても <h1> が自動で降格することはない、という点に注意してください。かつて仕様にあったアウトラインアルゴリズムは実装されないまま取り除かれ、現在は階層をランクで明示的に書くことが求められています。見た目の大きさは CSS で自由に決められるので、目立たせたいだけの行に見出し要素を使う必要はありません。逆に、見出しであるべき行を <div> で書くと、見出しで拾い読みするスクリーンリーダーの利用者からその節が見えなくなります。サブタイトルは <hgroup> の中に <p> で書き、見出しには内容を短く言い表した言葉を入れる。この 2 点を守るだけでも、構造の正確さは大きく変わります。