コンテンツ・モデル
W3C HTML5 の「3.2.5 コンテンツ・モデル (Content models)」(W3C Working Draft 25 August 2009)を和訳したものです。
HTML5はまだ策定中の仕様のため、内容が変更されている可能性があります。正確性を求める場合は、最新の原文を参照してください。また、もし本サイトのリファレンスが、最新の仕様と異なる部分がありましたら、ご指摘頂けると幸いです。
3.2.5 コンテンツ・モデル
この仕様にあるすべての要素は、コンテンツ・モデルが定義されます。コンテンツ・モデルとは、その要素の中に、どんなノードを入れても良いかを説明するものです。しいては、HTMLドキュメントとフラグメントの構造がどうならなければいけないかを説明するものとなります。
準拠と用語の章で述べられているとおり、DOM の CDATASection ノードは Text ノードと同等に扱われ、そして、エンティティ参照ノードは、それが拡張されたかのように扱われます。こうすることで、要素がコンテンツ・モデルに一致するかしないかを決定します。
要素の間にスペース文字を入れても構いません。ユーザーエージェントは、そのマークアップ内の要素の間のスペース文字を、DOMでは、テキストノードとして扱います。空のテキストノードと、連続したスペース文字だけで構成されたテキストノードのことを、要素間ホワイトスペースといいます。
要素間ホワイトスペース、コメントノード、プロセッシング・インストラクション・ノードは、要素がコンテンツモデルに一致するかどうか確立する際には無視されなければいけません。そして、ドキュメントと要素セマンティクスを定義する次のアルゴリズムの際にも無視されなければいけません。
要素 A と要素 B があるとします。もし A と B が同じ親要素をもち、それらの間に要素ノードやテキストノード(要素間ホワイトスペースを除く)がない場合、要素 A は要素 B に前置または後置するといいます。
ウェブ制作者は、明示的に許可された場所以外で、HTML名前空間の要素を使ってはいけません。各要素で定義されているとおりに、また、他の仕様で明示的に要求があるとおりにしなければいけません。XML複合ドキュメントでは、HTML名前空間の要素を他の名前空間の要素の中に入れることができます。ただし、これら別の名前空間の要素が、関連のコンテキストを提供するものとして定義されている場合に限ります。
Atom の仕様は、Atom content 要素を定義していますが、その type 属性の値が xhtml の場合、ひとつのHTMLの div 要素を含めなければいけません。そのため、この仕様で正式にはっきりとは言っていませんが、そのコンテキストに div 要素を入れることができます。[ATOM]
さらに、HTML名前空間の要素は孤立ノードになることがあります(つまり親ノードがない)。
例えば、スクリプトで、td 要素を生成し、それをグローバル変数にセットするとします。本来、td 要素は tr 要素の中だけでしか使えないことになっているずなのですが、これは準拠しています。
var data = {
name: "Banana",
cell: document.createElement('td'),
};
3.2.5.1 コンテンツの種類
HTMLの各要素は、0個以上の似通った特徴でグループ化されたカテゴリに分類されます。次に示す広義のカテゴリが、本仕様で使われます:
- メタデータ・コンテンツ(Metadata content)
- フロー・コンテンツ(Flow content)
- セクショニング・コンテンツ(Sectioning content)
- ヘッディング・コンテンツ(Heading content)
- フレージング・コンテンツ(Phrasing content)
- エンベッディッド・コンテンツ(Embedded content)
- インタラクティブ・コンテンツ(Interactive content)
いくつかの要素は、他のカテゴリに入ることがあります。それらのカテゴリは、この仕様の別の部分で定義されています。
これらのカテゴリーの関係は下図の通りです:
加えて、ある特定の要素は、フォーム関連要素として分類され、さらに、さまざまなフォーム関連の処理モデルで役割を定義するサブカテゴリに分類されます。
固有の要件を持ち、どの特定のカテゴリにも適合しない要素もあります。
3.2.5.1.1 メタデータ・コンテンツ
メタデータコンテンツとは、他のコンテンツのプレゼンテーションやビヘイビアをセットアップしたり、該当のドキュメントと他のドキュメントとの関係をセットアップしたり、他の "範囲外" の情報を伝えたりするコンテンツのことです。
セマンティクスが主にメタデータ関連である名前空間の要素(例:RDF)も、メタデータ・コンテンツです。
故に、次のように、XML シリアル化の際に RDF を使うことができます:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:r="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<head>
<title>Hedral's Home Page</title>
<r:RDF>
<Person xmlns="http://www.w3.org/2000/10/swap/pim/contact#"
r:about="http://hedral.example.com/#">
<fullName>Cat Hedral</fullName>
<mailbox r:resource="mailto:hedral@damowmow.com"/>
<personalTitle>Sir</personalTitle>
</Person>
</r:RDF>
</head>
<body>
<h1>My home page</h1>
<p>I like playing with string, I guess. Sister says squirrels are fun
too so sometimes I follow her to play with them.</p>
</body>
</html>
しかし、HTMLシリアル化では不可能です。
3.2.5.1.2 フロー・コンテンツ
ドキュメントやアプリケーションの本体に使われるほとんどの要素は、フローコンテンツに分類されます。
aabbraddressarea(map要素の子孫だった場合)articleasideaudiobbdoblockquotebrbuttoncanvascitecodecommanddatalistdeldetailsdfndialogdivdlemembedfieldsetfigurefooterformh1h2h3h4h5h6headerhgrouphriiframeimginputinskbdkeygenlabellink(itemprop属性が存在する場合)mapmarkmathmenumeta(itemprop属性が存在する場合)meternavnoscriptobjectoloutputppreprogressqrubysampscriptsectionselectsmallspanstrongstyle(scoped属性が存在する場合)subsupsvgtabletextareatimeulvarvideo- テキスト
一般的なルールとして、コンテンツモデルがフロー・コンテンツを許可する要素は、子孫に、要素間ホワイトスペースでないテキストノードを最低ひとつ持つ、または、エンベッディッド・コンテンツである要素ノードを最低ひとつ持つ、のいずれかとなるべきです。ただし、この仕様の要求を満たすために、del 要素とその子孫要素は対象外となります。前述の子孫として数えてはいけません。
この要求は、そんなに厳しいものではありません。しかし、仕様に準拠しつつも、要素が空になることがある場合が、数多くあります。例えば、要素をプレースフォルダーとして用意し、スクリプトを使って後からその要素にコンテンツを埋める場合や、要素がテンプレートの一部を構成しており、ほとんどのページではその要素にコンテンツが埋め合わされるが、あるページでは対象外となる場合です。
3.2.5.1.3 セクショニング・コンテンツ
セクショニング・コンテンツとは、見出しやフッターを表す範囲を定義するコンテンツのことです。
各セクショニング・コンテンツ要素には見出しとアウトラインを入れることを想定しています。詳細については、「見出しとセクション」をご覧ください。
セクショニング・ルートとなる要素もあります。セクショニング・コンテンツとは区別されますが、同じくアウトラインを入れることができます。
3.2.5.1.4 ヘッディング・コンテンツ
ヘッディングコンテンツは、セクションの見出しを定義します。(明示的にセクショニング・コンテンツ要素を使ってマークアップしようが、ヘッディング・コンテンツ自身の存在によって示そうが、どちらでも構いません。)
3.2.5.1.5 フレージング・コンテンツ
フレージング・コンテンツとは、ドキュメントのテキストのことです。段落内のレベルでテキストをマークアップする要素も同様です。段落からフレージング・コンテンツが続きます。
a(フレージング・コンテンツのみを含む場合)abbrarea(map要素の子孫の場合)audiobbdobrbuttoncanvascitecodecommanddatalistdel(フレージング・コンテンツのみを含む場合)dfnemembediiframeimginputins(フレージング・コンテンツのみを含む場合)kbdkeygenlabellink(itemprop属性が存在する場合)map(フレージング・コンテンツのみを含む場合)markmathmeta(itemprop属性が存在する場合)meternoscriptobjectoutputprogressqrubysampscriptselectsmallspanstrongsubsupsvgtextareatimevarvideo- テキスト
一般的なルールとして、コンテンツモデルがフレージング・コンテンツを許可する要素は、子孫に、要素間ホワイトスペースでないテキストノードを最低ひとつを持つ、または、エンベッディッド・コンテンツである要素ノードを最低ひとつ持つ、のいずれかとなるべきです。この仕様の要求を満たすために、del 要素とその子孫要素は対象外となります。前述の子孫として数えてはいけません。
フレージング・コンテンツとして分類されるほとんどの要素は、フレージング・コンテンツとして分類される要素のみを含むことができます。フロー・コンテンツを含めることはできません。
テキストは、コンテンツ・モデルのコンテキストの中では、テキストノードを意味します。テキストは自身のコンテンツ・モデルとして使われることもありますが、フレージング・コンテンツでもあり、要素間ホワイトスペースとなることもあります(テキストノードが空か、スペース文字しか含んでいない場合)。
3.2.5.1.6 エンベッディッド・コンテンツ
エンベッディッド・コンテンツとは、ドキュメントに他のリソースを組み込むコンテンツや、ドキュメントに挿入された他の語彙からのコンテンツのことです。
HTML名前空間ではない名前空間にあり、メタデータではないコンテンツを伝達する要素は、この仕様で定義されるコンテンツモデルに従うと、エンベッディッド・コンテンツになります。(例えば、MathML や SVG)
いくつかのエンベッディッド・コンテンツはフォールバック・コンテンツを持つことができます。フォールバック・コンテンツとは、外部のリソースを使うことができない(例:サポートされていない形式のリソースだから)ときに利用するコンテンツのことです。この要素は、もしあれば、それはどんなフォールバックなのかを定義します。
3.2.5.1.7 インタラクティブ・コンテンツ
インタラクティブコンテンツとは、とりわけ、ユーザーとのインタラクションを想定したコンテンツのことです。
aaudio(controls属性が存在する場合)buttondetailsembediframeimg(usemap属性が存在する場合)input(type属性が Hidden 状態でない場合)keygenlabelmenu(type属性が tool bar 状態にある場合)object(usemap属性が存在する場合)selecttextareavideo(controls属性が存在する場合)
HTMLのある特定の要素は、アクティベーション・ビヘイビアを持ちます。それは、ユーザーがそれらをアクティブにすることができることを意味します。これは、アクティベーション・メカニズムに依存する一連のイベントを発出することになります。通常は、後述の通り、click イベントの後に DOMActivate イベントが続くことになります。
ユーザーエージェントは、ユーザーが手動でアクティベーション・ビヘイビアを持つ要素をアクティブにすることができるようにするべきです。例えば、キーボードや音声入力やマウスクリックです。ユーザーがクリック以外の方法でアクティベーション・ビヘイビアを持つ要素をアクティブにした場合、そのインタラクション・イベントのデフォルト・アクションでは、その要素で、疑似クリック・アクティベーション手順が実行されなければいけません。
ユーザーエージェントが要素上で疑似クリック・アクティベーション手順を実行することになったら、ユーザーエージェントは、その要素でプレ・クリック・アクティベーション手順を実行しなければいけませんが、その際に、その要素では click イベントが発出されます。この click イベントのデフォルト・アクションでは、その要素でポスト・クリック・アクティベーション手順が実行されなければいけません。もしそのイベントがキャンセルされたら、ユーザーエージェントは、代わりにその要素でキャンセル・アクティベーション手順を実行しなければいけません。
要素 target が与えられると、直近のアクティベート可能な要素は、次のアルゴリズムに従って返される要素となります:
-
target がアクティベーション・ビヘイビアを持つなら、target を返し、この手順を中止します。
-
target が親要素を持つなら、target にその親要素をセットし、最初の手順に戻ります。
-
そうでなければ、直近のアクティベート可能な要素はありません。
ポインティング・デバイスがクリックされたら、ユーザーエージェントは次の手順を実行しなければいけません:
-
ユーザーによって指定された要素があれば、e をその直近のアクティベート可能な要素とします。
-
もし要素 e があれば、その要素でプレ・クリック・アクティベーション手順を実行します。
-
必要な
clickイベントを発出します。もし要素 e があれば、click イベントのデフォルト・アクションでは、要素 e でポスト・クリック・アクティベーション手順を実行しなければいけません。
もし、要素 e があり、そのイベントがキャンセルされていれば、ユーザーエージェントは、要素 e でキャンセル・アクティベーション手順を実行しなければいけません。
上記は、ウェブ制作者のスクリプトによって発出される任意の疑似イベントでは起こりません。しかし、click()メソッドを使って、プログラム的に発生させることが可能です。
ユーザーエージェントが要素でプレ・クリック・アクティベーション手順を実行することになったら、その要素に定義されたプレ・クリック・アクティベーション手順があれば、それを実行しなければいけません。
ユーザーエージェントが要素でポスト・クリック・アクティベーション手順を実行することになったら、その要素で DOMActivate と呼ばれるシンプルなイベントを発出しなければいけません。このイベントのデフォルト・アクションでは、その要素でファイナル・アクティベーション手順を実行しなければいけません。もしそのイベントがキャンセルされたら、ユーザーエージェントは、代わりにその要素でキャンセル・アクティベーション手順を実行しなければいけません。
ユーザーエージェントが要素でキャンセル・アクティベーション手順を実行することになったら、その要素に定義されたキャンセル・アクティベーション手順があれば、それを実行しなければいけません。
ユーザーエージェントが要素でファイナル・アクティベーション手順を実行することになったら、その要素に定義されたアクティベーション・ビヘイビアを実行しなければいけません。アクティベーション・ビヘイビアは、この時点までにたどってきた手順によって発出された click イベントと DOMActivate イベントを参照することができます。
3.2.5.2 トランスペアレント・コンテンツモデル
いくつかの要素はトランスペアレントとして説明されています。これらの要素は、コンテンツモデルの説明欄で "トランスペアレント" と記述されます。
コンテンツモデルの一部が "トランスペアレント" なら、その部分は、次のコンテンツを含んではいけません。それは、もし、ツリー内のすべてのトランスペアレント要素が、その親要素の中で、順番を維持したまま、そのコンテンツモデルの "トランスペアレント" 部分の中にある子によって置き換えられた場合、非準拠となってしまうようなコンテンツです。
トランスペアレント要素が親要素を持たない場合、そのコンテンツモデルの"トランスペアレント"となる部分は、代わりに、フロー・コンテンツを受け入れるものとして扱われなければいけません。
3.2.5.3 段落
このセクションで定義されているように、段落という用語は、後述の p 要素とは区別されます。ここで定義される段落という概念は、どうやってドキュメントを解釈するのかを説明するために使われます。
段落とは、通常は、一つ以上のセンテンスを伴ったテキストのブロックを形成するフレージング・コンテンツの連なりのことです。センテンスでは特定のトピックを話題にしたりします。タイポグラフィーという目的においては、さらに一般的な意味づけでグルーピングするために使われることもあります。例えば、住所も段落ですし、フォームの一部として使うなら複数行になります。詩の節なんかも段落です。
次の例では、セクションに2つの段落があります。見出しもあり、段落ではないフレージング・コンテンツを含んでいます。コメントと要素間ホワイトスペースが段落を形成しない点に注目してください。
<section> <h1>段落の例</h1> これは、<em>最初の</em>段落です。 <p>これは2つ目です。</p> <!-- これは段落ではありません。 --> </section>
フロー・コンテンツの段落は、そのドキュメントがどのように見えるのかに応じて定義されます。ただし、問題を複雑にする a, ins, del, map 要素を除きます。なぜなら、これらの要素は、ハイブリッドなコンテンツ・モデルを伴いますが、段落の境界をまたぐことができるからです。これは、以降に紹介する例のうち、最初の2つに相当します。
一般的に、段落の境界をまたぐような要素の使い方は避けた方が無難です。そのようなマークアップのメンテナンスは難しくなりがちです。
次の例は前述の例のマークアップを使っていますが、テキストに変更があったことを見せるために、そのマークアップに ins と del 要素を入れています(このケースでは、変更箇所に意味はまったくありません。)。この例が、ins と del 要素があるにもかかわらず、前述の例とまったく同じ段落を持つ点に注目してください。ins 要素は見出しと最初の段落をまたいでおり、del 要素は2つの段落間の境界をまたいでいます。
<section> <ins><h1>段落の例</h1> これは、<em>最初の</em>段落</ins><del>です。 <p>これは2つ目です。</p></del> <!-- これは段落ではありません。 --> </section>
view を、ドキュメントにある a, ins, del, map 要素すべてをそのコンテンツに置き換える DOM のビューとします。そして、view の中で、別のタイプのコンテンツによって途切れることがないフレージング・コンテンツの連なりそれぞれに対して、フレージング・コンテンツではないコンテンツを受け入れる要素の中で、連なりの最初のノードを first、連なりの最後のノードを last とします。このとき、エンベッディッド・コンテンツでも要素間ホワイトスペースでもない1つ以上のノードからなる連なりそれぞれごとに、first の直前から last の直後までのオリジナルの DOM の中に段落が存在することになります。(ゆえに、段落は、a, ins, del, map 要素をまたぐ範囲となることができます。)
準拠チェッカーは、お互いにオーバーラップする段落がある場合にウェブ制作者に注意喚起することができます(これは、object, video, audio, and canvas 要素を伴うと起こりえます。)。
フレージング・コンテンツ以外のコンテンツがまったくなく、お互いに段落を分割できないとき、個々の段落を包むために p 要素を使うことができます。
次の例では、最初の段落の半分、2つの段落を分離する見出し、そして、2番目の段落の半分に至るまでリンクとなっています。このリンクは段落と見出しにまたがっています。
<aside> ようこそ! <a href="about.html"> このサイトのテーマは... <h1>ファルコン!</h1> ロッキード・マーティン社の多目的戦闘機です! </a> このページでは F-16 ファイティング・ファルコンの真相に迫ります。 </aside>
別のマークアップ方法もあります。今度は、明示的に段落を見せます。ひとつだったリンクを3つに分割します:
<aside> <p>ようこそ! <a href="about.html">このサイトのテーマは...</a></p> <h1><a href="about.html">ファルコン!</a></h1> <p><a href="about.html">ロッキード・マーティン社の多目的 戦闘機です!</a> このページでは F-16 ファイティング・ ファルコンの真相に迫ります。</p> </aside>
段落は、フォールバック・コンテンツを定義する特定の要素を使うときにはオーバーラップすることができます。例えば、次のセクションの中で:
<section> <h1>私の猫ちゃん</h1> あなたは、私の猫のシミュレータと遊べます。 <object data="cats.sim"> 次のリンクを使って、猫シミュレータを見てください: <ul> <li><a href="cats.sim">シミュレータ・ファイルをダウンロード</a> <li><a href="http://sims.example.com/watch?v=LYds5xY4INU">オンライン・シミュレータを使う</a> </ul> もしくは、メルブロム・ブラウザにアップグレードしてください。 </object> 私はこれを誇りに思う。 </section>
5つの段落があります:
- "あなたは、私の猫のシミュレータと遊べます。object 私はこれを誇りに思う。" と言っている段落。object は
object要素のことです。 - "次のリンクを使って、猫シミュレータを見てください:" と言っている段落。
- "シミュレータ・ファイルをダウンロード" と言っている段落。
- "オンライン・シミュレータを使う" と言っている段落。
- "もしくは、メルブロム・ブラウザにアップグレードしてください。" と言っている段落。
最初の段落は、他の4つの段落によってオーバーラップされています。"cats.sim" というリソースをサポートするユーザーエージェントは、最初の段落だけを表示するでしょう。しかし、フォールバックを見せるユーザーエージェントは、紛らわしいことに、最初の段落の最初のセンテンスを、あたかも2つ目と同じ段落にあったかのように、見せるでしょう。そして、最後の段落を、あたかも最初の段落の2つ目のセンテンスの開始位置にあったかのように見せるでしょう。
このような混乱を避けるべく、明示的に p 要素を使うことができます。