HTML5の技術的考察
内容
要素のカテゴリーとコンテンツ・モデル
HTML5では、各要素は次のようなカテゴリーに分類されています。
- メタデータ・コンテンツ(Metadata content)
- フロー・コンテンツ(Flow content)
- セクション・コンテンツ(Sectioning content)
- 見出しコンテンツ(Heading content)
- フレーズ・コンテンツ(Phrasing content)
- 組み込みコンテンツ(Embedded content)
- インタラクティブ・コンテンツ(Interactive content)
- 知覚可能なコンテンツ(Palpable content)
- スクリプトサポート要素(Script-supporting elements)
「各要素は、類似した特徴によってグループ化された、ゼロもしくはそれ以上のカテゴリーに属します」、というのもHTML5仕様書からの受け売りですが、上述のカテゴリーに全く属さない要素もあれば、2つ以上のカテゴリーに所属する要素もあるということです。
どこか、いい加減な感じもしますが、それはそれとして、これらのカテゴリーの関係性は、以下の相関図で表されています。
コンテンツのカテゴリーと所属要素
各コンテンツの定義と、所属する要素は、次のとおりです。
メタデータ・コンテンツ
Metadata content is content that sets up the presentation or behavior of the rest of the content, or that sets up the relationship of the document with other documents, or that conveys other "out of band" information.
訳)メタデータ・コンテンツは、コンテンツのその他の表現あるいは挙動を設定する、コンテンツです。もしくは、他のドキュメントとの関係を設定します。あるいは、その他の「帯域外」情報を伝達します。
セマンティックスが主にメタデータと関連した(たとえばRDF)、他の名前空間に由来する要素も、やはりメタデータ・コンテンツです。
というわけで、基本的には、従来head要素内で記述されていた、文書の付属情報や、外部ファイルとの関連性を定義する要素が、主要なメタデータ・コンテンツということになります。ただし、script要素やstyle要素もこのカテゴリーに含まれるので、body要素内に配置される要素も存在します。
メタデータ・コンテンツの要素
フロー・コンテンツ
Most elements that are used in the body of documents and applications are categorized as flow content.
訳)ドキュメントとアプリケーションの本体(body)で使われるたいていの要素が、フロー・コンテンツに分類されます。
という大雑把な定義になっていますが、従来のブロックレベル(段落)要素やインライン(文字列)要素をすべてひっくるめて、body要素内に配置される要素は、このカテゴリーに属します。
フロー・コンテンツの要素
- a
- abbr
- address
- area(map要素の子要素である場合)
- article
- aside
- audio
- b
- bdi
- bdo
- blockquote
- br
- button
- canvas
- cite
- code
- data
- datalist
- del
- dfn
- div
- dl
- em
- embed
- fieldset
- figure
- footer
- form
- h1
- h2
- h3
- h4
- h5
- h6
- header
- hr
- i
- iframe
- img
- input
- ins
- kbd
- keygen
- label
- main
- map
- mark
- math
- meter
- nav
- noscript
- object
- ol
- output
- p
- pre
- progress
- q
- ruby
- s
- samp
- script
- section
- select
- small
- span
- strong
- style (scoped属性が付いている場合)
- sub
- sup
- svg
- table
- template
- textarea
- time
- u
- ul
- var
- video
- wbr
- テキスト
セクション・コンテンツ
Sectioning content is content that defines the scope of headings and footers.
Each sectioning content element potentially has a heading and an outline. See the section on headings and sections for further details.
訳)セクション・コンテンツは、見出しとフッターの範囲を定義するコンテンツです。
それぞれのセクション・コンテンツ要素が、潜在的に見出しとアウトラインを持っています。
セクションは、HTML5で追加された階層的な文書構造(アウトライン)を定義する概念です。そして、このセクションを生成する新しい要素が、このカテゴリーに属します。セクションについては後述しますが、要は章・節・項といったような階層構造で、段落をグループ化するとともに、この階層(アウトライン)としての意味付けを行うものです。
セクション・コンテンツの要素
セクショニング・ルート
Certain elements are said to be sectioning roots, including blockquote and td elements. These elements can have their own outlines, but the sections and headings inside these elements do not contribute to the outlines of their ancestors.
訳)blockquoteとtd要素を含め、ある特定の要素が、セクショニング・ルートとされます。これらの要素は、それ自身のアウトラインを持つことができます。しかし、これらの要素の中のセクションと見出しは、自身の親要素にはアウトラインを提供しません。
新設のfigure要素を除くと、旧来の要素でセクションの起点となる要素が、セクショニング・ルートです。セクション・コンテンツとの主要な違いは、セクショニング・ルートで生成されるセクションは、アウトラインには現れません。たとえば、段落単位の引用であるblockquote要素が、本文の間に挿入されたとしても、その部分が独立した章や節として現れたりはしない、ということです。
セクショニング・ルートの要素
※ セクショニング・ルートは、カテゴリー相関図内には表示されていません。
見出しコンテンツ
Heading content defines the header of a section (whether explicitly marked up using sectioning content elements, or implied by the heading content itself).
訳)(セクション・コンテンツ要素を使って明示的にマークアップされるか、あるいは見出しコンテンツ自身によって暗示されるかに係わらず)見出しコンテンツが、ひとつのセクションの見出しを定義します。
つまり、見出しコンテンツは、セクションに付けられるタイトル、もしくはラベルのような役割を演じるということです。ただし、見出しコンテンツによって、「暗黙のセクション」というものも形成されるので、それについては後述します。
見出しコンテンツの要素
フレーズ・コンテンツ
Phrasing content is the text of the document, as well as elements that mark up that text at the intra-paragraph level. Runs of phrasing content form paragraphs.
Note: Most elements that are categorized as phrasing content can only contain elements that are themselves categorized as phrasing content, not any flow content.
Text, in the context of content models, means either nothing, or Text nodes. Text is sometimes used as a content model on its own, but is also phrasing content, and can be inter-element whitespace (if the Text nodes are empty or contain just space characters).
訳)フレーズ・コンテンツは、ドキュメントのテキストであり、同様に段落内のレベルでそのテキストをマークアップする要素です。フレーズ・コンテンツの連続が、段落を形成します。
注記: フレーズ・コンテンツの範疇に入るほとんどの要素が、いかなるフロー・コンテンツでもない、それ自身がフレーズ・コンテンツという範疇に入る要素だけを、含むことがでます。
コンテンツ・モデルという文脈において、テキストは、何も意味しないか、もしくはテキスト・ノードとなります。テキストは時々、それ自身が持つコンテンツ・モデルとして使用されますが、それはフレーズ・コンテンツでもあり、(もしテキスト・ノードが空であるか、あるいはスペース文字を含むだけなら)要素間の空白スペースでもあり得ます。
フレーズ・コンテンツは、従来のインライン要素に相当します。まずそれは、段落の中にある文字列(テキスト)そのものであり、もしくはそうした文字列を段落の中で囲む要素なので、この要素の中には、やはり文字列やフレーズ・コンテンツ要素しか入らない、と執拗に言っているわけです。
さらに、半角スペースだけが配置されている場合、従来どおりそれは文字として扱われないことも、忘れられていません。
フレーズ・コンテンツの要素
組み込みコンテンツ
Embedded content is content that imports another resource into the document, or content from another vocabulary that is inserted into the document.
Elements that are from namespaces other than the HTML namespace and that convey content but not metadata, are embedded content for the purposes of the content models defined in this specification. (For example, MathML, or SVG.)
Some embedded content elements can have fallback content: content that is to be used when the external resource cannot be used (e.g. because it is of an unsupported format). The element definitions state what the fallback is, if any.
訳)組み込みコンテンツは、ドキュメントに他のリソースを読み込む、あるいは他の語彙のコンテンツを挿入する、コンテンツです。
HTML以外の名前空間に由来し、なおかつメタデータではない内容を伝達する要素は、この仕様で定義されたコンテンツ・モデルの目的において、組み込みコンテンツです(たとえばMathMLもしくはSVG)。
若干の組み込みコンテンツ要素が、フォールバック・コンテンツ「フォールバック」とは、提供されるべき機能に障害が生じた際、自動的に代替候補に切り替えて、(機能低下を招いたとしても)その機能の提供を継続することです。を持つことができます。たとえば、サポートされていないフォーマットを持っているため、その外部リソースが使用不可能なときに、代わりに使われるべきコンテンツです。
要素の定義は、もし次候補(フォールバック)があれば、それが何かを明示します。
img要素が画像ファイルを読み込んだり、iframe要素が他のWebページを読み込んだり、svg要素がその中に他言語で記述したベクトル図形を表示できたりするように、このカテゴリーの要素は、当該HTMLファイル内にHTMLもしくは他の形式の、外部ファイルやデータを表示させます。
そうしたファイルやデータにユーザー・エージェントが対応できない場合に備え、代わりとなる候補を入れておくことも、明記されています。
組み込みコンテンツの要素
インタラクティブ・コンテンツ
Interactive content is content that is specifically intended for user interaction.
訳)インタラクティブ・コンテンツは、特にユーザーとのやり取り(ユーザー・インタラクション)のために意図されたコンテンツです。
クリックするa要素、文字を入力したりクリックできるチェックボックスになったりするinput要素のように、静的にレンダリングされた要素ではなく、ユーザーの操作に反応する機構を備えた要素が、インタラクティブ・コンテンツに属します。
このため、同じ要素であっても、反応する機構を出さない場合は、このカテゴリーから除外されます。たとえば、動画を表示する新設のvideo要素は、controls属性を付けることで、再生や停止がクリック操作で可能になります。属性を付けないでこの制御機能を無効にすると、最早インタラクティブ・コンテンツではなくなる、という次第です。
img要素もこのカテゴリーに顔を出していますが、通常この要素はただの画像であり、インタラクティブ・コンテンツではありません。しかし、usemap属性を付けると、すなわち画像内にクリックできるリンク部分を持つイメージマップへ変身すると、インタラクティブ・コンテンツに仲間入りします。
インタラクティブ・コンテンツの要素
知覚可能なコンテンツ
As a general rule, elements whose content model allows any flow content or phrasing content should have at least one node in its contents that is palpable content and that does not have the hidden attribute specified.
This requirement is not a hard requirement, however, as there are many cases where an element can be empty legitimately, for example when it is used as a placeholder which will later be filled in by a script, or when the element is part of a template and would on most pages be filled in but on some pages is not relevant.
訳)原則として、フロー・コンテンツもしくはフレーズ・コンテンツとして認められた要素は、その内容として知覚可能なコンテンツであり隠し属性の無いものを、少なくとも1つのノードで持つべきです。
しかし、この必要条件は、たとえば、後からスクリプトによって充填されるプレースホルダーとして使われる場合や、要素がテンプレートの一部であり、ほとんどのページが充填されるものの一部は該当しない場合など、要素が合理的に空であり得る多くのケースが存在するため、厳格なものではありません。
以上の定義は、当初はフロー・コンテンツやフレーズ・コンテンツに関する説明として、仕様書に書かれていました。それが、最終的には1つのカテゴリーとして独立し、フローおよびフレーズ・コンテンツを包含するものとなったわけです。
このカテゴリーの意味するところは、「当該要素は、自身に知覚可能な内容を持つことによって、ユーザー・エージェントにその存在を知覚されるべきである」ということです。ただし、内容を空にしておくこともあるので、「それは絶対条件ではない」という但し書きが付きます。
なお、当該要素の持つべき“内容”は、要素内容とは限りません。なぜかというに、このカテゴリーにはimgやinputのような空要素も含まれているからです。これらの要素では、src属性やalt属性、あるいはtype属性などが、持つべき内容と現れ方を定義します。そして、要素内容と同様、属性もノードを形成するので、仕様では「少なくともひとつのノードで持つべき」(should have at least one node)と表現されているわけです。
知覚可能なコンテンツの要素
- a
- abbr
- address
- article
- aside
- audio (controls属性が付いている場合)
- b
- bdi
- bdo
- blockquote
- button
- canvas
- cite
- code
- data
- div
- dl (子要素が少なくとも1つの項目グループを含む場合)
- em
- embed
- fieldset
- figure
- footer
- form
- h1~h6
- header
- i
- iframe
- img
- input (type属性の状態がhiddenではない場合)
- ins
- kbd
- keygen
- label
- main
- map
- mark
- math
- meter
- nav
- object
- ol (子要素が少なくとも1つのli要素を含む場合)
- output
- p
- pre
- progress
- q
- ruby
- s
- samp
- section
- select
- small
- span
- strong
- sub
- sup
- svg
- table
- textarea
- time
- u
- ul (子要素が少なくとも1つのli要素を含む場合)
- var
- video
- テキスト(要素間の空白ではない場合)
スクリプトサポート要素
Script-supporting elements are those that do not represent anything themselves (i.e. they are not rendered), but are used to support scripts, e.g. to provide functionality for the user.
訳)スクリプトサポート要素は、それ自体が何かを表示するものではありませんが(すなわちレンダリングされません)、スクリプトをサポートして、たとえばユーザーに何らかの機能を提供するために使われます。
script要素は、従来どおり、その中にスクリプトを記述したり、外部スクリプトの読み込みに使ったりする、スクリプト操作のための基本機能を提供します。
新設のtemplate要素は、スクリプトによってデータを挿入し表示するものの雛形(テンプレート)を記述しておくものです。たとえばtemplate要素内に表を記述しておき、そのセルにスクリプトで内容を挿入して出力します。スクリプトが実行されなければ、template要素とその内容は表示されません。なお、IE11はtemplate要素に非対応です。
いずれにしても、スクリプトのために利用されるものがスクリプトサポート要素であり、元々画面には表示されないか、スクリプトで操作しなければ表示されないものだということです。
スクリプトサポート要素
フォーム関連
フォームに関連した要素は、その機能に応じてさらに細かく分類されます。
フォーム連携要素(form-associated elements)
form要素と関連付けられる要素です。ようは、特定のform要素の、下僕として働く要素です。
なおHTML5では、これらの要素は、必ずしもform要素の子要素となる必要はありません。form属性を使って特定のform要素と関連付け、連携させることができます。
フォーム連携要素は、さらに以下のサブカテゴリーで分類されています。
リスト化要素(Listed elements)
form.elements API と fieldset.elements API でリストされる要素を意味します。
送信可能要素(Submittable elements)
form要素が送信されるとき、フォームデータセットの構築に使うことができる要素を意味します。
リセット可能要素(Resettable elements)
form要素がリセットされるとき、その影響を受ける要素を意味します。
再連携可能要素(Reassociateable elements)
フォームコンテンツ属性を持ち、なおかつフォーム IDL 属性と適合した、制作者による明示的なフォーム所有者の指定を認める要素を意味します。
ラベル付け可能要素(Labelable elements)
すべてのフォーム連携要素ではありませんが、いくつかの要素はラベル付け可能要素に位置付けられます。それは、label要素と関連付けることが可能な要素を意味します。
カテゴリーなし
ところで、table関連の要素は、table要素がフロー・コンテンツ、td要素がセクショニング・ルートとして分類されているものの、その他については特にカテゴリー分類がありません。可哀そうですね。
該当カテゴリーなし(table関連)
他にも、いくつかの要素が「該当カテゴリー無し(Categories:None)」に“分類”されています。
該当カテゴリーなし(form関連)
該当カテゴリーなし(その他)
- 各コンテンツの定義内容に関しては、W3C勧告を直訳したものを掲載しています。
- 緑字の要素は、HTML5で新設された要素です。embed、wbr要素のように、かつては特定ブラウザーの独自要素であったものも、新設要素としてあります。
- ルビの構成を定義するruby、rt、rp要素は、XHTML 1.1で追加されたものですが、HTML 4と5の違いを比較した仕様書「HTML5 Differences from HTML4」においては、HTML5の新設要素として紹介されています。
長々とカテゴリーを紹介してしまいましたが、正しいHTML5を書くためには、各要素が、上記のどのカテゴリーに分類されているかとともに、含めることのできる要素内容を把握しなければなりません――と、唐突に言われても、この分類をすぐに理解するのは、なかなか難しいでしょう。
追加された属性
カテゴリーとは直接関係ありませんが、要素を書き出したついでに、HTML5で追加された属性も、ここで紹介しておきます。
input要素の追加タイプ
input要素には以下のtype属性値が追加され、それらに応じた表示と機能を提供します。
他の要素でも使えるようになった従来型属性
以下の要素では、以下の(従来から存在していた)属性が使えるようになりました。
属性名 | 対象要素 |
---|---|
hreflang, type, rel | area |
target | base |
charset | meta |
disabled, name | fieldset |
width, height | input(type="image") |
新設属性
全く新たに追加された属性は、以下のとおりです。
属性名 | 対象要素 |
---|---|
autofocus | input, select, textarea, button |
placeholder | label |
form | input, output, select, textarea, button, label, object, fieldset |
reqired | input, select, textarea |
autocomplete | input |
min | input |
max | input |
multiple | input |
pattern | input |
step | input |
list | datalist |
dirname | input, textarea |
maxlength | textarea |
minlength | textarea, form |
wrap | textarea |
maxlength | textarea |
novalidate | form |
formaction | input, button |
formenctype | input, button |
formmethod | input, button |
formnovalidate | input, button |
formtarget | input, button |
scoped | style |
async | script |
manifest | html |
sizes | link |
reversed | ol |
sandbox | iframe |
seamless | iframe |
srcdoc | iframe |
typemustmatch | object |
srcsetimg要素のsrcset属性(Chrome / Operaが先行して実装)は、当初、「The srcset attribute」として個別に提案されていましたが、2014年8月以降はHTML5.1に統合され、現在は同編集者草案(2014年10月27日)で提案されています。 | img |
従来型グローバル属性
以下のグローバル属性は、すべての要素で使えるようになりました。
新規グローバル属性
以下のグローバル属性が新設されました。
- contenteditable
- data-*
- hidden
- role
- aria-*
- spellcheck
- translate
廃止された要素
なお、HTML5では、以下の要素が廃止されています。
スタイル関連
- basefont
- big
- center
- font
- strike
- tt
テキスト関連
- acronym
フォーム関連
- isindex
リスト関連
- dir
組み込み関連
- applet
フレームページ関連
- frame
- frameset
- noframes
スクリプト関連
- noscript (XHTMLのみ)
スタイル関連の要素の使用は、CSSによる指定へ完全に置き換えることになります。フレームページiframe要素とtarget属性は、フレームページが滅んでも何故か生き残っています。も、アクセシビリティの問題を理由に全廃されました。
その他の要素は、旧式の技術である、使用頻度が低い、用法が不明瞭、といった理由で廃止されています。
廃止された属性
以下に、廃止された属性も列記しておきます。
属性名 | 対象要素 |
---|---|
rev, charset | link, a |
shape, coords | a |
longdesc | img, iframe |
target | link |
nohref | area |
profile | head |
version | html |
name | img(idに置き換え) |
scheme | meta |
archive | object |
classid | object |
codebase | object |
codetype | object |
declare | object |
standby | object |
valuetype | param |
type | param |
axis | td, th |
abbr | td |
scope | td |
summary | table |
accept | form |
usemap | input |
属性名 | 対象要素 |
---|---|
align | caption, iframe, img, input, object, legend, table, hr, div, h1~h6, p, col, colgroup, tbody, td, tfoot, th, thead, tr |
alink | body |
link | body |
vlink | body |
text | body |
background | body |
bgcolor | table, tr, td, th, body |
border | object |
cellpadding | table |
cellspacing | table |
char | col, colgroup, tbody, td, thoot, th, thead, tr |
charoff | col, colgroup, tbody, td, thoot, th, thead, tr |
clear | br |
compact | dl, menu, ol, ul |
frame | table |
frameborder | iframe |
height | td, th |
hspace | img, object |
vspace | img, object |
marginheight | iframe |
marginwidth | iframe |
noshade | hr |
nowrap | td, th |
rules | table |
scrolling | iframe |
size | hr |
type | li, ul |
valign | col, colgroup, tbody, td, thoot, th, thead, tr |
width | hr, table, td, th, col, colgroup, pre |
属性名 | 対象要素 |
---|---|
border | img(cssに置き換え) |
language | script(typeに置き換え) |
name | a(idに置き換え) |
HTML5で廃止された要素や属性は、仕様書の「11章 廃止された機能」(11 Obsolete features)に掲載されていますが、HTML 4.01からの変更点については、「HTM5のHTML4からの相違」(HTML5 Differences from HTML4)という仕様書にもまとめられています。ただしこの仕様書は、現状では作業草案(2014年9月18日)です。
以前のHTML5仕様から削除/除外された要素
このほか、当初、HTML5で新設されたものの、後の仕様で削除もしくは除外された要素がいくつかあります。
削除された要素
- hgroup
除外された要素
- command
- details
- dialog
- menu
- summary
details、dialog、menu要素は、HTML5からは除外されたもののHTML5.1で引き続き策定中です。details、dialog要素の子要素であるsummary要素も同様です。menu要素の子要素としてcommand要素が予定されていましたが、こちらはmenuitem要素に名を変えて、やはり5.1で策定中です。
コンテンツ・モデルの捉え方
ではカテゴリーに引き続いて、HTML5の新しい概念である「コンテンツ・モデル」について見ていきましょう。
従来の要素の定義
もちろん、こんなカテゴリー区分が無かった、従来のHTMLやXHTMLでも、要素の入れ子関係には「インライン要素はブロックレベル要素の中に入れなければならない」という大原則がありました。たとえば、a要素をbody要素の直接の子要素として書いてはいけません。
<body>
<a href="#">文字列</a>
</body>
また、これは「インライン要素にブロックレベル要素を入れてはならない」ということでもあります。
<a href="#"><p>文字列</p></a>
品行方正なa要素の書き方は、p要素のような何らかのブロックレベル要素の入れ子にすることです。
<body>
<p><a href="#">文字列</a></p>
</body>
まあ、インライン要素というのは、文中の単語や文字列といったものを表すので、それらは段落(ブロックレベル要素)の中に入れなさい、という単純至極な道理です。
しかし、ブロックレベル要素同士の話になると、少し面倒になります。たとえば見出しを表すh1要素はその中にもちろん文字が入れられます。文字が入るということは、インライン要素も入れられます。では、p要素を入れられるでしょうか? それは無理です。見出しは、それでひとつの段落として完結するようになっていて、他の見出しや本文の段落からは独立しています。ですから、こうしたブロックレベル要素同士の入れ子は作れません。
<body>
<h1>
<h2>
<p>文字列</p>
</h2>
</h1>
</body>
では、「ブロックレベル要素にブロックレベル要素を入れてはならない」と言い切れるのかというと、そうでもありません。たとえば、複数のブロックレベル要素を囲むことができるブロックレベル要素として、div要素があります。div要素の中には、body要素内に入れられるものであれば、何でも入れ子にできます。
<body>
<div>
<h1>見出し1</h1>
<div>
<h2>見出し2</h2>
<p>文字列</p>
</div>
</div>
</body>
また、リストを表すul要素やol要素の中で、リスト項目を表すli要素の中にも、ほとんどの要素を入れられます。一方で、li要素の中にli要素は入れられません。li要素は、ul要素の直接の子要素でなければなりません。同様に、ul要素の中にul要素を入れることもできません。ul要素やol要素の中に入れられるのは、li要素だけです。
<body>
<!-- 正しい書き方 -->
<ul>
<li>項目</li>
<li>
<h1>見出し1</h1>
</li>
<li>
<ul>
<li>項目</li>
</ul>
</li>
</ul>
<!-- 誤った書き方 -->
<ul>
<h1>見出し1</h1>
<li>項目</li>
<li>
<li>項目</li>
</li>
<ul>
<li>項目</li>
</ul>
</ul>
</body>
コンテンツ・モデルの把握
こうした様々な細則は、たぶん、HTMLの記述に慣れてくればおのずと理解できるものですが、HTML5では、こうした関係を論理的に明示したいという欲求に駆られたのかもしれません。フーコー風に言えば、博物学的に分類し系統を定め、関係性の網の目に捉えようというわけです。
その大まかな前提となる各カテゴリーの定義は、
- メタデータ・コンテンツはhead要素内に入れる画面に表示されない要素
- フロー・コンテンツはbody要素内に入れる画面に表示される要素
- フレーズ・コンテンツは段落の中に組み込まれる要素(従来のインライン要素)
ということになります。そして、
- セクション・コンテンツは自身に段落を組み込める要素
- 見出しコンテンツは見出しそのもの(これは簡単)
であり、再びフロー・コンテンツは、その他の段落的なものも含めた画面に表示される要素(これはもう曖昧)すべて、ということになります。
こうしたカテゴリーの定義に基づいて、自身を配置できる要素(場所)と、自身に含めることのできる要素内容が決定されます。たとえばp要素であれば、以下のように仕様で定義されています。
p要素の定義 | |
---|---|
カテゴリー | フロー・コンテンツ |
知覚可能なコンテンツ | |
使用できる文脈 | フロー・コンテンツであり得る場所 |
コンテンツ・モデル | フレーズ・コンテンツ |
このように、HTML5では、当該要素が所属するカテゴリーと、その子要素にできる要素が所属するカテゴリーを定義して、それらに基づき「ある要素の中にどの要素を入れられるのか」を捉えようとしています。これが、「コンテンツ・モデル」(Content model)と呼ばれるものです。まあ、端的に言ってしまえば、「中に入れられる要素」=コンテンツ・モデルということになります。
Categories: | Flow content |
---|---|
Palpable content | |
Contexts in which this element can be used: | Where flow content is expected |
Content model: | Phrasing content |
一方、当該要素を配置できる場所が、「使用できる文脈」(Contexts in which this element can be used)です。つまり、自身の親要素にできるものは何かを、そのカテゴリーで示します。
では、「フロー・コンテンツであり得る場所」(Where flow content is expected)とはどこでしょうか? その大元はbody要素ですが、コンテンツ・モデルにフロー・コンテンツが定義されている要素(たとえばdiv要素)の中は、「フロー・コンテンツであり得る場所」になります。
body要素の定義 | |
---|---|
カテゴリー | セクショニング・ルート |
使用できる文脈 | html要素の次 |
コンテンツ・モデル | フロー・コンテンツ |
div要素の定義 | |
カテゴリー | フロー・コンテンツ |
知覚可能なコンテンツ | |
使用できる文脈 | フロー・コンテンツであり得る場所 |
コンテンツ・モデル | フロー・コンテンツ |
このように、所属カテゴリーと使用できる文脈の定義に関連付けられて、コンテンツ・モデルが決定されるわけですが、これは先のコンテンツの相関図で一目瞭然――というものではなく、要素個別の定義を確認していかなければなりません。
たとえば、「相関図」を見ただけでは、見出しコンテンツやセクション・コンテンツの中に、フレーズ・コンテンツ=テキストを入れることができないのでは、と思ってしまいます。
もちろん、それは見当違いで、たとえば見出しコンテンツのh1要素は、フロー・コンテンツでもあるので、フレーズ・コンテンツを中に入れることができます。
では、フロー・コンテンツの中に見出しコンテンツを入れられるような図になっているので、h1要素の中にh1要素を入れてもよいのでしょうか? いえ、これは人として間違いです。その理由は、この図ではなく、h1(~h6)要素のコンテンツ・モデルを確認しなければならないからです。すなわち、この相関図は、要素の入れ子関係を表すものではないのです。
実際のところ、h1~h6要素の仕様は、次のように定義されています。
h1~6要素の定義 | |
---|---|
カテゴリー | フロー・コンテンツ |
見出しコンテンツ | |
知覚可能なコンテンツ | |
使用できる文脈 | フロー・コンテンツであり得る場所 |
コンテンツ・モデル | フレーズ・コンテンツ |
このコンテンツ・モデルに従って、h1要素には「フレーズ・コンテンツを入れることはできるが、それ以外は認められない」ということになります。
もうひとつの例を、フレーズ・コンテンツでもあるa要素で見ていきましょう。a要素の定義は、以下のようになっています。
a要素の定義 | |
---|---|
カテゴリー | フロー・コンテンツ |
フレーズ・コンテンツ | |
インタラクティブ・コンテンツ | |
知覚可能なコンテンツ | |
使用できる文脈 | フレーズ・コンテンツであり得る場所 |
コンテンツ・モデル | 透過(インタラクティブ・コンテンツを除く) |
ここに登場する、「透過」というコンテンツ・モデルですが、中に入れられる要素が「自分自身の親要素に入れられる要素」であるものを、“コンテンツ・モデルが「透過(transparent)」である”と、仕様では表現しています。
Some elements are described as transparent; they have "transparent" in the description of their content model. The content model of a transparent element is derived from the content model of its parent element:
(訳)若干の要素が透過であると記述されています; それらはコンテンツ・モデルの記述で「透過」となっています。透過的な要素のコンテンツ・モデルは、その親要素のコンテンツ・モデルから得られます:
これは、「当該要素には固有のコンテンツ・モデルは無く、親要素のモデルが透過的に浸透する」ということですが、CSS風の言い方をすれば、「親要素のモデルを継承CSSでの値の「継承」はinheritの訳ですが、この単語を使わずにtransparentとしているので、“継承”とは意味もしくは意図するところが異なるかもしれません。する」ことになります。
では、この仕様を、少し詳しく見ていきましょう。
まず、a要素は、フレーズだけでなく、フローおよびインタラクティブ・コンテンツでもあります。そして、「コンテンツ・モデル」の規定に従えば、a要素の中にp要素のような、旧来のブロックレベル要素を含めることができます(HTML5ではそれが可能になりました)。
<div>
<a href="#"><p>文字列</p></a>
</div>
a要素を置ける場所(使用できる文脈)は「フレーズ・コンテンツであり得る場所」(=インライン)ですから、たとえばdiv要素を親として、その中に配置できます。そして、div要素内にはp要素も配置できますから、この場合のa要素のコンテンツ・モデルである「自分自身の親要素に入れられる要素」に、p要素は当てはまります。故に、上記のコーディング例は正しい、ということになります。
ただし、p要素の中のa要素の中に、さらにp要素を入れるとそれは文法エラーです。
<p><a href="#"><p>文字列</p></a></p>
なぜなら、p要素の中に含めることのできるのはフレーズ・コンテンツだけなので、p要素の中にp要素は含められません。すなわち、上の例でのa要素の親要素はp要素なので、この場合のa要素の親要素に入れられる要素ではない、という理屈になるわけです。
なお、「インタラクティブ・コンテンツを除く」というコンテンツ・モデルの例外規定は、a要素でa要素を囲めない、a要素でinput要素を囲めない、といったことです。マウスやキーボード操作に反応する要素が二重になると、内側の要素が操作できなくなるという、これは至極当然の理由です。
従来のHTMLでも、使用する状況によってブロックレベルにもインラインにもなる、ins要素やdel要素が存在しました。これらも、HTML5では、コンテンツ・モデルが「透過」になっています。一方、従来どおりインラインでしか使用できないspan やstrongといった要素のコンテンツ・モデルは、「フレーズ・コンテンツ」です。
要素名 | 従来の分類 | HTML5でのコンテンツ・モデル |
---|---|---|
a | インライン | 透過 |
ins | インライン/ブロックレベル | 透過 |
del | インライン/ブロックレベル | 透過 |
span | インライン | フレーズ・コンテンツ |
strong | インライン | フレーズ・コンテンツ |
ブロックレベルとインライン両刀使いの要素を明確化するために、こうしたコンテンツ・モデルが必要になったのかもしれません。HTMLは人為的に作られた言語であるにも拘らず、もしくは人間が作ったが故に、その関係には多様性が存在し、それを厳密に捉えようとすればするほど、整然とした系統で明快な関係が説明されるのではなく、例外を跡付けるために複雑に絡み合った定義が提示されることとなります。
HTML5のコンテンツ・モデルという概念は、たぶん、理解できている人には明快なのでしょうが、それを突然提示された人にとっては、論理の迷宮のように映るでしょう。結局のところ、初めに大まかな理解として従来の「インライン要素はブロックレベル要素の中に入れなければならない」を把握した上で、各要素を使用する際に、それぞれの規定を確認していくしかないでしょう。