第7章 壊れた HTML をどう扱うべきか
表示できた HTML は、正しい HTML でしょうか。逆に、ソースにない要素が DOM にあれば、入力が壊れていたのでしょうか。どちらも、それだけでは決まりません。
7.1 三つの問いを分ける
第5章の tbody タグ省略、第6章の p 終了タグ省略は、条件を満たせば正しい書き方です。タグと DOM の要素が一対一で見えないことは、エラーの証拠にはなりません。
HTML を調べるときは、次の三つを分けます。
| 問い | 調べるもの |
|---|---|
| 著者が書いてよい内容か | 要素のコンテンツモデル、属性の値、タグ省略の条件 |
| 読み取り中にパースエラーになるか | HTML パーサーの規則 |
| 実際にどんな木になったか | DOM。スクリプトによる変更も含む |
パースエラーは不適合な入力の一種ですが、すべての不適合がパースエラーになるわけではありません。パーサーは、著者向けの規則をすべて検査して正しい構造へ直す道具ではないのです。
7.2 同じ条件で三つの断片を比べる
第4章の確認用文書の body を、次の断片で一つずつ置き換えてください。Nu Html Checker には断片だけでなく、DOCTYPE や title を含む文書全体を渡します。
まず、li の終了タグを省略した例です。
<ul><li>項目 A<div>補足</div></ul>
li は div を内容にできます。また、この位置では li の終了タグを省略できます。したがって、この入れ子と省略は適合します。DOM でも div は li の子です。
次は、余った終了タグのある例です。
<p>前置き<div>本文</div></p>
これは第6章で見たパースエラーです。DOM には末尾に空の p ができます。入力の問題を指摘する validator と、回復結果を表示する DevTools の両方で原因を確認できます。
最後に、ul の直下へ div を置きます。
<ul><div>補足</div></ul>
ul の内容として許されるのは li と、script や template などのスクリプトを支援する要素です。div は許されません。しかしこの断片のパースでは、div は ul の子として残ります。ブラウザが li を作って包み直すわけではありません。
| 本文断片 | 適合性の検査で確認する点 | DOM の要素関係 |
|---|---|---|
| li の終了タグ省略 | この省略と入れ子に問題はない | ul → li → div |
余った </p> | 対応する開いた p がない | p、div、空の p |
| ul 直下の div | ul のコンテンツモデルに違反 | ul → div のまま |
この表はエラーメッセージの逐語的な再現ではありません。表示文言や警告は検査ツールの版によって変わります。注目するのは、どの規則への指摘なのかです。
7.3 回復は閲覧を続けるための規則
HTML には、入力に問題があってもパースを続ける規則があります。余った終了タグをどう扱うか、表の不適切な位置にあるテキストをどこへ置くかまで、実装者向けに定められています。ブラウザが著者の意図を推測して、その場で最善の木を選ぶわけではありません。
この性質は、作者が更新を止めた文書も読み続ける Web で役立ちます。ただし、閲覧を続けられることは、文書の意味や操作性が正しい保証ではありません。ul 直下の div のように、不適合な関係がそのまま DOM に残ることもあります。
XML では整形式の違反が致命的なエラーになりますが、HTML はそれとは違う処理規則を持ちます。HTML で許される省略を、XML の閉じ忘れと同じ基準で判定してはいけません。配信形式による違いは第14章で扱います。
7.4 validator と DevTools を組み合わせる
実務では、まず生成された文書全体を validator へ渡し、著者向け規則への違反を確認します。次に DevTools で DOM を見て、意図した親子関係かを確かめます。表示がずれているなら、その DOM に対する CSS の指定も追います。
検査で問題が出なかったとしても、文章の意味、キーボード操作、代替テキストの適切さまでは保証されません。逆に、画面が期待どおりでも、余った終了タグを放置してよい根拠にはなりません。
「入力として適合するか」と「ブラウザが何を作ったか」を別々に調べる。この手順が、HTML の寛容さに頼りきらずに開発するための足場になります。