🚀

HTMLにおける見出しタグとセクショニングコンテンツの役割

2021/08/19に公開

はじめに

マークアップをする上でよくhタグの使い方を気をつけたほうが良いと聞きますが、実際HTMLとしてどのような機能をしているのか不明だったためHTML Living Standardを読みこみました。
そこでの解釈をまとめをまとめています。認識が間違っている点があればぜひご指摘ください。

参考
https://momdo.github.io/html/sections.html

言葉の定義

まずここの理解で大切な「セクション」と「アウトライン」という言葉を先に解説します。

セクションとは

セクションは、元のDOMツリーで一部のノードに対応するコンテナである。各セクションは、セクションに関連付けられた1つの見出しを持つことができ、さらにネストされた任意の数のセクションを含むことができる。アウトラインのためのアルゴリズムはまた、特定のセクションおよび潜在的な見出しをもつDOMツリーにおける各ノードを関連付ける。

ちょっと解釈が難しいが、

  • 特定の範囲のノードをラップする。
  • その範囲のノードを関連付ける。
  • 1つの見出しとネストした下層のセクションを含む

簡単に言い換えると、見出しと見出しに関連したコンテンツをまとめた範囲をセクションと言うっぽい。
普通のセクションと意味はあまり変わりがないが、見出しとセットなのがちょっと違う。

ちなみにDOMツリーやノードに対する解説はこちらの記事がわかりやすい。
https://zenn.dev/ak/articles/c28fa3a9ba7edb

アウトラインとは

アウトラインは文章順序、読み込みの順序を表現するもので、アウトラインの階層が浅い順から読み込まれる。
そして、セクショニングルート、セクショニングコンテンツ、見出しタグで定義される。

このセクションは、セクショニングコンテンツ要素またはセクショニングルート要素に対するアウトラインを作成するためのアルゴリズムを定義する。これは、入力される場合かつ歩行中に終了する場合に各ノードが訪問している状態で、ツリー順に、DOMツリーのノード上の歩行に関して定義される。
ツリー とは、有限かつ階層的なツリー構造である。 ツリー順序 は、深さ優先かつ前順による走査に基づく。
https://triple-underscore.github.io/DOM4-ja.html#concept-tree-order

つまり、見出しタグやセクショニングコンテンツを整えることで、HTMLの読み込み(アウトライン)を正しく定義できるということですね。

では、詳しく仕様を見ていきます。

見出しとセクションの仕様

アウトラインはセクショニングルートに対して作成される

セクショニングルート要素は独自のアウトラインを持つことができ、要素の内側のセクションと見出しは祖先のアウトラインに影響を受けません。

セクショニングルートの要素
body blockquote details dialog fieldset figure td

多くの場合HTML文書のアウトラインはbody要素のアウトラインとなります。他のセクショニングルート要素は全く別のアウトラインになっているぐらいに捉えていれば良さそうです。

セクショニングコンテンツはセクションの範囲を明示する

section article nav asideはセクショニングコンテンツと呼ばれ、セクションの範囲を明らかにします。

レイアウト上どうしても文書の意味とマークアップの順序がずれることがありますが、セクショニングコンテンツを使うことで、綺麗な文章構造にすることができます。

<h1>青森県産のりんご</h1>
<p>りんごは赤いと美味しい</p>
<h2>青森県産のりんごは赤い</h2>

アウトライン

- 青森県産のりんご (- りんごは赤いと美味しい)
  - 青森県産のりんごは赤い
<h1>青森県産のりんご</h1>
<section>
  <p>りんごは赤いと美味しい</p>
  <h2>青森県産のりんごは赤い</h2>
</section>

アウトライン

- 青森県産のりんご
  - 青森県産のりんごは赤い (- りんごは赤いと美味しい)

セクショニングコンテンツは階層を一つ深くする

セクショニングコンテンツで囲むと、階層が一つ深くなったアウトラインが作成されます。

<h1>青森県産のりんご</h1>
<h1>青森県産のりんごは赤い</h1>
- 青森県産のりんご
- 青森県産のりんごは赤い
<h1>青森県産のりんご</h1>
<section>
  <h1>青森県産のりんごは赤い</h1>
</section>
- 青森県産のりんご
  - 青森県産のりんごは赤い

hタグが使われたところからセクションが開始される

hタグを使うと、そこからセクションの開始だと判断されます。

hタグがセクションを構築するということが直感的にはわかりにくいかと思いますが、以下の2つの例は同じアウトラインになります。

