噂のID問題

噂のID問題

[36] 噂の ID 問題とは、2001年頃~2004年頃に話題になった、 HTMLid 属性値大文字小文字の扱いに関する問題です。

当時 HTML の規範とされていた HTML4 仕様は、 HTMLSGML応用であるとの空想 (あるいは願望) の上に構築されていました。 HTML4id 属性SGMLID 属性型として定義されていましたが、 HTML4SGML宣言により、 id 属性値SGML構文解析器によって大文字正規化されると記述されていました。

しかし、実は HTML4 の中の人の意図も、現実の Webブラウザの実装 (一部を除く。) も、 id 属性大文字小文字は区別されるというものでした。 HTML4 仕様書中には id 属性大文字小文字を区別すると書かれていましたし、 SGML構文解析器による大文字化が行われないとしないと理解できない例が挙げられていました。

つまり、 HTML4 の中の人は SGML を使っていなかったのでその規定を知らなかったかうっかり忘れており、 仕様書中に示した HTML 文書の例を実際に SGML構文解析器を使った Webブラウザで確認することもせず (だってそんなもの存在していない!)、 Webブラウザを作っている人達も一々 Web で現実に使われていない SGML の仕様など確認せず、最初の W3C 勧告から4年くらい経つまで誰も間違いに気付かなかったというわけです。

それでもまだ人々は HTMLSGML応用であるとの夢から醒めていませんでしたから、 一部の人達は仕様上も実装上も問題にならないよう大文字だけを id 属性値として使うべきだと主張しましたし (ISO-HTML 関係者など)、 仕様の解釈を無理にでもこじつけて当時の現状を正当化しようとした人もいました (当時の HTML WG など)。

結局仕様と実情が一致するのは SGML の夢から醒めた HTML5 を待つことになります。

