colspan="100%"の罠 ―W3CのHTML5仕様書を読んでみた―

項目1 項目2 項目3
データが登録されていません

仕事で、上のようなテーブル(データがないときに、データがない旨のメッセージを表示する)に列を追加したら

項目1 項目2 項目3 追加された項目
データが登録されていません

このようにテーブルが欠けるバグがあった。

<td colspan="4">登録されていません</td>

項目1 項目2 項目3 項目4
登録されていません

こうすれば直るけれど、列を追加した際に同様のバグがまた混入するのでメンテナンス性が悪い。

<td colspan="100%">登録されていません</td>

項目1 項目2 項目3 項目4
登録されていません

ググったらcolspan="100%"で行けると言っている人がいて、一見すると良さそうだけれど

<td colspan="50%">登録されていません</td>

項目1 項目2 項目3 項目4
登録されていません

50%にしても半分にならない。

<td colspan="3abc">登録されていません</td>

項目1 項目2 項目3 項目4
登録されていません

ここまで試すと、100%はただの100と同じだったらしいということが読めて来る。

では何故そうなっているのかについては、W3CHTML5の仕様書を読めば分かった。

1. Let input be the string being parsed.
2. Let position be a pointer into input, initially pointing at the start of the string.
3. Let sign have the value "positive".
4. Skip white space.
5. If position is past the end of input, return an error.
6. If the character indicated by position (the first character) is a U+002D HYPHEN-MINUS character (-):
 1. Let sign be "negative".
 2. Advance position to the next character.
 3. If position is past the end of input, return an error.
Otherwise, if the character indicated by position (the first character) is a U+002B PLUS SIGN character (+):
 1. Advance position to the next character. (The "+" is ignored, but it is not conforming.)
 2. If position is past the end of input, return an error.
7. If the character indicated by position is not an ASCII digit, then return an error.
8. Collect a sequence of characters that are ASCII digits, and interpret the resulting sequence as a base-ten integer. Let value be that integer.
9. If sign is "positive", return value, otherwise return the result of subtracting value from zero.

数値を解釈するアルゴリズムが示されている。簡単にまとめると、先頭が数字の場合に、連続する数字を表す文字(ASCII digit)の塊を10進数の数値として評価しているという訳だ。

<td colspan="abc4abc">登録されていません</td>

項目1 項目2 項目3 項目4
登録されていません

7. If the character indicated by position is not an ASCII digit, then return an error.

先頭の文字が数字でない場合はエラーを返すとあるので、上のように先頭が数字でないパターンを試してみると、確かに中間に置いた数値は評価されないことが分かる。

話題としては些細なものだけれど、仕様書のアルゴリズムに基本的に忠実な形で各ブラウザが実装されていることを知れて何だか感慨深い。