HTML5の技術的考察

セクション

アウトライン

さて、みなさんは、文章を作成する際、「アウトライン」を意識してWebページを作成しているでしょうか?

文章のアウトラインは、一般的には見出しによって構成されます。その見出しには、大見出し、小見出しといったレベルがあり、HTMLでは1~6段階、Microsoft Wordでは1~9段階まで用意されていました。

Wordの設定ダイアログ

Microsoft Word 2013のアウトライン・レベル

この文章もそうなのですが、文章内容を意味のまとまりでグループ化し、それをWindowsのフォルダーのように階層化したものが、アウトラインです。Wordでは、2007までは「見出しマップ」として、2010以降では「ナビゲーション」として、このアウトラインを確認することができます。

Wordの見出しリスト

Microsoft Word 2013のナビゲーションによる表示

アウトラインが適切に指定されたPDF文書であれば、Adobe Readerの「しおり」でも、同様に確認できます。HTMLは「文書構造を定義するもの」とよく言われますが、その基本は、アウトラインで文章を分かりやすくまとめるということに他なりません。

Wordで文章に見出しを付けると、それが階層構造で表されるのは、先に見たアウトライン・レベルという9段階の数値が、あらかじめ見出しに設定されているからです。では、HTMLの見出しはどうでしょうか? こちらはh1~h6というように、要素名に数値のランクが付けられ、アウトライン・レベルを表しています。

また、見出しだけでなく、HTMLの各要素も、その入れ子構造に従って階層で管理され、Internet Explorerでは「開発者ツール(F12ツール)」を使いDOMツリーという形式で階層を確認できます。

しかし、たとえばbody要素の直下にh1~h6要素を順々に記述しても、これらの要素はDOMツリーで階層構造にはなりません。


<body>
<h1>見出し1</h1>
<h2>見出し2</h2>
<h3>見出し3</h3>
<h4>見出し4</h4>
<h5>見出し5</h5>
<h6>見出し6</h6>
</body>
image017

上記ソースコードによるh1~h6要素のDOMツリー(IE11)

Wordなどワープロの文書では、このように見出しを並べて書くと、「ナビゲーション」等で見られるとおり、きちんと階層化してくれます。

Wordでの階層化

なぜ、HTML文書ではダメなのでしょうか? それは当然といえば当然で、DOMツリーの階層は、要素の入れ子関係によってのみ表されるからです。

さきに触れたように、h1~h6の見出しコンテンツには、要素内容としてフレーズ・コンテンツしか入りません。端的に言えば、h1要素の中にh2要素やp要素を入れることはできません。ですから親要素が同じなら、これらの要素は、DOMツリーでは同じレベルとして表示されます。

セクション

HTML5では、アウトライン・レベルを定義するものとして、「セクション」という概念が導入されました。この概念に従えば、見出しの要素はその1~6のランクによって、たとえツリー表示にならなくても、S・セガールを彷彿とさせる、「暗黙のセクション」による階層が存在するということになっています。

先に例示した、h1~h6までの見出し要素を記述したHTMLソースでアウトラインを確認HTML5で生成されるアウトラインは、「HTML 5 Outliner」というWebサイトで確認できます。すると、以下の図のようになります。

表示された暗黙のセクション

HTML5のアウトラインを解析するツールで表示した暗黙のセクション

しかし、「暗黙」は人間がそれとなく理解するもので、HTMLコードとしての構造が不明確です。

section要素

そこで、こうした階層構造を明示的に作成する要素のひとつとして、section要素が新設されました。この要素のコンテンツ・モデルは、次のとおりです。

section要素の定義
カテゴリーフロー・コンテンツ
セクション・コンテンツ
知覚可能なコンテンツ
使用できる文脈フロー・コンテンツであり得る場所
コンテンツ・モデルフロー・コンテンツ

そして、仕様書では次のように解説されています。

The section element represents a generic section of a document or application. A section, in this context, is a thematic grouping of content. The theme of each section should be identified, typically by including a heading (h1-h6 element) as a child of the section element.

