同じような HTML コードでもパース結果が異なることがある2021年12月05日 23時11分

この記事は HTML アドベントカレンダーの 5 日目の分です。


HTML 標準では、誤りのある HTML コードを Web ブラウザがどう解釈すべきかも定められています。例えば、span 要素の終了タグを書き忘れた場合、

const c = document.createElement('div');
c.innerHTML = '<p><span>foo</p><p>bar</p>';
console.log(c.innerHTML);
// => "<p><span>foo</span></p><p>bar</p>"

最初の段落が終了する地点で span 要素も終了すると解釈されました。ここで span 要素を b 要素に変えてみるとどうなるでしょう。

const c = document.createElement('div');
c.innerHTML = '<p><b>foo</p><p>bar</p>';
console.log(c.innerHTML);
// => "<p><b>foo</b></p><p><b>bar</b></p>"

最初の段落が終了する地点で b 要素がいったん終了するのは span 要素のときと同じですが、今度は 2 番目の段落の内容にも b 要素が登場します。span 要素も b 要素も要素のカテゴリや内容モデルは変わらないのに、どうしてこの差が生まれるのでしょうか。

HTML のパースにあたって、abbigcodeemfontinobrssmallstrikestrongttu の各要素は書式設定要素という分類に含まれ、誤りの訂正方法が他の要素とは異なってくるのです。

Web 製作者が意図していたであろう構造を再現するため、また過去のブラウザのパース結果との互換性をできるだけ保つため、HTML パーサーはあれこれがんばって誤りを修正してくれているのですね。