Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

第9章 img はなぜ閉じタグを持たないのか

<p> にも <div> にも必ずある閉じタグが、<img> にはありません。書き忘れても怒られないどころか、</img> と書くほうが間違いです。なぜ画像だけ、特別扱いなのでしょうか。

この章では、img に閉じタグがないのは書き忘れを許しているからではなく、最初から子を持たない要素として設計されているからだと見ます。ゴールは、<img> を見たときに「終わりが省略されている」のではなく、「内容を包む種類の要素ではない」と説明できるようになることです。

前章では、ソースと DOM が違って見えるのは、ブラウザがどの段階の結果を見せているかが違うからだと整理しました。この章ではそこから一歩進めて、その違いを生む HTML の文法そのものへ目を向けます。次章では、もっと目立たない存在であるコメントにも仕様上の制約があることを見ます。

9.1 img は内容を包む要素ではない

pdiv を見ると、開始タグと終了タグのあいだに内容が入るのが HTML の基本形に見えます。その感覚のまま img を見ると、「なぜここだけ閉じタグがないのか」と不思議に見えます。

しかし img は、文章や子要素を内側に抱える要素ではありません。文書の中に画像という外部資源を埋め込む場所を示す要素です。必要なのは、どの画像を参照するか、代替テキストをどう与えるかといった属性であって、開始タグと終了タグのあいだに入る本文ではありません。

ここで重要なのは、img が「中身を書かなくてもよい要素」なのではないことです。最初から子を持てない要素として定義されているので、閉じタグが省略されているのではなく、そもそも持たないのです。

9.2 空要素という区別

HTML には、img のほかにも br hr meta link input のように、子を持たない要素があります。これらは空要素として扱われます。

<p>前置き<br>補足</p>
<img src="photo.jpg" alt="港の写真">

この例で br は改行位置を、img は画像の埋め込み位置を表しています。どちらも、あいだに文章や別要素を抱えて意味を作る要素ではありません。だから </br></img> のような終わり方を期待するより先に、「この要素は内容を囲む型なのか、位置だけを示す型なのか」を見分ける必要があります。

第1章で、HTML は処理を書く言語ではなく文書構造を記述する言語だと見ました。その観点から読むと、空要素は「ここに何かがある」という構造上の印を置く要素です。文を開いて閉じる箱ではなく、文書の中に特定の役割を持つ点を打つ要素だと考えたほうが実態に近いです。

ここで見えてくるのは、HTML が「タグごとに見た目の書き方が違う言語」なのではなく、「要素ごとに持てる内容を分類している言語」だということです。閉じタグの有無は、その分類の結果として表に出ているにすぎません。

9.3 <img /> は HTML では何を意味するのか

ここでよく混乱するのが、<img /> という書き方です。XML や XHTML に慣れていると、自己終了記法に見えます。そのため、「HTML でも末尾の / が要素を閉じている」と理解したくなります。

しかし HTML では、本質はそこではありません。img が閉じタグを持たないのは、末尾の / があるからではなく、img 自体が空要素だからです。つまり img の終わりを決めているのは見た目の記号ではなく、要素の定義です。

この違いを見失うと、「では <div /> も同じように閉じられるのか」と考えてしまいます。HTML ではそうはなりません。

<div />
<p>本文</p>

これを「div がここで閉じた」と読むと分かりやすそうですが、HTML ではそうした自己終了にはなりません。div は空要素ではないので、/ が付いていても、通常要素として扱われます。子を持つ通常要素と、最初から子を持てない空要素は、見た目が少し似ていても文法上は別物です。/ が魔法の閉じ記号なのではなく、空要素にたまたま付いていても害が出にくいだけだ、と理解したほうが正確です。

補足: そもそも img という要素は、1993 年に Mosaic ブラウザの開発者マーク・アンドリーセン(Marc Andreessen)が当時の議論の場(www-talk メーリングリスト)で提案したものです。画像を別ウィンドウではなく文書の中へ直接埋め込む案で、<icon> という別名や、もっと一般的な仕組みを推す声もありました。結局、いちばん手軽な img が広まって今も残っています。最初の設計が「最良」だったからではなく、現実に広く使われたものが残る——という、いかにも Web らしい決まり方の一例です。

もう 1 つ: 「<div />/ は無視される」と書きましたが、これには例外があります。HTML の中に埋め込んだ SVG や MathML(外来要素) の中では、<rect /> のような自己終了が本当に効きます。これらは XML 由来の文法を持つためです。つまり / が無意味なのは「HTML の通常要素では」という条件付きで、同じ 1 文字が、文脈によって効いたり効かなかったりします。

9.4 終了タグがないことは「ゆるさ」ではない

img に閉じタグがないと聞くと、HTML のゆるさの例に見えがちです。しかし実際には逆です。何でもありだから閉じタグがないのではなく、子を持たない要素を最初から区別しているから、ここでは閉じタグが不要になります。

この視点は、第2部で見てきた HTML の挙動にもつながります。HTML は入力に寛容な場面がある一方で、内部では要素ごとの役割や置ける内容をかなりはっきり区別しています。img が閉じタグを持たないのも、その区別の一部です。ゆるい書式の偶然ではなく、コンテンツモデル(要素ごとに「中に何を置けるか」を定めたルール)を持つ文法の結果として読むべきです。

実務でも、この理解は無駄ではありません。たとえばテンプレートを読んでいるときに、imgpdiv と同じ感覚で眺めると、「なぜここは閉じていないのか」という枝葉に引っ張られます。先に「これは内容を包む要素ではない」と分かっていれば、見るべき関心は閉じ方ではなく、srcalt など、その要素に本当に必要な情報へ向きます。

ここまでで、閉じタグの有無は書き方の癖ではなく、要素がどんな内容を持てるかという設計の結果だと分かりました。次章では、その視点をさらに地味な題材へ移し、コメントでさえ好き勝手に書けるわけではないことを見ます。

参考資料