Examples of sections would be chapters, the various tabbed pages in a tabbed dialog box, or the numbered sections of a thesis. A Web site’s home page could be split into sections for an introduction, news items, and contact information.

Note: Authors are encouraged to use the article element instead of the section element when it would make sense to syndicate the contents of the element.

Note: The section element is not a generic container element. When an element is needed only for styling purposes or as a convenience for scripting, authors are encouraged to use the div element instead. A general rule is that the section element is appropriate only if the element’s contents would be listed explicitly in the document’s outline.

訳)section要素はドキュメントあるいはアプリケーションの一般的なセクションを表します。セクションは、この文脈において、コンテンツの主題のグループ化を行います。一般に見出し(h1-h6 要素)を section 要素の子要素に含めることによって、それぞれのセクションの主題は識別されるべきです。

セクションの例は、章、タブ付きダイアログ・ボックスの各タブのページ、あるいは論文の命題別のナンバーが付けられたセクションでしょう。Webサイトのホームページも、イントロダクション、ニュース記事、そして連絡先情報といったセクションに分割できます。

注記: 独立した複数の要素のコンテンツを、並行して提供することに意味がある場合は、制作者はsection要素の代わりにarticle要素を使うことが奨励されます。

注記: section要素は一般的なコンテナ要素ではありません。要素がスタイルのために、あるいはスクリプトの都合で必要であるとき、制作者はsection要素の代わりに div 要素を使うことが奨励されます。原則として、要素のコンテンツがドキュメントのアウトラインで明示的にリストされる場合に限り、section要素が適切であるということです。

たとえば、見出し1~3で文書構造を定義するのであれば、


<body>
<h1>見出し1</h1>
<section>
	<h2>見出し2①</h2>
	<section>
		<h3>見出し3①</h3>
		<p>本文</p>
	</section>
	<section>
		<h3>見出し3②</h3>
		<p>本文</p>
	</section>
</section>
<section>
	<h2>見出し2②</h2>
	<section>
		<h3>見出し3③</h3>
		<p>本文</p>
	</section>
</section>
</body>

