HTML5 では section 要素が導入され、これまでの見出し要素(h1〜h6)のみによる大雑把なドキュメントアウトラインの形成に伴う諸処の問題を、明示的に分かりやすく解決・表現できるようになりました。しかし一方で、見出し要素(h1〜h6)を使った暗黙的なセクショニングも併用することが可能であり、これが人間にとって理解しにくいドキュメントアウトラインを形成することもあります。
例えば次のマークアップの例は、
1 2 3 4 5 6 7 8 9 |
<h1>あああ</h1> <h2>いいい</h2> <h3>ううう</h3> <h4>えええ</h4> <section> <h5>おおお</h5> <h1>かかか</h1> </section> <h6>ききき</h6> |
次のアウトラインを形成します。
1 2 3 4 5 6 7 |
1. あああ 1. いいい 1. ううう 1. えええ 2. おおお 3. かかか 4. ききき |
どうでしょうか?
もしこれに違和感があるようでしたら、まだ理解が不足していると思います。
実は僕もついちょっと前まで大事な部分を誤解していたのですが、先日参加させて頂いた「MarkupCafe Osaka Vo.1」で、松田さん(@matsudasu)とこのあたりで議論になったことがきっかけで、ようやく改めて理解できた感じです(松田さんには Facebook 上で一緒に考えたり、議論をしたり、色々教えて頂いたりして大変勉強になりました!サンクスです!)。
そこで本稿では、HTML5 のセクショニングとアウトラインアルゴリズムについて、僕が個人的に理解が不足していた箇所を中心に、なるべく分かりやすく解説してみたいと思います。
なお、本稿はアウトラインアルゴリズムについての補足であり、セクショニングコンテンツやセクショニングルート、また明示的・暗黙的セクションに関しての基本的な解説は含みません。必要に応じて、次のリンク先や、他の関連コンテンツを参照してください。
— HTML5 ドキュメントのセクションとアウトラインhttps://developer.mozilla.org/ja/docs/Web/HTML/Sections_and_Outlines_of_an_HTML5_document
— 見出しとセクション
http://www.html5.jp/tag/elements/headings-and-sections.html
また、本稿での例やその他の例のアウトラインを確認したい場合には、次のサイトが便利です。マークアップが実際にはどんなアウトラインを形成するのか、自分で試してみるととても面白い発見があると思います。
— HTML 5 Outliner
http://gsnedders.html5.org/outliner/
セクション内の最初の見出し要素が、そのセクションの見出し
セクションの中の「最初の見出し要素」は、そのセクションの見出しになります。見出し要素は h1 〜 h6 のどれでも構いません。
1 2 3 4 |
<h2>あああ</h2> <section> <h3>いいい</h3> </section> |
この時、<h3>いいい</h3> は、それを囲った <section> の見出しになります。また、形成されるアウトラインは次のようなものになります。
1 2 |
1. あああ 1. いいい |
【重要】ここで <h2>あああ</h2> は、HTMLには書かれいない body 要素(セクショニングルート)の見出しになっています。この後の例でも、body 要素を省略していますが、意味的には必ず body 要素があるものとして読み取ってください。
簡単なようですが、では、次のマークアップではどのように解釈できるでしょうか?
1 2 3 4 5 |
<h2>あああ</h2> <section> <h3>いいい</h3> <h3>ううう</h3> </section> |
section 内の最初の見出し要素 <h3>いいい</h3> が section の見出しになるのであれば、次の <h3>ううう</h3> はどうなるでしょうか? h3 が連結されて <h3>いいいううう</h3> という意味合いになるでしょうか? あるいは、2個目のセクションは1つ深い階層のアウトラインとなるでしょうか?
正解は次のマークアップと同じ意味になります(分かりやすさの為に、暗黙的に作られたセクション [section] と表記してみました)。
1 2 3 4 5 6 7 |
<h2>あああ</h2> <section> <h3>いいい</h3> [/section] ← 暗黙的にセクションが終了し [section] ← 再開される <h3>ううう</h3> </section> |
明示的に開始されたセクションの見出しが最初の <h3> になるので、次の同じ <h3> のタグが現れた時点で、セクションは暗黙的に終了して同じレベルで再開されます。
暗黙的セクションは明示的セクションを超えられない
では、次の例ではどうでしょうか?
1 2 3 4 5 |
<h2>あああ</h2> <section> <h3>いいい</h3> <h4>ううう</h4> </section> |
これは素直に次のようなアウトラインを形成します。
1 2 3 |
1. あああ 1. いいい 1. ううう |
さて、では次の例ではどうでしょうか?
1 2 3 4 5 |
<h2>あああ</h2> <section> <h3>いいい</h3> <h1>ううう</h1> </section> |
この場合、アウトラインは次のようになります。
1 2 3 |
1. あああ 1. いいい 2. ううう |
セクションの見出しとなった <h3> に比べて、より高いレベルの見出し要素 <h1> が指定された為、明示的なセクションは一旦終了して再開されます。但し、見出し要素による暗黙的なセクショニングは、あくまでも明示的なセクションの中に限ってのものです。ですから、<section> タグを超えることはなく、同じレベルでセクションを再開します。
分かりやすくするために、また [section] という表記を使って、暗黙的に作られたセクションを表してみます(なお、この記法では見出し要素の番号(レベル)は意味が無くなるため、以降、見出し要素の番号の表記を省略します)。
1 2 3 4 5 6 7 |
<h_>あああ</h_> <section> <h_>いいい</h_> [/section] [section] <h_>ううう</h_> </section> |
暗黙的なセクションが明示的なセクションを超えていないことが理解できると思います。
では、さらに次の例はどうでしょうか?
1 2 3 4 5 6 7 8 9 |
<h4>あああ</h4> <section> <h6>いいい</h6> <h3>ううう</h3> <h4>えええ</h4> <h2>おおお</h2> <h5>かかか</h5> <h1>ききき</h1> </section> |
これは次のアウトラインを形成します。
1 2 3 4 5 6 7 |
1. あああ 1. いいい 2. ううう 1. えええ 3. おおお 1. かかか 4. ききき |
複雑なようですが、ここまでのお話で理解できる筈です。暗黙的セクションを [section] として表すと、これは次のように解釈されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<section> <h_>いいい</h_> [/section] [section] <h_>ううう</h_> [section] <h_>えええ</h_> [/section] [/section] [section] <h_>おおお</h_> [section] <h_>かかか</h_> [/section] [/section] [section] <h_>ききき</h_> </section> |
暗黙的セクションのアウトラインは常に1階層ずつ
見出し要素による暗黙的セクションでは、例えば次のように番号を飛ばして表記することが出来ますが、
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<h1>あああ</h1> <h2>いいい</h2> <h3>ううう</h3> <h1>かかか</h1> <h3>ききき</h3> <h6>くくく</h6> <h1>さささ</h1> <h3>ししし</h3> <h2>すすす</h2> <h3>せせせ</h3> <h4>そそそ</h4> |
セクションの階層は常に1段階ずつなので、 次のようなアウトラインを形成します。
1 2 3 4 5 6 7 8 9 10 11 |
1. あああ 1. いいい 1. ううう 2. かかか 1. ききき 1. くくく 3. さささ 1. ししし 2. すすす 1. せせせ 1. そそそ |
3つの例がありますが、2番目の例のように、h1 から h3 に飛んでもアウトラインは1階層深くなるだけです。また、3つ目の例のように、<h3>ししし</h3> と書いても階層は1つ深くなるだけなので、次の行の <h2>すすす</h2> は同じレベルで開始されます。このように、見出し要素の番号を飛ばして書いても、アウトラインの階層は常に1階層ずつ深くなることに注意が必要です。
より複雑な例で理解する
最後に、ここまでの理解を踏まえて、最初の例について考えてみます。
1 2 3 4 5 6 7 8 9 |
<h1>あああ</h1> <h2>いいい</h2> <h3>ううう</h3> <h4>えええ</h4> <section> <h5>おおお</h5> <h1>かかか</h1> </section> <h6>ききき</h6> |
上の例は、次のアウトラインを形成しました。
1 2 3 4 5 6 7 |
1. あああ 1. いいい 1. ううう 1. えええ 2. おおお 3. かかか 4. ききき |
順番に考えてみましょう。分かりやすさの為に、暗黙的セクションを [section] と表記します。なお、セクショニングルートとして body タグがあることを忘れないで確認してください。
さて、まず、最初の <h1>あああ</h1> から <h4>えええ</h4> は次の通りになると思います。
1 2 3 4 5 6 7 |
<h_>あああ</h_> [section] <h_>いいい</h_> [section] <h_>ううう</h_> [section] <h_>えええ</h_> |
これは単純ですね。
さて、<h4>えええ</h4> の後に <section> が来ますので、「暗黙的セクションは明示的セクションを超えられない」ので、全ての暗黙的セクションが終了します。
1 2 3 4 5 6 7 8 9 10 11 |
<h_>あああ</h_> [section] <h_>いいい</h_> [section] <h_>ううう</h_> [section] <h_>えええ</h_> [/section] [/section] [/section] <section> |
次に明示的セクションが開始されます。ここで、h5 が明示的セクションの見出しになりますね。
1 2 3 4 5 6 7 8 9 10 11 12 |
<h_>あああ</h_> [section] <h_>いいい</h_> [section] <h_>ううう</h_> [section] <h_>えええ</h_> [/section] [/section] [/section] <section> <h_>おおお</h_> |
次に <h1>かかか</h1> ですね。明示的セクションの見出し要素となった h5 よりも上の見出しレベルなので、明示的に開始されたセクションは、暗黙的に一旦終了して再開されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<h_>あああ</h_> [section] <h_>いいい</h_> [section] <h_>ううう</h_> [section] <h_>えええ</h_> [/section] [/section] [/section] <section> <h_>おおお</h_> [/section] [section] <h_>かかか</h_> </section> |
最後に <h6>ききき</h6> が新しいセクションを開始します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<h_>あああ</h_> [section] <h_>いいい</h_> [section] <h_>ううう</h_> [section] <h_>えええ</h_> [/section] [/section] [/section] <section> <h_>おおお</h_> [/section] [section] <h_>かかか</h_> </section> [section] <h_>ききき</h_> [/section] |
このように、順序だてて見て行くと、ある程度理解も容易になると思います。
もし「難しいな」と思うようであれば、それは見出し要素(h1〜h6)の番号に惑わされ過ぎなのかも知れません。「見出し要素の番号はアウトラインの階層を表すものでもなく、単に相対的な位置づけを表しているに過ぎない」ぐらいに思うと、より分かりやすくなるのではないかと思います。
まとめ
ここまでに見て来たように、明示的セクションと暗黙的セクションを合わせて利用するときには、いくつかの留意すべき点があり、それを誤ると、マークアップから直感的に理解できるアウトラインと、実際のアウトラインとが乖離してしまうことになります。
個人的には、以下のような点を理解していたら迷うことは無いのではないかと思っています。
- セクション内の最初の見出し要素(h*)が、そのセクションの見出しになる
- 見出し要素の番号(レベル)は、明示的セクションを超えて意味を成さない
- 暗黙的セクションは、明示的セクションを超えられない
- 暗黙的セクションは、必ず1段階ずつの階層のアウトラインを形成する
また、よく言われることですが、実務では以下のような方針を取ると、混乱が減らせて良いのではないかと思います。
- 明示的セクションの階層と、見出し要素(h*)タグを一致させる
- 明示的セクションで統一し、h1 タグしか使わない
- なるべく見出し要素で飛び番号を用いない(感覚的な階層とすぐズレるため)
以上です。
もし何か誤った解釈などがありましたら、ご指摘いただけると嬉しいです。