3.2.5 コンテンツ・モデル
本仕様で定義されている要素は、それぞれに、その要素に期待されるコンテンツの種類を表すコンテンツ・モデルを持ちます。HTML 要素には、その要素のコンテンツ・モデルで記述される要件に一致するコンテンツを入れなければいけません。
準拠および用語のセクションで述べられている通り、要素がそのコンテンツ・モデルに一致するかどうかを調べる目的において、DOM にある CDATASection ノードは、Text ノードと同等であるとして扱われます。そして、エンティティ参照ノードは、それらがその場所で展開されているかのように扱われます。
スペース文字は、要素の間のどこにでも入れることができます。ユーザーエージェントは、そのソース・マークアップにある要素の間のこれらの文字を、DOM においては、テキスト・ノードとして扱います。空のテキスト・ノードと、このような文字だけで構成されるテキスト・ノードは、要素間ホワイトスペースとして扱われます。
要素間ホワイトスペース、コメント・ノード、プロセッシング・インストラクション・ノードは、要素のコンテンツがその要素のコンテンツ・モデルに一致しているかどうかを確定するときには無視されなければいけません。そして、ドキュメントと要素のセマンティクスを定義するアルゴリズムに従うときには、無視されなければいけません。
ゆえに、要素 A と要素 B が同じ親ノードを持ち、それらの間に他の要素ノードやテキスト・ノード(要素間補ワートスペースは除く)が存在していなければ、要素 A は要素 B の前にある、または、後ろにある、と言います。同様に、要素の中に、要素間ホワイトスペース、コメント・ノード、プロセッシング・インストラクション・ノード以外のノードがひとつも無ければ、その要素の子はたったひとつのノードのみとなります。
ウェブ制作者は、それぞれの要素に定義されているとおりに明示的に許可されている、または、他の仕様で明示的に必須とされている場所でない限り、HTML 要素を使ってはいけません。XML 複合ドキュメントでは、要素が関連のコンテキストを提供するものとして定義されているのであれば、これらのコンテキストは他の名前空間の要素の中に入れることができるでしょう。
例えば、Atom 仕様には content 要素が定義されています。Atom 仕様では、その type 属性の値が xhtml なら、その中に HTML の div 要素をひとつ入れる必要があります。そのため、このことが本仕様で明示的に規定として言及されていないとしても、div 要素は、そのコンテキストの中に入れても良いことになります。 [ATOM]
さらに、HTML 要素は、孤立ノードになる場合があります(つまり、親ノードがない)。
例えば、td 要素は tr 要素の中でしか使えないことになっていますが、スクリプトで td 要素を生成しグローバル変数に格納したとしても、それは準拠しています。
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要素の子孫の場合)articleasideaudiobbdibdoblockquotebrbuttoncanvascitecodecommanddatalistdeldetailsdfndivdlemembedfieldsetfigurefooterformh1h2h3h4h5h6headerhgrouphriiframeimginputinskbdkeygenlabelmapmarkmathmenumeternavnoscriptobjectoloutputppreprogressqrubyssampscriptsectionselectsmallspanstrongstyle(scoped属性が存在している場合)subsupsvgtabletextareatimeuulvarvideowbr- テキスト
一般的なルールとして、コンテンツ・モデルがフロー・コンテンツを許す要素は、要素間ホワイトスペースではないテキスト・ノードを少なくともひとつ子孫に持つか、エンベッディッド・コンテンツとなる要素ノードを少なくともひとつ子孫に持つべきです。この要件においては、del 要素とその子孫は、その del 要素の祖先に寄与するものとして数えてはいけません。
この要件はそんなに厳しいものではありません。しかし、 仕様に準拠しつつも、要素が空になることがある場合が数多くあります。例えば、要素をプレースホルダーとして用意し、スクリプトを使って後からその要素にコンテンツを埋める場合や、要素がテンプレートの一部を構成しており、ほとんどのページではその要素にコンテンツが埋め合わされるが、あるページでは対象外となる場合です。
3.2.5.1.3 セクショニング・コンテンツ
セクショニング・コンテンツは、見出しやフッターの範囲を定義するコンテンツです。
セクショニング・コンテンツ要素はそれぞれ潜在的に見出しとアウトラインを持ちます。詳細は見出しとセクションのセクションをご覧ください。
セクショニング・ルートとなる要素もあります。これはセクショニング・コンテンツとは区別されますが、同じくアウトラインを持ちます。
3.2.5.1.4 ヘッディング・コンテンツ
ヘッディング・コンテンツは、セクションのヘッダーを定義します( 明示的にセクショニング・コンテンツ要素を使ってマークアップしようが、ヘッディング・コンテンツ自身の存在によって示そうが、どちらでも構いません。 )。
3.2.5.1.5 フレージング・コンテンツ
フレージング・コンテンツはドキュメントのテキストのことです。段落内のレベルでテキストをマークアップする要素も同様です。段落からフレージング・コンテンツが続きます。
a(フレージング・コンテンツのみが入れられている場合)abbrarea(map要素の子孫の場合)audiobbdibdobrbuttoncanvascitecodecommanddatalistdel(フレージング・コンテンツのみが入れられている場合)dfnemembediiframeimginputins(フレージング・コンテンツのみが入れられている場合)kbdkeygenlabelmap(フレージング・コンテンツのみが入れられている場合)markmathmeternoscriptobjectoutputprogressqrubyssampscriptselectsmallspanstrongsubsupsvgtextareatimeuvarvideowbr- テキスト
一般的なルールとして、コンテンツ・モデルがどんなフレージング・コンテンツでも許す要素は、要素間ホワイトスペースではないテキスト・ノードを子孫に少なくともひとつ持つか、もしくは、エンベッディッド・コンテンツとなる要素ノードを子孫に少なくともひとつ持つべきです。この要件においては、del 要素とその子孫は、その del 要素の祖先に寄与するものとして数えてはいけません。
フレージング・コンテンツとして分類される要素のほとんどは、フレージング・コンテンツとして分類される要素のみを入れることができます。フロー・コンテンツを入れることができません。
テキストとは、コンテンツ・モデルという文脈においては、テキスト・ノードを意味します。テキストはときにそれ自身のコンテンツ・モデルとして使われますが、それはフレージング・コンテンツでもあり、要素間ホワイトスペースになることもあります(テキスト・ノードが空の場合か、スペース文字だけを含んでいる場合)。
3.2.5.1.6 エンベッディッド・コンテンツ
エンベッディッド・コンテンツとは、ドキュメントに他のリソースを組み込むコンテンツ、もしくは、ドキュメントに挿入される他の語彙のコンテンツのことです。
HTML 名前空間ではない名前空間の要素で、かつ、メタデータではないコンテンツを伝達する要素は、本仕様で定義されるコンテンツ・モデルにおいては、エンベッディッド・コンテンツです。(例えば、MathML や SVG)
いくつかのエンベッディッド・コンテンツ要素は、フォールバック・コンテンツを持つことができます。このコンテンツは、外部リソースを使うことができない場合(例えば、未サポートのフォーマットだった場合など)に利用するためのコンテンツのことです。この要素の定義では、もしあれば、それはどんなフォールバックなのかが提示されます。
3.2.5.1.7 インタラクティブ・コンテンツ
インタラクティブ・コンテンツは、ユーザー・インタラクションに特化したコンテンツのことです。
aaudio(controls属性が存在している場合)buttondetailsembediframeimg(usemap属性が存在している場合)input(type属性が Hidden 状態でない場合)keygenlabelmenu(type属性が toolbar 状態の場合)object(usemap属性が存在している場合)selecttextareavideo(controls属性が存在している場合)
HTML のある特定の要素はアクティベーション・ビヘイビアを持ちます。それは、ユーザーがそれらをアクティブにすることができることを意味します。これは、アクティベーション・メカニズムに依存する一連のイベントを引き起こします。通常は、後述の通り、最後には click イベントが発生することになります。
ユーザーエージェントは、アクティベーション・ビヘイビアを持つ要素をユーザーが手動でアクティブにすることができるようにするべきです。例えば、キーボードの利用や音声入力やマウス・クリックを通してです。ユーザーがクリック以外の方法でアクティベーション・ビヘイビアが定義されている要素をアクティブにしたとき、そのインタラクション・イベントのデフォルト・アクションは、その要素で疑似クリック・アクティベーション手順を実行することでなければいけません。
ユーザーエージェントが要素で疑似クリック・アクティベーション手順を実行することになった場合、ユーザーエージェントはその要素でプレ・クリック・アクティベーション手順を実行しなければいけません。それから、その要素で click イベントを発出しなければいけません。この click イベントのデフォルト・アクションは、その要素でポスト・クリック・アクティベーション手順を実行することです。もしそのイベントがキャンセルされたら、ユーザーエージェントは代わりにその要素でアクティベーション・キャンセル手順を実行しなければいけません。
ポインティング・デバイスがクリックされた場合、ユーザーエージェントは次の手順を実行しなければいけません:
-
e を、ユーザーによって指定された要素の直近のアクティブ可能要素(後述します)があれば、それにします。
-
要素 e があれば、その上でプレ・クリック・アクティベーション手順を実行します。
-
必要な
clickイベントを発出します。要素 e があれば、その
clickイベントのデフォルト・アクションは、要素 e でポスト・クリック・アクティベーション手順を実行することとしなければいけません。要素 e があるものの、そのイベントがキャンセルされたら、ユーザーエージェントは、要素 e でアクティベーション・キャンセル手順を実行しなければいけません。
上記は、ウェブ制作者のスクリプトによって発出される任意の疑似イベントでは発生しません。しかし、click() メソッドを使えば、プログラム的にそれを発生させることができます。
要素 target の直近のアクティブ化可能要素とは、次のアルゴリズムに要素 target を与えて返される要素のことです。
-
target が定義されたアクティベーション・ビヘイビアを持つなら、target を返し、これらの手順を終了します。
-
target が親要素を持つなら、target にその親要素をセットし、手順の最初に戻ります。
-
そうでなければ、直近のアクティブ化可能要素はありません。
ユーザーエージェントが要素でプレ・クリック・アクティベーション手順を実行することになったら、その要素に定義されたプレ・クリック・アクティベーション手順があれば、それを実行しなければいけません。
ユーザーエージェントが要素でアクティベーション・キャンセル手順を実行することになったら、その要素に定義されたアクティベーション・キャンセル手順があれば、それを実行しなければいけません。
ユーザーエージェントが要素でポスト・クリック・アクティベーション手順することになったら、その要素に定義されたアクティベーション・ビヘイビアがあれば、それを実行しなければいけません。アクティベーション・ビヘイビアは、この時点に至るまでの前述の手順によって発出された click イベントを参照することができます。
3.2.5.2 トランスペアレント・コンテンツ・モデル
いくつかの要素は、トランスペアレントだと説明されています。このような要素は、そのコンテンツ・モデルの説明欄に "トランスペアレント" と記述されています。トランスペアレント要素のコンテンツ・モデルは、その親要素のコンテンツ・モデルを受け継ぎます。つまり、"トランスペアレント" であるコンテンツ・モデルの役割において求められる要素とは、そのトランスペアレント要素の親のコンテンツ・モデルの役割において求められる要素と同じになります。
例えば、ruby 要素の中にある ins 要素に rt 要素を入れることはできません。なぜなら、ruby 要素のコンテンツ・モデルが ins 要素を許すのは、そのコンテンツ・モデルがフレージング・コンテンツを許しているからですが、rt 要素はフレージング・コンテンツではないからです。
トランスペアレント要素がお互いにネストされているような場合は、この一連の課程が繰り返し適用されなければいけません。
次のマークアップを考えてみましょう。
<p><object><param><ins><map><a href="/">Apples</a></map></ins></object></p>
"Apples" を a 要素の中に入れても良いかをチェックために、そのコンテンツ・モデルを調べます。 a 要素のコンテンツ・モデルはトランスアレントです。map 要素、ins 要素もしかりですが、ins 要素が入れられている object 要素のコンテンツ・モデルの一部も同様です。object 要素は p 要素の中にあります。その p 要素のコンテンツ・モデルはフレージング・コンテンツです。テキストはフレージング・コンテンツですから、ゆえに、"Apples" は許されるのです。
トランスペアレント要素に親がない場合、"トランスペアレント" であるそのコンテンツ・モデルの役割は、どんなフロー・コンテンツでも受け入れるものとして扱われることになります。
3.2.5.3 段落
このセクションで定義している段落という用語は、後で定義している p 要素とは(関連はありますが)異なります。ここで定義している段落という概念は、ドキュメントを解釈する方法を説明するために使っています。
段落とは、通常、特定の話題を扱う1つ以上の文を伴うテキストのブロックを形成するフレージング・コンテンツの連なりことで、印刷における段落と同様です。しかし、より一般的なテーマのグルーピングにも使うことができます。例えば、住所、フォームの一部、署名欄、詩の節も段落と言えます。
次の例には 1 つのセクションの中に 2 つの段落があります。見出しもありますが、段落ではないフレージング・コンテンツを含んでいます。コメントと要素間ホワイトスペースが段落を形成しない点に注目してください。
<section> <h1>段落の例</h1> これは、この例の <em>最初</em> の段落です。 <p>これは二つ目です。</p> <!-- これは段落ではありません。 --> </section>
フロー・コンテンツの中にある段落は、問題を複雑にする a, ins, del, map要素を除外して、そのドキュメントがどう見えるかに応じて定義されます。なぜ除外するのかというと、それらの要素は、ハイブリッドのコンテンツ・モデル持ち、段落の境界をまたぐことができるからです。これについては、以降の最初の 2 つの例で示されている通りです。
一般的に、要素が段落の境界をまたぐのは避けた方が良いです。そのようなマークアップをメンテナンスするのは難しいと言えます。
次の例は、前の例のマークアップを引き続き使ったものですが、いくつかのマークアップの回りに ins と del 要素を入れ、テキストの訂正を示しています(とはいえ、この例では、その訂正に意味はありません。)。この例が、 ins と del 要素があるにも関わらず、前の例と同じ段落を持っている点に注目してください。ins 要素は見出しと最初の段落をまたいでおり、del 要素は 2 つの段落の間の境界をまたいでいます。
<section> <ins><h1>段落の例</h1> これは、この例の <em>最初</em> の段落</ins> です<del>。 <p>これは二つ目です。</p></del> <!-- これは段落ではありません。 --> </section>
view を、ドキュメントにある a, ins, del, map 要素すべてを、それらのコンテンツに置き換えた DOM のビューとします。そして、view の中で、他のタイプのコンテンツによって中断されない連続するフレージング・コンテンツのそれぞれに対して、フレージング・コンテンツと同様にフレージング・コンテンツでない他のコンテンツを受け入れる要素の中で、first を一連のノードのうちの最初のノードとし、last を一連のノードのうち最後のノードとします。エンベッディッド・コンテンツでも要素間ホワイトスペースでもない少なくとも 1つのノードを構成するそのような連なりに対して、first の直前から last の直後までのオリジナルの DOM の中に、ひとつの段落が存在するということになります。(したがって、段落は a, ins, del, map 要素をまたがった範囲になることができます。)
準拠チェッカーは、お互いに重なり合う段落がある場合、ウェブ制作者に警告することができます(これは、object, video, audio, canvas 要素がある場合、そして、svg や math のように、間接的に HTML が追加で組み込むことができる他の名前空間の要素を通すことで、起こりえます)。
フレージング・コンテンツ以外のコンテンツがなく、もう段落として分離できないとき、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 つの段落が重なっています。"cat.sim" というリソースをサポートしたユーザーエージェントであれば、最初の段落だけを表示するでしょう。しかし、フォールバックを表示するユーザーエージェントでは、紛らわしいことに、最初の段落が 2 つ目の段落と同じ段落にあるかのように表示してしまうでしょう。そして、最後の段落が、あたかも最初の段落の 2 つ目の文の手前にあるかのように表示されてしまうでしょう。
明示的な p 要素を使えば、この混乱を避けることができます。