というsection要素の2段階の入れ子関係によって、次のような3階層のアウトラインを明示的に構成できます。

  1. 見出し1(
    1. 見出し2①(
      1. 見出し3①(
      2. 見出し3②(
    2. 見出し2②(
      1. 見出し3③(

この構成の場合、最上位ランクのh1要素がページの「タイトル」(部)、第2ランクのh2要素が「章」、第3ランクのh3要素が「節」になっているといえるでしょう。ですからsection要素は、「章-節-項」や「部-章-節-項-目」といった章節階層を定義するものとして捉えることもできます。

セクショニング・ルート

ところで、今回使用したsection要素は2つだけだったのに、生成された階層は3つでした。一番上の階層は、どこからやってきたのでしょう?その正体は、body要素です。

実際、次のように、h1要素も囲むsection要素を書いてしまうと、「Untitled Section」(無題のセクション)とされた階層がひとつ増え、4階層になってしまいます。


<body>
<section>
	<h1>見出し1</h1>
	<section>
		<h2>見出し2①</h2>
		<section>
			<h3>見出し3①</h3>
			<p>本文</p>
		</section>
		<section>
			<h3>見出し3②</h3>
			<p>本文</p>
		</section>
	</section>
	<section>
		<h2>見出し2②</h2>
		<section>
			<h3>見出し3③</h3>
			<p>本文</p>
		</section>
	</section>
</section>
</body>
Untitled Sectionの表示

Untitled Sectionがbody要素直下のsection要素によって生成されている

これは、body要素が最上位のセクションとして存在していることの証左です。

body要素は、フロー・コンテンツを入れる最上位の要素なので、自らがセクションになるセクショニング・ルートに分類されています。まあ、body要素については、セクションの総元締めと捉えておけばよいでしょう。これは、逆に言えば、body要素の直下にsection要素を入れる必要はない、ということでもあるわけです。

body要素の定義
カテゴリーセクショニング・ルート
使用できる文脈html要素内の2番目の要素
コンテンツ・モデルフロー・コンテンツ

セクション・コンテンツとセクショニング・ルートには、当然、違いがあるのですが、それはfigure要素の解説のところで後述します。

それはそれとして、この4階層構成にした場合、body要素が表すトップセクションには見出し要素が何も入っていないので、トップセクションは「Untitled Section」と認識されてしまうわけです。

ですから、section要素にはそのアウトライン・レベルを表す見出し要素を入れることが望ましいとされています。

アウトラインの構成

では、「音の無いアルバム」サイトの「第2章」ページを例にとって、アウトライン(section要素)の構成を考察してみましょう。

第2章ページの画面

音の無いアルバム「第2章」ページ

文書構造

まず、このファイルの主要な文書構造は、以下のとおりです。

第2章 文書構造概略図

「第2章」ページ 文書構造の概要

これらのうち、h1要素「第2章」から、h2要素「目次リスト」の前のp要素までを、このページの本文と考えてください。


<body>
<h2>サイトナビゲーション</h2>
<h1>第2章 </h1>
<h2>魅惑と幻惑に彩られた出発</h2>
<h2>80年代前半</h2>
<h3>ルーツを求めて</h3>
<h3>60年代の音</h3>
<h3>キンクス</h3>
<h3>デヴィッド・ボウイ</h3>
<h3>パンクロック</h3>
<h4>クラッシュ</h4>
<h4>ストラングラーズ</h4>
<h3>限りある情報を求めて</h3>
<h3>輸入盤専門店の巡礼</h3>
<h2>目次リスト</h2>
<h2>脚注</h2>
</body>
アウトライン

すると、それらのアウトラインは、h1~h4要素によって、以下のように構成されていると捉えることができます。

  1. 第2章
    1. 魅惑と幻惑に彩られた出発
    2. 80年代前半
      1. ルーツを求めて
      2. 60年代の音
      3. キンクス
      4. デヴィッド・ボウイ
      5. パンクロック
        1. クラッシュ
        2. ストラングラーズ
      6. 限りある情報を求めて
      7. 輸入盤専門店の巡礼
    3. 目次リスト(非表示)
    4. 脚注(非表示)

実際、この見出し構成のみで、「HTML5 Outliner」でアウトラインをチェックすると、以下のようになります。

第2章のアウトライン

「第2章」ページのアウトライン

先に解説したとおり、見出し要素のランクで構成しているということは、すでに暗黙のセクションが存在しているのです。

今回は、それをsection要素で明示的に構成しなおします。すなわち、見出し要素を基準として、以下のとおりにsection要素で範囲指定することになります。

セクション構成の概略図

「第2章」ページのセクション構成概略図 。h1要素「第2章」を囲むセクションは、body要素によって既に作成されている


<body>
<h2>サイトナビゲーション</h2>
<h1>第2章 </h1>
<section>
	<h2>魅惑と幻惑に彩られた出発</h2>
</section>
<section>
	<h2>80年代前半</h2>
	<section>
		<h3>ルーツを求めて</h3>
	</section>
	<section>
		<h3>60年代の音</h3>
	</section>
	<section>
		<h3>キンクス</h3>
	</section>
	<section>
		<h3>デヴィッド・ボウイ</h3>
	</section>
	<section>
		<h3>パンクロック</h3>
		<section>
			<h4>クラッシュ</h4>
		</section>
		<section>
			<h4>ストラングラーズ</h4>
		</section>
	</section>
	<section>
		<h3>限りある情報を求めて</h3>
	</section>
	<section>
		<h3>輸入盤専門店の巡礼</h3>
	</section>
</section>
<h2>目次リスト</h2>
<h2>脚注</h2>
</body>

この結果は、暗黙のセクションと、全く同じです。ただし、それが要素のツリー構造として、明示的に指定されたということです。

Outlinerでの表示結果

HTML5 Outlinerでの表示結果

アウトライン・レベルと見出しランク

なお、section要素で構成した入れ子構造に対し、必ずしも相当するランクの見出しを割り当てる必要はありません。

まず、bodyとsection要素の4段階の入れ子構造に合わせて、そのアウトライン・レベルに対し、行儀良くh2, h3, h4, h5要素を付与した例を見てみましょう。

例1

<body>
<h2>見出し2</h2>
<section>
	<h3>見出し3</h3>
	<section>
		<h4>見出し4</h4>
		<section>
			<h5>見出し5</h5>
		</section>
	</section>
</section>
</body>
例1の表示結果

HTML5 Outlinerでの例1の表示結果

その結果は、当然ですが、順序良くh2が最上位、h5が最下位のアウトライン・レベルになります。

しかし、見た目は見出し要素だけの場合と同じでも、実際のアウトラインの順位は、ここでは見出し要素のランク数ではなく、section要素の入れ子構造によって定義されているのです。そして、各section要素中にどのようなランクの見出しが入っていても、入れ子構造で表されたアウトライン・レベルが強制されているのです。

たとえば、すべての見出しをh1要素にしても、生成されるアウトライン・レベルは同じ結果になります。

例2

<body>
<h1>見出し1</h1>
<section>
	<h1>見出し1</h1>
	<section>
		<h1>見出し1</h1>
		<section>
			<h1>見出し1</h1>
		</section>
	</section>
</section>
</body>
例2の表示結果

HTML5 Outlinerでの例2の表示結果

さらには、以下のようにめちゃくちゃな見出しの付け方であっても、section要素を基にして、やはり同じアウトライン・レベルが生成されます。

例3

<body>
<h2>見出し2</h2>
<section>
	<h6>見出し6</h6>
	<section>
		<h3>見出し3</h3>
		<section>
			<h1>見出し1</h1>
		</section>
	</section>
</section>
</body>
例3の表示結果

HTML5 Outlinerでの例3の表示結果

まあ、アウトライン・レベルというものがよく分からなくても、「section要素(や他のセクショニング・コンテンツ要素、セクショニング・ルート要素)さえきちんと配置すれば、見出しのレベルに捉われることなく、アウトラインが生成できて便利だね」というコーディングのいい加減さを、HTML5は表象しているようにも見えます。

しかしこれは、「iframe要素で他のページを読み込んだり、スクリプトで他のページと組み合わせたりした場合、元ページと読み込みページで見出しレベルが一致していなくても、セクションが正しく配置されてさえいれば、アウトライン・レベルも正しく構成されるようにした」という、Webの現実的な運用に即した考え方なのです。

例4

<body>
<h2>見出し2</h2>
<section>
	<h1>見出し1</h1>
	<section>
		<h2>見出し2</h2>
		<section>
			<h3>見出し3</h3>
		</section>
	</section>
</section>
</body>

上の例4で、青字section要素の内側が外部から読み込ませる内容だと仮定するなら、その先頭にはh1要素が入っていますが、元ページは最上位の見出しとしてh2要素を持っています。もしも、見出しのランクを優先してアウトライン・レベルが決まってしまうなら、読み込まれた内容が元ページよりも上位のレベルになり、階層構造の収拾が付かなくなってしまいます。しかし、実際のアウトライン・レベルは、明示的なセクション・コンテンツの構造によって強制されるので、「HTML5 Outlinerでの例4の表示結果」の図のように、アウトラインは正しく構成されます。

外部ソース読み込みの概略図

例4で外部ソースからの読み込みを想定した領域

例4の表示結果

HTML5 Outlinerでの例4の表示結果

実際、WordPressのようなPHPプログラムなどでは、いくつかのページ内容を組み合わせて出力させる機会は、多々あります。あるWebサイトのページが

  • サイトのタイトルをh1要素
  • ページのタイトルをh2要素
  • 記事のタイトルをh3要素(この中の子セクションに別ページを読み込む)

と設定していたとします。そして、全く同じ構成で作られた別サイトのページを丸ごと読み込んだとしたら、h3要素の下にh1要素が入ることになります。たとえ、そのような事態になっても、元ページのh3要素の下にきちんと子セクションがあり、そこにh1要素以下が入るなら、見出しのランクが「1」でも、それは第4レベルのアウトライン以下に位置付けられ、整合性が保たれることになります。

そうした場合の利便性を考えたうえでの、柔軟なアウトラインの運用が本来の目的なのであり、いくら見出しを自由に入れられるからといって、面倒だからと例2のように1種類の見出しで統一したり、てきとうでいいやと例3のように滅茶苦茶な見出しの付け方をしたりすることは、言語の論理性をないがしろにする、人間としてはあるまじき行為といえるでしょう。そんな人は、アルマジロ個人的にアルマジロという生物が嫌いなわけではありません。洒落です。です。

アウトライン・アルゴリズム

さて、ここまで見てきたような、アウトライン・レベルを生成するものが、HTML5の重要な概念のひとつである、「アウトライン・アルゴリズム」です。

仕様書では、アウトライン・アルゴリズムについて、以下のように定義されています。

4.3.10.1 Creating an outline

This section defines an algorithm for creating an outline for a sectioning content element or a sectioning root element. It is defined in terms of a walk over the nodes of a DOM tree, in tree order, with each node being visited when it is entered and when it is exited during the walk.

The outline for a sectioning content element or a sectioning root element consists of a list of one or more potentially nested sections. A section is a container that corresponds to some nodes in the original DOM tree. Each section can have one heading associated with it, and can contain any number of further nested sections. The algorithm for the outline also associates each node in the DOM tree with a particular section and potentially a heading. (The sections in the outline aren’t section elements, though some may correspond to such elements — they are merely conceptual sections.)

訳)4.3.10.1 アウトラインの生成

ここでは、セクション・コンテンツ要素あるいはセクショニング・ルート要素のためにアウトラインを生成することに対して、アルゴリズムを定義します。それは、DOMツリーの階層を巡回する状態での定義になります。

セクション・コンテンツ要素、あるいはセクショニング・ルート要素のためのアウトラインは、1つ以上の潜在的にネストされたセクションのリストから成り立ちます。セクションは、DOMツリーを起点とした、いくつかのノードに対応するコンテナです。それぞれのセクションが、対応する1つの見出しを持つことができ、なおかつ複数のネストされたセクションを持つことができます。アウトライン・アルゴリズムは、同様に、DOMツリーの中でそれぞれのノードを特定のセクションと潜在的な見出しに対応させます。(ここで述べられたアウトラインのセクションは概念的なものであって、section要素だけを指すわけではありません。この概念には、他のいくつかの要素も該当します。)

では、この概念に対する理解を、深めていきましょう。

アルゴリズムの理解

「アウトライン・レベルと見出しランク」で示した例1~4では、アルマジロな「例3」も含め、実は比較的容易に理解できる構成でした。なぜかというに、それらは、或るひとつのセクションに対応する見出し要素を、レベルがどうあれ、ひとつしか入れていないからです。セクション関連要素と見出し要素が1対1の関係であれば、アウトライン・レベルは、セクションの階層構造がそのまま反映されます。

では、以下の例ではどうなるでしょうか?

例5

<body>
<h1>見出し1</h1>
<section>
	<h2>見出し2</h2>
	<h3>見出し3</h3>
	<h4>見出し4</h4>
</section>
</body>
例5の表示結果

HTML5 Outlinerでの例5の表示結果

まあ、これは比較的簡単ですね。section要素内の複数見出しは、そのランクに応じて暗黙のセクションを生成しています。section要素内に順序立てた複数の見出し要素があれば、それらすべてが順序良くアウトラインとなる次第です。

では、このsection要素内での、見出しの順序を逆転してみましょう。

例6

<body>
<h1>見出し1</h1>
<section>
	<h4>見出し4</h4>
	<h3>見出し3</h3>
	<h2>見出し2</h2>
</section>
</body>
例6の表示結果

HTML5 Outlinerでの例6の表示結果

この例では、section要素内の見出しが、そのランク(2~4)に基づく親子関係ではなく、対等な兄弟のレベルになっています。

これはいったい、どうしたことなのでしょうか? section要素が何か悪さをしているのでしょうか? いえ、section要素内の見出しにとって、親のsection要素の存在は、資本論でカール・マルクスがよく用いている表現を使えば、この場合どうでもよいことです。

話が長くなりますが、ここでまたひとつの例を提示しましょう。すなわち、section要素は使わずに、body要素内に直接h1~h6の要素を記述したものです。ただし、ランクの低いほうを先にして(h6~h1)、見出しを並べています。

例7

<body>
<h6>見出し6</h6>
<h5>見出し5</h5>
<h4>見出し4</h4>
<h3>見出し3</h3>
<h2>見出し2</h2>
<h1>見出し1</h1>
</body>
例7の表示結果

HTML5 Outlinerでの例7の表示結果

すると、上記の図のように、すべての見出しはアウトライン・レベルが対等となり、やはり兄弟として認識されます。例6の場合は、section要素の内側で、こうしたアウトライン・レベルの解釈がなされていたわけです。

つまりアウトライン・アルゴリズムは、「自分より上位ランクの見出しが後ろにある場合、その前の見出しは自身の暗黙のセクションを終了する。そして、後ろの上位ランクの見出しは、前と同じレベルでセクションを開始する」という解釈を、行っているのです。

例7では、body要素で1つのセクションが始まり、h6要素はそれのタイトルなので、これらは一体のものです。次に出てきたh5要素は、前のh6要素よりはランクが上なので、h6が表わすbody要素のセクションを終了し、同じレベルで次のセクションとなります。h4、h3、h2、h1も、同じことを繰り返しているわけです。

ソースコード的には(body要素が2つになるので実際にはあり得ませんが)、例7は、結果的に次のような明示的アウトライン構造になっているといえます。


<body>
	<h6>見出し6</h6>
</body> ←body要素が表すセクションはここで終了する!
<section>
	<h5>見出し5</h5>
</section>
<section>
	<h4>見出し4</h4>
</section>
<section>
	<h3>見出し3</h3>
</section>
<section>
	<h2>見出し2</h2>
</section>
<body>
	<h1>見出し1</h1>
</body>

例6の場合は、body要素に対して、明示的にsection要素で下位レベルのセクションを作成し、そのタイトルがh4要素です。そして、後ろのh3要素は、やはり自分が前の見出し(h4)よりランクが上なので、section要素のセクションを終了させて、自身のセクションを作成します。そのセクションは、前のsection要素と同じレベルになります。次のh2要素も同様です。

こちらも明示的なアウトラインは、以下のようになっているといえます。


<body>
<h1>見出し1</h1>
<section>
	<h4>見出し4</h4>
</section> ←section要素はここで終了する!
<section>
	<h3>見出し3</h3>
</section>
<section>
	<h2>見出し2</h2>
</section>
</body>

では、最後の例として、以下の場合を見てみましょう。

例8

<body>
<h1>見出し1</h1>
<section>
	<h4>見出し4</h4>
	<h3>見出し3</h3>
	<h2>見出し2</h2>
</section>
<h5>見出し5</h5>
</body>

例6とほぼ同じですが、section要素の後ろにh5要素を追加してあります。section要素内末尾のh2要素よりも低いランクの見出しを持ってきたわけですが、結果は以下のとおりで、h5はh2と兄弟レベルになります。

例8の表示結果

HTML5 Outlinerでの例8の表示結果

これは、なぜかというに、そもそもh5要素はsection要素の外にありました。そのアウトライン・レベルは、やはりsection要素外にあるh1要素との関係で決まります。h5はh1より下位ランクですから、body要素内で1レベル下の下位セクションを生成していたことになります。section要素も、body要素より1レベル下ですから、section要素とh5要素は兄弟になります。そして、section要素の内部が分割されてできたセクションも、これと同じレベルであり、結果として「h4、h3、h2とh5はみな兄弟」ということになる訳です。

これを明示的に表せば、以下のとおりです。


<body>
<h1>見出し1</h1>
<section>
	<h4>見出し4</h4>
</section>
<section>
	<h3>見出し3</h3>
</section>
<section>
	<h2>見出し2</h2>
</section>
<section> ←h5要素には元々暗黙のセクションが実在した!
	<h5>見出し5</h5>
</section>
</body>

もしも、section要素の後ろに来る見出しを、section要素内の見出したちよりも上のレベルに上げるとしたら、この例では、body要素直下のh1要素と同等以上のランク、すなわちh1要素を使うしかありません(例9を参照)。

例9

<body>
<h1>見出し1</h1>
<section>
	<h4>見出し4</h4>
	<h3>見出し3</h3>
	<h2>見出し2</h2>
</section>
<h1>見出し1</h1>
</body>
例9の表示結果

HTML5 Outlinerでの例9の表示結果。最後の見出しをh1要素に変更

以上のように、アウトライン・アルゴリズムというものは、見方によっては、暗黙のセクションを持つ見出し要素によって攪乱させられる、一筋縄ではいかない論理なのです。

補足: 一時at riskとされたアウトライン・アルゴリズム

この難解さのせいかどうかは分かりませんが、HTML5の重要な概念として追加されたにもかかわらず、アウトライン・アルゴリズムは、2013年8月6日の勧告候補では”at risk”(現状で使用することにはリスクあり)として、削除候補に挙げられていました。

結局、確定したW3C勧告では、そのまま残りましたが、以下の警告文が追加されています。

⚠Warning! There are currently no known implementations of the outline algorithm in graphical browsers or assistive technology user agents, although the algorithm is implemented in other software such as conformance checkers. Therefore the outline algorithm cannot be relied upon to convey document structure to users. Authors are advised to use heading rank (h1-h6) to convey document structure.

訳)警告! 適合チェッカーのような他のソフトウェアでは存在するものの、画面表示型ブラウザー、あるいは支援技術ユーザー・エージェントには、アウトライン・アルゴリズムの既知の実装が、現在はありません。そのため、アウトライン・アルゴリズムは、ユーザーに文書構造を伝達する術がありません。文書構造を伝えるために、h1~h6要素によるランクを用いることが、制作者には勧められます。

なんと恐ろしい警告でしょう。アウトライン・アルゴリズムを理解しようとHTMLページの制作者が右往左往していただけでなく、一般的なブラウザーには、このアルゴリズムを解釈する機能が搭載されていなかったのです。故に、「見出しコンテンツ要素のランクを適切に使え」ということが、この警告の結論となっています。

まあ、この長かった解説も、結局のところ、「セクション関連要素を使う場合、はじめから順序正しく、一対の見出しを付けていけば、それが一番だ」という、まっとうな結論に落ち着いた次第です。

幻のhgroup要素(仕様からは削除)

さて、話を「第2章」ページに戻すと、h2要素に基づいた初めのセクションにはh2要素が一つ入っているだけです。

そもそも、このh2要素「魅惑と幻惑に彩られた出発」は、h1要素「第2章」の“サブタイトル”として用意したものです。

見出しの画像

h1要素がページのタイトルで、h2要素はそのサブタイトルという位置付けになっている

では、この部分に明示的なセクションを作るには、どうすればよいでしょう? たとえば、以下のように区切ることにしたとします。


<body>
<h2>サイトナビゲーション</h2>
<section>
	<h1>第2章 </h1>
	<h2>魅惑と幻惑に彩られた出発</h2>
</section>
<section>
	<h2>80年代前半</h2>
	以下略

しかし、これではh1要素のセクションと、「80年代前半」のセクションが分離し、アウトライン・レベルの関係が親子から兄弟になってしまいます。

アウトラインが兄弟化

このセクションの入れ方では、「第2章」と「80年代前半」は同じレベルの兄弟セクションになってしまう。文書構造としては、「第2章」のアウトラインの下位に「80年代前半」を配置する必要がある

今回の文書構造では、h1要素のセクションの中に入れ子として、h2要素以下のセクションが入るべきです。

そこで登場するのは、かつて「hgroup」と呼ばれていたこともあった、Princeのような(新)要素です。hgroup要素は、その名のとおり見出しをグループ化します。グループ化された見出しは、その中でランクが上位の見出し(この場合はh1)だけがアウトラインに認識され、他は無視されます。


<body>
<h2>サイトナビゲーション</h2>
<hgroup>
	<h1>第2章 </h1>
	<h2>魅惑と幻惑に彩られた出発</h2>
</hgroup>
<section>
	<h2>80年代前半</h2>
	以下略

この要素のコンテンツ・モデルは、以下のようなものでした。

hgroup要素の定義
カテゴリーフロー・コンテンツ
見出しコンテンツ
使用できる文脈フロー・コンテンツであり得る場所
コンテンツ・モデルひとつ、もしくはそれ以上のh1~h6要素

先に触れたとおり、ここでのh2要素は、文書構造的にはh1要素のサブタイトルという扱いです。こうしたサブタイトルは、従来であれば見出し以外の要素で入れるとか、見出し内をbr要素で改行して入れるといった、すっきりしない方法に頼るしかありませんでした。しかし、HTML5では、見出しのようでいて見出しでないものをhgroup要素内に定義することで、このうやむや感を解決してくれます(解決してくれるはずでした…)。

hgroup要素の概念図

今は亡きhgroup要素が生きていてくれたなら、グループ内の下位ランク見出しをアウトラインから除外し、サブタイトルとして扱うことができたものを…

実は、hgroup要素は仕様から削除されてしまい、最早復活しそうにはありません。が、しかし、仕様変更の危険性世に出回っているいくつかの解説書では、出版時期などの関係もあり、hgroup要素の削除には触れられていないものがあります。を味わうため、そのまま入れておくことにします。

この結果、h2要素「魅惑と幻惑に彩られた出発」は、アウトラインから除外されます。

hgroup要素のOutliner確認結果

HTML5 Outlinerで確認した結果。当該h2要素は、アウトライン上は存在していない。

「あとから取ってつけたように現れたmain要素なんかより、よっぽど実用的な(個人の感想です)hgroup要素。なぜ、君は抹殺されてしまったんだ」と嘆いてみても、諸行無常、現実とはこのように非情なものです。

ここでは、hgroup要素を慰霊碑的に残しておきますが、実際のコーディングでは、文字列「魅惑と幻惑に彩られた出発」は、h2ではなくp要素タグで囲み、hgroup要素のタグは削除することになるでしょう。

hgroupは余談となってしまいましたが、たかが見出しの扱いぐらいに、色々と細かいところまで目配りして来ました。私は、章や節による構成を念頭に置いて文章を書いているので、section要素などによるアウトラインの定義は、親和性が高いというか、私の「作文の仕方」にとって馴染み深いものです。故に、それらを正しくHTMLに組み込むことは、喫緊の課題です。

しかし、ちょっとした記事とか、商品一覧といったページに、ここまでのアウトライン・レベルによる階層化は必要ないでしょう。いくらHTML5でsection要素が新設されたからとか、セクショニングがHTML5の重要な概念だと焚きつけられたからといって、アウトラインを構成する必要の無い文章にまで、無理にそれを適用する必要はありません。

まあ、論文調の文章を書くつもりはない、見出しの階層なんて興味がない、サブタイトルがどんな要素だって関係ない、という方は、section要素の使い方で悩むこともないでしょう。そう、サブタイトルの定義に必要なhgroup要素は、幻として消え去ったのですから。

krzm.jp:not(so-called mobile friendly)