// ①
<body>
  <h1>フルーツ</h1>
  <h2>りんご</h2>
  <h2>赤い</h2>
  <h2>美味しい</h2>
</body>

//②
<body>
  <h1>フルーツ</h1>
  <section>
    <h2>りんご</h2>
  </section>
  <section>
    <h2>赤い</h2>
  </section>
  <section>
    <h2>美味しい</h2>
  </section>
</body>
- フルーツ
 - りんご
 - 赤い
 - 美味しい

セクショニングコンテンツの中の最初のhタグがそのセクションの見出しを表す。

セクショニングコンテンツ内の最初のhタグがそのセクションの見出しとなります。見出しのランクの大小は関係ありません。

このような文書構造だと、どちらも「赤い」はセクションの見出しになります。

// ①
<section>
  <h1>赤い</h1>
  <h2>りんご</h2>
  <p>赤いりんごは美味しいです。</p>
</section>

// ②
<section>
  <h4>赤い</h4>
  <h1>りんご</h1>
  <p>赤いりんごは美味しいです。</p>
</section>

セクショニングコンテンツの中の2番目以降のhタグ

直前のhタグ以下のランクのhタグであるならば、サブセクションが開始される。

これは直感的な内容ですね。
前のhタグより小さいランクのhタグを使ったら、一階層下のサブセクションとして展開されます。

<body>
  <h1>フルーツ</h1>
  <section>
    <h1>赤い</h1>
    <h2>りんご</h2>
    <p>赤いりんごは美味しいです。</p>
  </section>
</body>
- フルーツ
  - 赤い
    -りんご

直前のhタグのランク以上のhタグがあるならば、新しいセクションが開始される。

ここはすこし注意が必要で、直前のhタグ以上のランクのhタグであれば新しいセクションになります。
h1を使ったからと言って、そのセクショニングコンテンツ以上のアウトラインの階層にはなりませんし、直前のhタグ以上の階層になることもありません。
直前がh3であれば、アウトライン上h1もh2もh3も同等となります。

<body>
  <h1>フルーツ</h1>
  <section>
    <h3>赤い</h3>
    <h1>りんご</h1>
    <p>赤いりんごは美味しいです。</p>
  </section>
</body>
- フルーツ
  - 赤い
  - りんご

例題

文章で見ただけだと理解が難しいので、色々なサンプルを作ってみました。
HTMLの後にアウトラインを記載していますので、どのようなアウトラインになるか考えてみてください。

例題1

// ①
<body>
  <h1>フルーツ</h1>
  <section>
    <h1>赤い</h1>
    <h1>りんご</h1>
    <p>赤いりんごは美味しいです。</p>
  </section>
</body>

// ②
<body>
  <h1>フルーツ</h1>
  <section>
    <h4>赤い</h4>
    <h1>りんご</h1>
    <p>赤いりんごは美味しいです。</p>
  </section>
</body>

// ③
<body>
  <h1>フルーツ</h1>
  <section>
    <h2>赤い</h2>
    <h3>りんご</h3>
    <p>赤いりんごは美味しいです。</p>
  </section>
</body>

アウトライン

// ①
- フルーツ
  - 赤い
  - りんご

// ② (①と同じですね。)
- フルーツ
  - 赤い
  - りんご

// ③
- フルーツ
  - 赤い
    - りんご

①と②は同じ階層のセクションが2つできたアウトライン、③はセクションの中にサブセクションができる形となります。

例題2

// ①
<body>
  <h1>title</h1>
  <h2>りんご</h2>
  <h2>赤い</h2>
  <h2>美味しい</h2>
</body>

// ②
<body>
  <h1>title</h1>
  <section>
    <h1>りんご</h1>
  </section>
  <section>
    <h1>赤い</h1>
  </section>
  <section>
    <h1>美味しい</h1>
  </section>
</body>

// ③
<body>
  <h1>title</h1>
  <section>
    <h1>りんご</h1>
  </section>
  <section>
    <h2>赤い</h2>
  </section>
  <section>
    <h4>美味しい</h4>
  </section>
</body>

全て同じアウトラインになります。

- title
  - りんご
  - 赤い
  - 美味しい

例題3

// ①
<body>
  <h1>title</h1>
  <section>
    <h1>AAA</h1>
    <h2>BBB</h2>
  </section>
  <section>
    <h1>CCC</h1>
    <h1>DDD</h1>
  </section>