[2] 要約: HTML 4 以前の (XHTML になるより前の) HTML の終点アンカー (id 属性や name 属性の値) に小文字のラテン文字を使うことは可能で、 実際によく使われてきましたが、実は規格上問題がありますから、 使わないほうが幸せになります。この問題は XHTML にはありませんが、XHTML に限らず HTML 4 以前の HTML で書かれた文書の素片識別子 (#) を含む URI参照を使うときにこの問題に巻き込まれる虞がありますから、油断はできません。

詳しくは次の文献等をどうぞ。

[1] 釣瓶雜記(2003年11月〜12月) <http://kazmacky.cool.ne.jp/kinkyo/2003e.html#DATE1128_01>

ISO‐HTML利用者の手引き』 を引用して詳しく考察しています。

[8] User's Guide to ISO/IEC 15445:2000(E) ISO-HTML <http://www.cs.tcd.ie/15445/UG.HTML#ANCHOR-FOLDING>

[9] 2003年11月 - マーク付けノート <http://www.satoshii.org/markup/notes/2003/11#date23>

[10] <IW:htmllint:1142>: この問題を日本語圏に知らしめるきっかけとなったメイル。

[17] CSS へのこの問題の影響は?

5.9 ID selectors <IW:CSS2:"selector.html#id-selectors"> にはそもそも大文字・小文字の区別に言及がないような。 <http://www.w3.org/TR/2003/WD-CSS21-20030915/selector.html#id-selectors> も同じ。

5.1 Pattern matching <IW:CSS2:"selector.html#q1"> には要素型名が HTML では区別されない旨、 5.8.1 Matching attributes and attribute values <IW:CSS2:"selector.html#q10"> には属性名・属性値が文書言語によっては区別されない旨が書かれてはいるけど。

他のところの記述を見落としているのでなければ、 そもそも CSS では #ID は大文字で書かないといけなかったことになる。

[18] 関係ないけど気になったのは、 属性値の区別が文書言語に依存すること。 文書言語とは The encoding language of the source document (e.g., HTML or an XML application).だから、 XHTML1.0<p lang="JA"> と書いてもちゃんと p[lang|="ja"] と一致するようになっているわけだ。

でも XHTML じゃなくて何か UA が知らないマーク付け言語だとこうはならない。 悲劇的ですらある CSS の非互換問題の中ではこんなのどうでもいいことかもだけど。

[19] Namazu は素片識別子になる name 属性を勝手に小文字にしちゃうようだ (id にはそもそも未対応)。 おかげで対策した文書の検索結果の素片識別子が役に立たない。

アンカー名の構文

[20] アンカー名 (name または id) は、文書内で固有でなければなりません。すなわち、 文書内の他の nameid と同じ名前ではいけません。

しかも、大文字・小文字の違いだけの別の名前を使うこともできません。

仕様書: HTML 4 12.2.1 Syntax of anchor names <IW:HTML4:"struct/links.html#idx-anchor-3">

[21] 例えば、

<P><A name="xxx">...</A>
<P><A name="XXX">...</A>

(HTML 4 仕様書より) は違法です。

[25] HTML 4 仕様書によれば、アンカー名は ASCII 文字に制限するべきです。

アンカー名の一致

[22] アンカー名と素片識別子の一致の検査は、 大文字・小文字を区別して行わなければなりません。

仕様書:

[23] 次の例は、合法ですが、 UA の挙動は未定義です (小文字のアンカー名が他で定義されていないとして)。

<P><A href="#xxx">...</A>
...more document...
<P><A name="XXX">...</A>

HTML 4 仕様書

一部の UA は (不正に) 一致するものとみなしてしまいますが、 そうでない UA もあります。

[24] >>23 不正にって注記が入っているあたり、 未定義とはいえないような... どうよ? > HTML 4 の中の人

[26] a, form, img, map, applet, frame, iframe では、固有識別子を指定するために nameid の両方を指定することが認められます。 ただし、同じ要素の2つの属性の値は同じでなければなりません。 HTML 4.01 12.2.3, A.1.1.8

[28] 合法な例:

<P><A name="A1" id="A1" href="#A1">...</A>

(HTML 4 仕様書より、改)

[27] 違法な例:

<A href="#A1">...</A>
...
<H1 id="A1">
...pages and pages...
<A name="A1"></A>

(HTML 4 仕様書より、改)

大文字と小文字の区別のまとめ

[31]

規格識別子区別素片識別子として使用メモ
SGML {NAMECASE GENERAL YES}IDなし (大文字化)
SGML {NAMECASE GENERAL NO}IDあり
XMLIDありする
HTML 4a nameありする区別をなくすと区別できない名前は使用禁止
HTML 4idDTD: なし (大文字化), 本文: ありするa name と同じ名前空間
HTML 4img nameあり
HTML 4applet nameあり
HTML 4map nameなしする
HTML 4frame nameなし
HTML 4iframe nameなし
HTML 4form nameなし
SGML {NAMECASE GENERAL YES}IDREFなし (大文字化)
SGML {NAMECASE GENERAL NO}IDREFあり
XMLIDREFあり
URI 参照素片識別子あり
HTML 4素片識別子あり
HTML 4label forDTD: なし (大文字化), 本文: あり
HTML 4param value (datatypeobject)不明
HTML 4meta nameありしない複数要素で同名可
HTML 4param name物体依存しない複数要素で同名可
HTML 4フォーム制御子 nameありしない複数要素で同名可なことも

id vs name

[29] idname、 どちらを使うべきかについて、 HTML 4 仕様書 (12.2.3 Anchors with the id attribute <IW:HTML4:"struct/links.html#idx-anchor-10">) は次のように説明しています。

ただし、 HTML 4 仕様書が id では文字参照実体参照を使えないと言っているのは間違いです。 どちらの属性でも、属性値表記を使えば参照で書けます。

[30] このうち、古い UA は id に対応していないという点は、 HTML 4 が勧告された1990年代後半にはまだ比較的大きな問題でしたが、 今となってはそのような UA はほとんど使われていませんし、 使っていたとしても利用者は既にかなり不利益を被っているはずですから、 もはや気にする必要はまったくないでしょう。

メモ

[32] XHTMLでは大文字のid属性でも大丈夫 - 徒書 (北村曉 著, 2007-01-30 16:04:46 +09:00 版) <http://www.akatsukinishisu.net/itazuragaki/html/id_attr_in_xhtml.html> (名無しさん 2007-01-31 21:50:12 +00:00)

[33] 余白雑記 > January 2007 - よはくのところ。 (香川さやか 著, 2007-01-30 00:14:33 +09:00 版) <http://yohaku.maybe.jp/diary/d2007/d-0701.htm#JAN29A> (名無しさん)

[34] id属性値が小文字のHTML4をXHTMLへ移行する場合 - 徒書 (北村曉 著, 2007-01-30 15:59:59 +09:00 版) <http://www.akatsukinishisu.net/itazuragaki/html/lower_case_id_html4.html> (名無しさん)

[35] まじかんと雑記: HTML の id の大文字・小文字の問題 ( 版) <http://magicant.txt-nifty.com/main/2007/12/html_id_dcf5.html> (名無しさん)