HTML

Content model

コンテンツ・モデルの意味

 どの要素にどんなコンテンツを入れても良いかを定義したものを、コンテンツ・モデルと呼びます。すべての要素にコンテンツ・モデルが定義されています。HTMLでマークアップする場合は、コンテンツ・モデルを意識する必要があります。

 例えば、article要素のコンテンツ・モデルとして、フロー・コンテンツが挙げられます。これは、article要素の中には、フロー・コンテンツに属する要素を入れてよいという事を意味します。

 このように、コンテンツ・モデルとして、カテゴリーが定義されている事が多いのですが、中には、カテゴリーではない定義もあります。ここでは、HTMLの要素に規定されているコンテンツ・モデルのパターンをいくつか見ていきましょう。

パターン① カテゴリーに制限

 多くの要素のコンテンツ・モデルは、カテゴリーによって定義されています。

 例えば、section要素のコンテンツ・モデルは、フロー・コンテンツおよびセクショニング・コンテンツと定義されています。つまり、これらのカテゴリーに属する要素であれば、section要素の中に入れても良い事になります。

正しい例


<section>
	<h1>...</h1>
	<p>...</p>
	<article>...</article>
</section>

 section要素の中に入れた h1要素、p要素、article要素は、いずれもフロー・コンテンツかセクショニング・コンテンツに属する要素です。そのため、このマークアップに問題はありません。

 次に、誤った例を見てみます。

誤った例


<section>
	<style>...</style>
</section>

 style要素は、scoped属性が指定されていない限り、メタデータ・コンテンツとなります。そのため、style要素を section要素の中に入れる事はできません。

パターン② 特定の要素に制限

 一部の要素のコンテンツ・モデルは、カテゴリーではなく、特定の要素に限定しているものがあります。例えば、hgroup要素のコンテンツ・モデルは、1個以上の h1~h6要素と定義されています。

正しい例


<hgroup>
	<h1>...</h1>
	<h2>...</h2>
</hgroup>

 つまり、hgroup要素の中には、h1から h6要素ではない要素を入れてはいけないという事を表します。

 ここで、hgroup要素のコンテンツ・モデルでは個数まで指定されている点に注意してください。「1個以上」という定義があります。したがって、hgroup要素の中が空っぽというわけにはいきません。

誤った例


<hgroup></hgroup>
<hgroup>
	<p>...</p>
</hgroup>

 この誤った例では2つの hgroup要素がありますが、いずれも正しくありません。

パターン③ 子孫の要素に制限

 通常、コンテンツ・モデルの定義は、その要素の子、つまりその要素の直下に入れる要素を制限するものです。その要素の子の中に何を入れて良いかについては、子のコンテンツ・モデルに依存します。しかし、一部の要素では、コンテンツ・モデルで子孫の要素を制限するものがあります。

 例えば、address要素のコンテンツ・モデルはフロー・コンテンツです。しかし、子孫にヘッディング・コンテンツとセクショニング・コンテンツ、そして、header要素と footer要素を入れてはいけない事になっています。

 例えば、h1要素はフロー・コンテンツですが、ヘッディング・コンテンツにも属しています。そのため、address要素に h1要素を入れる事はできません。同様に、section要素もフロー・コンテンツですが、セクショニング・コンテンツにも属しています。そのため、address要素に入れる事はできません。

 一方、div要素はフロー・コンテンツですが、ヘッディング・コンテンツにも、セクショニング・コンテンツにも属しません。そのため、address要素の中に div要素を入れる事ができます。

 しかし、address要素のコンテンツ・モデルでは「子孫」という用語を使っています。そのため、次の例は正しくありません。

誤った例


<address>
	<div>
		<section>...</section>
	</div>
</address>

 div要素はフロー・コンテンツです。そのため、address要素に div要素を入れる事自体に問題はありません。そして、div要素のコンテンツ・モデルはフロー・コンテンツです。そのため、div要素の中に section要素を入れる事自体にも問題はありません。しかし、address要素のコンテンツ・モデルでは、子孫にセクショニング・コンテンツを入れてはいけない事になっていますので、この親子関係は、address要素の中においては正しくないという事になります。

パターン④ 空

 一部の要素のコンテンツ・モデルとして、「空」と定義されているものがあります。これは、その要素にはコンテンツを入れる事が出来ない事を表します。br要素や hr要素などの空要素が該当します。

パターン⑤ トランスペアレント

 一部の要素では、そのコンテンツ・モデルとしてトランスペアレントと定義されているものがあります。要素のコンテンツ・モデルがトランスペアレントというのは、その要素のコンテンツを、そのまま、その要素と置換えたとしても、HTMLの仕様に準拠しなければいけない事を意味します。

 簡単に言えば、それは「コンテンツ・モデルとして透過である」という意味です。言い換えると「親要素のコンテンツ・モデルを継承する」という意味です。決して「透明で見えなくなる」という意味ではありません。

 もう少し具体的に説明しましょう。要素αの中に要素βがあったとします。そして、要素βのコンテンツ・モデルがトランスペアレントだったとしましょう。この場合、要素αのコンテンツ・モデルとして定義された要素、つまり、要素αに入れても良い要素でなければ、要素βには入れてはいけないという事になります。つまり、要素αのコンテンツ・モデルが、そのまま要素βにも適用されるという事になります。

 また、もう少し別の見方でトランスペアレントを説明するなら、もし要素βのコンテンツ・モデルがトランスペアレントであるならば、要素βの開始タグと終了タグを HTMLから削除したとしても、HTMLとして準拠していなければいけないという事になります。

a 要素の例


<p>私は<a href="cat.html"><em>猫</em>がほしかったんだ</a>!</p>

 この DOMは次のようになります。

上記例の DOM


└p
 ├私は
 ├a href="cat.html"
 │ ├em
 │ │ └猫
 │ └がほしかったんだ
 └!

 もし a要素の開始タグと終了タグを削除したら、その DOMは次のようになります。

a要素の開始タグと終了タグを削除した場合の DOM


└p
 ├私は
 ├em
 │ └猫
 ├がほしかったんだ
 └!

 これは HTMLの文法として問題ありません。つまり、a要素のコンテンツの中に入れられていたコンテンツは、p要素のコンテンツとしても、HTMLに準拠していなければいけないのです。

 では、間違った例を見てみましょう。

間違った例


<em>
	<a href="content.html">
		<section>...</section>
	</a>
</em>

 em要素の直下に a要素を入れる事は、問題がありません。また、a要素の直下に section要素を入れる事にも、問題はありません。しかし、この例から a要素の開始タグと終了タグを削除してみてください。em要素の直下に section要素が来る事になります。em要素のコンテンツ・モデルはセクショニング・コンテンツを禁止していますので、この例は正しくないという事になります。

 このように、コンテンツ・モデルがトランスペアレントになる要素は a要素の他にもいくつかあります。canvas, video, audio など、フォールバック・コンテンツを入れる事が出来るような要素では、条件にもよりますが、そのコンテンツ・モデルはトランスペアレントになります。