</body>

// ②
<body>
  <h1>title</h1>
  <section>
    <h3>AAA</h3>
    <h4>BBB</h4>
  </section>
  <section>
    <h2>CCC</h2>
    <h2>DDD</h2>
  </section>
</body>

こちらの2つも等価なアウトラインです

- title
  - AAA
    - BBB
  - CCC
  - DDD

他にもサンプルは沢山あるので、気になる方は確認してみてください。
https://momdo.github.io/html/sections.html#sample-outlines

セクションに関係するタグ

body

body要素はHTMLの中でコンテンツを表し、HTMLの中で一つだけ使うことが推奨されている。
またbodyセクショニングルート要素となるので、HTMLのアウトラインはbodyをルートとして考える事となる。

article

article要素は、サイトの中で自己完結した構造を表す。
原則として独立して配布可能なまたは再利用可能なものである。例えば、フォーラムの投稿、記事、ユーザーの投稿コメント、対話的なウィジェットやガジェットが当てはまる。

section

section要素は明示的にセクションの範囲を表す、一般的なセクションタグ。
見出しを伴い、その主題を表すコンテンツのグループを示す。

sectionはアウトラインに影響を与えるため、単純なスタイル付けやスクリプトの付与のために使われるならdivを使うことが推奨されている。
スタイル目的ではなく、アウトラインの形成のために意図的にsectionを使いましょう。

nav要素はナビゲーションリンクをもつセクションや他ページへリンクするページのセクションなどに使う。

注意点

  • セクショニングコンテンツであるので、リンクのグループとしてnav要素を使うのではなく、主要なナビゲーションブロックから成るセクションとして使用する。
  • フッターにnav要素は不要である。footerはナビゲーションを含むのが一般的であるし、セクションの役割を果たすため。
  • ページに一つだけしか使えないと言われることもあるが、別に2つ使っても良い

ちなみに、nav要素はスクリーンリーダーの読み上げをスキップできるので、アクセシビリティの観点からもnav要素のマークアップを決めたほうが良い。

aside

aside要素は、周りのコンテンツに関連するコンテンツから構成され、かつそのコンテンツとは別のものと見なすことができるセクションを表す。
一般的にサイドバーに使われる。

h1~6

セクションの見出しを定義し、要素名の数字で与えられたランクを持つ。

hgroup

hgroup要素は複数見出しを1つのグループにし、そのグループの中で最高ランクのhタグのランクがhgroupのランクとみなされる。
また、最高ランク以外の見出しは、補助的なテキストとされる。

こちらのhgroupはh1と認識され一つのアウトラインを形成する。また、フルーツ(美味しい)のような意味合いになる。
h1とh2をhgroupで囲まないと2つのアウトラインが作成される。

<hgroup>
 <h1>フルーツ</h1>
 <h2>美味しい</h2>
</hgroup>

良く見出しに装飾として英語が使われるが、このような時に使うとよい

<hgroup>
 <h1>Feature</h1>
 <h2>特徴</h2>
</hgroup>

header要素は、前置きまたはナビゲーション補助のグループを表す。
hタグを含まれることが望まれるが必須ではない。ページナビゲーションや検索フォーム、ロゴを含むことが多い。
明確な定義がないため、一般的にヘッダーの機能を持つ部分はheaderで囲もう。

注意事項
headerはアウトラインに含まれない。

footer要素は直近の祖先のセクションニングコンテンツまたはセクショニングルートのフッターを表す。footer自体はセクショニングコンテンツではない。

footerも明確な定義がなく、誰が書いたか、関連文書へのリンク、著作権データなど、そのセクション関する情報を一般に含むとされている。
こちらも一般的にフッターの機能を持つ部分はfooterで囲もう。

まとめ

hタグはテキストの強調度合いをランク付けるというイメージでしたが、セクションを定義するための要素の意味合いが強いようで大きく認識が変わりました。

根拠がないのでSEO上の優劣の話は出来ませんが、今回の内容がSEOに関わるならば「h1は何回使っても良い」「h1がなくてもh2を使っても良い」とされる理由が納得できます。

ただ、HTML上一緒だからといって適当にhタグのランクを付けたり、セクショニングコンテンツを使うべき所をhタグのみで代替してしまうと可読性が落ちてしまいます。

HTMLの挙動を理解した上で、人間とgoogle両方に正しいマークアップができるように頑張りたいと思います。

Discussion