HTML4.01ではp要素の終了タグ「</p>
」は省略することができるようになっている。数ある省略可能なタグの中で、最も気を付けなければならないのがこの「</p>
」。
まずスキーマを見てみる。p要素の内容モデルを確認するのに必要なのは次の箇所:
<!ELEMENT BODY O O (%block;|SCRIPT)+ +(INS|DEL) -- document body --><!ELEMENT P - O (%inline;)* -- paragraph --><!ENTITY % inline "#PCDATA | %fontstyle; | %phrase; | %special; | %formctrl;"><!ENTITY % fontstyle "TT | I | B | BIG | SMALL"> <!ENTITY % phrase "EM | STRONG | DFN | CODE | SAMP | KBD | VAR | CITE | ABBR | ACRONYM" > <!ENTITY % special "A | IMG | OBJECT | BR | SCRIPT | MAP | Q | SUB | SUP | SPAN | BDO"> <!ENTITY % formctrl "INPUT | SELECT | TEXTAREA | LABEL | BUTTON">
つまり、終了タグを省略することができ、ins, del, %inline;以外を内容に持つことができないというわけだ。しかし実装は異なる。
この仕様を正しく実装するなら、次のような処理が必要だ:
p要素の内容としてtable要素の出現が許される場合がある。場合があるというか、ほとんどの場合許されるといっていい。IEだろうがFirefoxだろうがOperaだろうがsafariだろうが、p要素の内容にtableが許される。これは恐らく、レガシーな記述に対応するために後方互換として意図的にやっているのだろう。
とかいいつつ、実はこの後方互換処理を行わせない方法もある。HTML4.01 Strictを宣言する。Gecko、Webkit、Operaで有効だが、MSHTMLに関してはこの限りではない。DOCTYPEスイッチで後方互換処理を無効にできないばかりか、table要素以外にも、form要素をp要素の内容に持てるようだ。
ちょっとまてと。もう一度「2.」を読み返してみる。平たく言えばこういうことだ。「親要素が終了したら、終了していない子要素も終了する」。これってエラー補正処理を考える上で当たり前の振る舞いじゃないか? だが、その当たり前の処理を難しくしているらしいのが「ins及びdel要素」だ。次の例を見てみよう:
<ins datetime=".."><p>挿入された文章..</ins> <p>古い文章..
MSHTML、Webkit、Operaは、p要素内において開始タグの出現なしに出現したins/del要素の終了タグ「</ins>
」を無視する。これは後方互換性とか何とかではなく、単なるバグであろう。恐らくp要素の内容として許される要素について、その開始タグの出現なしに終了タグが出現した場合、それをエラーとみなして無視しているのだと思われる。お粗末。
さて。これらは「p要素」の終了タグの話に過ぎないという点に注意。これだけ色々面倒があることを知っていたら、省略をフル活用したHTML4.01を採用することは、ひょっとしたらなかったかもしれない。だがこれまでに色々調べたり経験したりして「知って」しまったのだからもう後戻りするコストを払う意味はないし、個人的には利点の方がはるかに多い。あくまでも「個人的には」。
HTMLでタグを省略するのは、普通の人はやめておいた方がいいよ。「普通の人」が読んでいるとは思えないけれども。まーとにかく色々あるし、もともと公開書庫のコンテンツとしてHTML4.01の実践的な部分は書こうと思っていたので、これからも少しずつ省略についての考察等々は公開していく予定。
テストページも用意したけど、要らないよな。公開書庫に移す時には付録として公開すると思うけど。