こんにちは @color_box です。
個人開発中に遭遇した疑問を調べていたら、HTMLのLiving Standardに行き着いた話について書きます。
不可解なタグ移動
不可解な挙動だとおもって詳しく調べていたらHTMLのLiving Standardに行き着いたという話です。
個人の趣味プロジェクトにて、下記のようなHTMLを表示しようとしたところ
<body> <table> <tbody> <tr> <a format="js" data-remote="true" rel="nofollow" data-method="put" href="/kaomojis/122/select"> <td class='' id='122'> something </td> </a> <a format="js" data-remote="true" rel="nofollow" data-method="put" href="/kaomojis/123/select"> <td class='' id='123'> something2 </td> </a> </tr> </tbody> </table> </body>
ブラウザで表示した結果下記のようになりました。
<body> <a format="js" data-remote="true" rel="nofollow" data-method="put" href="/kaomojis/122/select"> </a> <a format="js" data-remote="true" rel="nofollow" data-method="put" href="/kaomojis/123/select"> </a> <table> <tbody> <tr> <td class='' id='122'> something </td> <td class='' id='123'> something2 </td> </tr> </tbody> </table> </body>
<a>
タグの位置が <table>
タグの前に移動してしまい、ズレた場所に表示されています。
そもそも <a>
タグの中に <td>
タグを入れるなという話ではあります。
しかし、ブラウザでの表示が壊れるとかではなく、タグの位置がずれたりするのは直感に反する動きだったのでこの挙動について詳しく調べることにしました。
HTMLの改変場所の調査
まず、curlコマンドで直接HTMLを取得したらどうなるかを確認します。 その場合、最初の意図通りのHTMLが取得できました。
次に、ブラウザの種類に応じてこのような挙動になっているのかどうかが気になったため、複数のブラウザでの挙動を確認します。 最初に確認した環境はChromeだったため、次にSafariでの挙動を確認しました。 結果は変わらず、ChromeでもSafariでも表示されるHTMLに変化はありませんでした。
これらのことから、HTMLの改変はブラウザで発生しているのではないか?ということが推測できました。 ブラウザの種類によらず、同様の改変がされているのであれば、ChromeとSafariの両ブラウザが共通としている仕様、つまりHTMLのLiving Standardに起因しているのではないかということが推測できました。
HTML Living Standardの調査
パースに関するページ内でtable
などのキーワードで検索して眺めているとそれっぽい記述が見つかります。
The highlighted b element start tag is not allowed directly inside a table like that, and the parser handles this case by placing the element before the table.
例として言われているのは <b>
タグですが、 <table>
タグの前に移動させるという点がまさに直面している問題と同じ挙動でした。
このことから、最初に上げた不可解なタグの移動はHTMLの仕様によるものであるということがわかりました。
これはfoster-parentという仕組みだそうです。
まとめ
いかがでしたか?
今回はちょっとした疑問からHTMLのLivingStandardについて私が調べたときの流れを紹介させていただきました。
この件について分報でボヤいた時、HTMLのLiving Standardに関するページの共有とヒントをくれた同僚の@wat_aro氏と9sako6氏に感謝します。
この記事が今後似たような調査をするどなたかのお役に立てば幸いです。