🍈

DOMDOMタイムス#10: DOM, quirks, <!DOCTYPE html>

2023/08/28に公開

今日もDOMDOMタイムスやっていきましょう👶
今回は例の<!DOCTYPE html>という謎宣言とDOMの関係性です。

<!DOCTYPE html>を書かないとどうなる?

HTMLファイルの最初に<!DOCTYPE html>が書いていないページがたま〜にあります。

自分は日頃DOMに関するコードを書いていますが、色々なウェブページのソースを見ています👶
その中にはたまーにあるのです、<!DOCTYPE html>を書いていないページが

そうなると、実はブラウザの挙動が変わってきてしまいます。
何を言っているんだ?という感じかもしれませんが、本当です🌞MDNさんから拝借。

For HTML documents, browsers use a DOCTYPE in the beginning of the document to decide whether to handle it in quirks mode or standards mode.
中略
The DOCTYPE shown in the example, <!DOCTYPE html>, is the simplest possible, and the one recommended by current HTML standards. Earlier versions of the HTML standard recommended other variants, but all existing browsers today will use full standards mode for this DOCTYPE, even the dated Internet Explorer 6. There are no valid reasons to use a more complicated DOCTYPE. If you do use another DOCTYPE, you may risk choosing one which triggers almost standards mode or quirks mode.
中略
The only purpose of <!DOCTYPE html> is to activate no-quirks mode.
https://developer.mozilla.org/en-US/docs/Web/HTML/Quirks_Mode_and_Standards_Mode

要するに<!DOCTYPE html>という記載がないHTMLに対して、ブラウザは「almost standards mode」か「quirks mode」で動いてしまうワケです。
私たちの知っている挙動をするのがstandards mode。そしてquirks modeという挙動が異なるモードがあり、それらの真ん中をいくのがalmost standards mode。

standards mode以外のmodeはむかーしむかしのページとの互換性を保つための仕組みであるようで、まあこのあたりは詳しい解説がいろいろあるので読んでみてください(一応MDNを貼っておきますね)。

今回の記事ではquirks modeしか扱わないよ

今回の記事ではquirks modeしか扱いません
almost standards modeに興味がある人ごめんね……😭(そんな人いる?もしいたらalmost standards modeに関する記事を書いてほしいです、読みたいです)

というのも、そもそも<!DOCTYPE html>以外のDOCTYPEをわざわざ指定しているサイトは幸い(?)私は見たことがなく、<!DOCTYPE html>が書かれているか、何も書かれていないかの二択だと捉えて差し支えないと思っています。
そのうえで、下記サイトによればほとんどのブラウザ(少なくともFirefox, Safari, Chrome, Opera and Edge)はDOCTYPEの記載がない場合にquirks modeで動くようなのです。

というわけで今回の記事ではquirks modeしか扱いません!

quirksだとどうなるの?

さっそく見ていきましょう。じつはquirks modeに関する挙動をwhatwgがまとめてくれています。
最終更新は2022年11月であるようですが、内容に関する実質的な変更は2022年2月で、それもそこまで大きな変更ではありません。さすがにそんなに頻繁に変更があるものではないようです。

さて目次を見てみると、CSSというセクションが大部分を占めており、影響は描画に関するものがメインっぽいですね。

中身はざっとしか見ていませんが、ブロック要素の高さが0として扱われたり、

3.4. The blocks ignore line-height quirk
In quirks mode and limited-quirks mode, for a block container element whose content is composed of inline-level elements, the element’s line-height must be ignored for the purpose of calculating the minimal height of line boxes within the element.
https://quirks.spec.whatwg.org/#the-blocks-ignore-line-height-quirk

text-decorationがテーブル要素の中には適用されなかったり。

3.11. The text decoration doesn’t propagate into tables quirk
In quirks mode, text decoration must not propagate into table elements.
https://quirks.spec.whatwg.org/#the-text-decoration-doesnt-propagate-into-tables-quirk

これで終わり……じゃない!?

「これで終わりやん」と思いましたが、編集部(わたしひとり)では一応ですね、DOM Living Standardをquirksで検索してみました。
そしたら何箇所かありました!!ただし内容は煎じ詰めると次の2つになりそうです。

1.document.compatMode

document.compatModeは次のように説明されています。

Returns the string "BackCompat" if document’s mode is "quirks"; otherwise "CSS1Compat".
https://dom.spec.whatwg.org/#ref-for-dom-document-compatmode①

これは少し便利かもしれませんね👶

2.getElementsByClassName

こっちのがやばいですね。なんとgetElementsByClassNameの挙動が変わってしまいます。
下記でいうThe list of elements with class names classNamesとはgetElementsByClassNameの返り値のことを指しており、その計算ステップの3番目に記述があります。

The list of elements with class names classNames for a node root is the HTMLCollection returned by the following algorithm:

  1. Let classes be the result of running the ordered set parser on classNames.
  2. If classes is the empty set, return an empty HTMLCollection.
  3. Return an HTMLCollection rooted at root, whose filter matches descendant elements that have all their classes in classes.
    The comparisons for the classes must be done in an ASCII case-insensitive manner if root’s node document’s mode is "quirks"; otherwise in an identical to manner.
    https://dom.spec.whatwg.org/#concept-getelementsbyclassname

要するにgetElementsByClassNameの引数として与えられたclass名を扱う際に、大文字小文字区別しなくなるようなのです。地味に効きそうですね笑

なお、コードをちゃんと読まずに推測だけになりますが、これは内部的なCSS適用の際にも当てはまりそうだなあと下記のbug報告を見て思いました👶

めちゃちなみにですが、クラス名やid名でcase insensitiveであるというのはIE5.xとIE6互換モードでもそうだったらしいですよ。
下記はそれを利用したテクニックだそうで、いやはや本当にすごいです。

まあでも他にもありそうだよね

ただまあいうて上に書いたこと以外にもなんかナゾの違いとかありそうですよね。
クラス名の件だってquirks modeの仕様の方には書いていませんでしたし😭

いちおう下記リンク先でquirks modeに関連していそうなchromeバグをモジュールごとに表示させてみたので、これを見てみてもいいかもしれません。

って、そんなん見る必要ある人いませんよね笑

ではでは、今日はここまでであります。
<!DOCTYPE html>がないサイトで何かがバグったら、これまで書いたことに気をつけつつデバッグしてみるといいかもしれませんねえ🌞

GitHubで編集を提案

Discussion