ようこそ、HTML Advent Calendar 2018へ!カレンダーのはじめにふさわしく、HTMLの冒頭に書く<!DOCTYPE>
について掘り下げてみます。
今ではだいぶシンプルになったけど
HTML5では<!DOCTYPE html>
とごくシンプルなものですが、昔はもっと長く、しかも何種類もありました。
- HTML 4.01 Strict…
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
- HTML 4.01 Transitional…
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- HTML 4.01 Frameset…
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
呪文のように長い上に、URLまで入っていて、そらで書けるものではありません。
どうしてこんなに長かったDOCTYPE宣言が、HTML5ではここまでシンプルになったのでしょうか。
HTMLの先祖…SGML
では、歴史の針をぐいっと戻してみます。HTMLより前に、「テキスト+タグ」で意味構造を表現するというプロジェクトとして、SGMLが始まりました。そして、HTMLはもともとこのSGMLの仕様に則って作られたものだったのです。
SGML自体は利用者がタグを定義できるのですが、その定義にはDTDという別な言語が使われていました。そして、SGMLとDTDを結びつけるためのものがDOCTYPE宣言でした。
<!DOCTYPE ルート要素 PUBLIC "識別子" "URL(省略可)" [
<!-- サブセット(省略可) -->
]>
<!DOCTYPE ルート要素 SYSTEM "URL" [
<!-- サブセット(省略可) -->
]>
PUBLIC
として既知の"識別子"
でDTDを指定するか、SYSTEM
として"URL"
を指定するかで、文書のDTDを指定していました。そして、文書ごとのサブセット
も指定可能でした。SGMLを元にしたHTMLにも、この形を受け継いだDOCTYPE宣言がなされることとなりました(上に挙げたHTML 4.01用の3つも、上の形に従っていることがわかると思います。DTDのURLも、HTTPSにリダイレクトされますがアクセスは可能です)。
現実問題
本気でSGMLを処理するには仕様が巨大すぎるために、SGMLが普及したのは狭い範囲にとどまり、「自分でタグを定義できるマークアップ言語」の普及はより簡略化したXMLの展開を待つこととなりました。
そして、HTMLのほうも、HTML 3.2以前の頃はInternet Explorer対Netscape Navigatorのブラウザ戦争が華やかなりし頃で、ブラウザごとに勝手に拡張がなされていました。これではまずいと、HTML 4.0ではブラウザの独自拡張もある程度は採用しつつ標準化を進めていきました。
ただ、いきなり標準に沿った表示に切り替えてしまうと、既存のページが全て崩れてしまうという大災害となるので、「新しいDOCTYPEを書いているものは標準に従って表示し、そうでないものは従来の表示(Quirksモード)にする」という処理が組み込まれました。これがDOCTYPEスイッチです。
HTML5においては
HTML5はSGMLから独立した形となっているので、理論的にはDOCTYPEは不要となるはずです。ただ、上のようにDOCTYPEスイッチがある以上、DOCTYPEなしではQuirksモードとなってしまいます。そこで、「既存のIE6などもきちんと標準モードに切り替わる」ことを考慮して選ばれた形が、<!DOCTYPE html>
です。今から新たなHTMLを作る場合に他のDOCTYPEを使う必要はないでしょう。
結論
- 今は
<!DOCTYPE html>
だけでいい。 - 一度互換性で入れた機能は、あとから別な意味で制約になることもある。
外部リンク
- FirefoxでのDOCTYPEスイッチ
- リストを見ていると、呆れるほど多くのDTD識別子が並んでいました。