program-htmlの日記

つれづれ書いてます

HTMLの細かい構文ルール-プログラミング・本のブログ

自身のアウトプットも兼ねてつれづれと書き続けるブログ。


HTML解体新書ー仕様から紐解く本格入門 [ 太田 良典 ]

前回からの続きです。

HTMLの細かい構文ルール[08]

[タグ名に使用できる文字]

HTMLのタグ名はASCII英字(ASCII alpha)で始まる必要があり、数字で始まることは許されません。下記の例のように記入すると<75と解釈されます。

<75>

1文字目だけASCII英字で2文字以降はほとんどの数字や記号類が使用できます。ただ2文字でも利用できない文字があります。

  • >:タグの終了と解釈される。
  • ASCII空白文字:属性値との区切りと解釈される。
  • /:自己終了タグもしくは属性値との区切りと解釈される。

 

【終了タグに属性は書けない】

終了タグに属性を書くことはできません。終了タグに属性を書いた場合、エラーとなり、属性は無視されます。ですが、終了タグ自体は有効に機能します。
下記の例だとclass="foo"は無視されるが、</p>は終了タグとして解釈されます。

<p>foo</p class="foo">

 

【終了タグ末尾の/】

終了タグの末尾に/を書くことはできません。単に/が無視され、終了タグ自体は解釈されます。下記の例だと/無視され、終了タグとして解釈されます。

<p>foo</p/>

 

【空タグ】

タグ名を省略した空のタグを指します。直近に開いた要素の名前を参照します。SGMLや理論上HTML4でも使用可能でしたが、現在のHTML構文では使用できません。下記の例だと<></>は直前のpを参照にpタグを解釈するそうです。

<p>テキスト</p>

<>テキスト</>

 

【開始タグを省略すると属性は書けない】

開始タグを省略できる場合があります。その一方で開始タグを省略した際に属性のみを書く方法は存在しません。つまり、属性を指定したければ必ず開始タグを書かなければいけません。

 

【重複する属性】

同一の属性は複数指定できません。下記の例ですとclass="name1"のみ解釈されます。属性の種類によっては複数の値を指定できる場合があります。classの場合はASCII空白文字(スペース)で区切って指定します。

<div class="name=1" class="name2">


<!-- 複数の値を指定 -->

<div class="name=1 name2">

 

【属性値の省略】

空の属性値の記述は省略できます。

<img alt>

<img alt="">

<img alt=''>

 

【引用符のない属性】

属性を書く場合、引用符を省略できる場合があります。引用符を省略した場合、以下のような解釈になります。

  • タブ、改行、スペース、>が出現すると属性値が終了と解釈
  • "、'、<、=、`が出現すると構文エラーとなるが、該当の文字は属性値の一部として解釈される。

仕様上可能だが、セキュリティ観点からは、属性値は引用符で括ることを強く推奨されてます。

 

【終了タグを書き漏らした際のエラー】
終了タグを書き漏らした場合、ブラウザーで様々な解釈をされます。後述のように直感に反する挙動となることが多いため、エラーが起きないマークアップをするように心掛けたい。

直感に反するエラー

HTML Standardのエラー処理には、直感に反する特殊なルールがいくつかあります。

 

ノアの方舟ルール】

<p><b><b><b><b>4つのb開始タグ</p>

<p>bのないp</p>

上記の例のようにわざと<b>を4つ書きエラーを起こさせた場合、下記の例のように解釈されます。

<p><b><b><b><b>4つのb開始タグ</b></b></b></b></p>

<b><b><b><p>bのないp</p></b></b></b>

<b>が1つの時と同じルールで補正されているように見えますが、2行目のp要素の外側に補われている<b>タグと</b>タグの数は3つしかありません。4つあったはずのb要素が1つ減っています。これは、要素をまたがって補われる際、同一要素名・同一クラスの要素は3つまでしか復元されないルールがあるからです。これをノアの方舟(Noah's Ark)といいます。

 

【foster parenting】
table要素には特殊なエラー処理foster parentingがあります。table要素直下には、caption, col, colgroup, thead, tbody, tfoot要素といったテーブル関連要素を入れることができます。ただし、それ以外の要素を入れると構文エラーになります。

<table>

  <tr>

    <th>見出しセル</th>

    <td>データセル</td>

  </tr>

  <p>テキスト</p>

</table>

上記の例ですとtable要素内にp要素を入れています。先ほどもいいましたが、テーブル関連要素以外の要素を入れていますので、構文エラーになり下記のような解釈をされてしまします。

<p>テキスト</p>
<table>

  <tr>

    <th>見出しセル</th>

    <td>データセル</td>

  </tr>

</table>

下にあったp要素がtableの前に移動されています。table要素ではテーブル関連要素以外の要素は前に追い出せれる仕様になっています。これをfoster parentingといいます。

特に注意したいのは全角スペースです。全角スペースもtable要素は前に追い出されます。マークアップでインデントを全角にすると、予想外の挙動になる場合もありますので注意が必要です。

 

ルート要素と文章のメタデータ[01]