HTML 4.01 は下記リンクでid属性/class属性を定義しています。
id属性値は文法上、NAMEトークンであり、class属性値はCDATAのリストで表されるようです。
- id属性値は「アルファベット([A-Za-z])で開始し、任意の数のアルファベット、数字、([0-9])、ハイフン(-)、アンダースコア(_)、コロン、(:)、ピリオド(.)のみで記述する必要がある。大文字/小文字を区別する(CS)。この名前は文書中で一意でなければならない(MUST)。」
- class属性値は「空白文字によって区切られた空白以外の文字列のリストである。HTML文字実体参照/数値参照を解釈し、改行コード(LF)を無視し、改行コード(CR)またはタブ文字は一つの空白文字で置き換える。大文字/小文字を区別する(CS)。」
id属性値の「一意でなければならない」については後述の「id属性値の名前は文書中で一意でなければならない」も参照してください。 class属性値は空白以外の全ての文字を指定する事が出来ます。
HTML Living Standard (通称 HTML 5) ではid属性値、class属性値に対して空白文字を除く全ての文字を使用できます。 id属性値の「名前が一意でなければならない」のは HTML 4.01 と同様です。
「一意でなければならない」は「文書中で同じ名前を複数回指定してはならない」と置き換えることもできます。 例えば、次のHTML文書は文法違反です。
<p id="hoge">hoge 1</p>
<p id="hoge">hoge 2</p>
同一文書内で同じid属性値を複数指定した場合、Webブラウザはそれを警告する事はしませんが、CSS/JavaScriptにおいて期待通りに動作しない場合があります。
<style>
/**
* <p id="hoge">hoge 1</p> にのみ適用される
*/
#hoge {
border: solid 1px red;
}
</style>
<p id="hoge">hoge 1</p>
<p id="hoge">hoge 2</p>
<script>
console.log(document.getElementById('hoge')); // <p id="hoge">hoge 1</p>
</script>
idセレクタも getElementById
もは最も先に出現した要素にのみマッチします。
属性セレクタ [id="hoge"]
で複数の要素にマッチ可能ですが、そうするぐらいなら class="hoge"
と記述してclassセレクタを使うべきでしょう。
id属性値は「フラグメント識別子(URLハッシュ)」としても扱われる重要な属性の為、ユニークな名前を付ける必要があります。
Selectors API 規定上も数字から始まる名前はエスケープシーケンスを使えば表現可能です。
- 6.7. ID 選択子 - Selectors Level 4 (日本語訳)
- 6.6. class 選択子 - Selectors Level 4 (日本語訳)
- 4.1.3 文字と活字ケース - Cascading Style Sheets Level 2 Revision 2 (CSS 2.2) Specification 日本語訳
- CSSにおいて、(要素名、クラス、およびセレクター内のIDを含む)識別子は、文字
[a-zA-Z0-9]
およびISO 10646のU+0080以上の文字、さらにハイフン(-
)およびアンダースコア(_
)のみを含むことができる。識別子は、数字、2つのハイフン、ハイフンの直後の数字で開始できない。識別子はまた、エスケープされた文字および数字コードとして任意のISO 10646文字を含めることができる(次項を参照)。たとえば、識別子"B&W?"
は、"B\&W\?"
または"B\26 W\3F"
として記述してもよい。 Unicodeは、コード・バイ・コードでISO 10646と等価であることに注意する([UNICODE]および[ISO10646]参照)。
まとめると次のようになります。
- 文字
[a-zA-Z0-9]
およびISO 10646のU+0080以上の文字、さらにハイフン(-
)およびアンダースコア(_
)のみを含むことができる - 数字(
[0-9]
)、2つのハイフン(--
)、ハイフンの直後の数字(-[0-9]
)で開始できない - バックスラッシュ(
\
)で文字をエスケープできる(例:\-
は-
を表す) - Unicodeエスケープシーケンスを利用できる(例:
\\0030
は0
を表す)
なお、バックスラッシュエスケープ(3.)やUnicodeエスケープシーケンス(4.)を利用すれば、2. の数字やハイフンから始まることが出来ない制約を回避する事が可能です(次節参照)。
下記はUnicodeエスケープシーケンスを利用して class="03"
の要素ノードにマッチするclassセレクタをCSS/JavaScriptで書いたものです。
<style>
/* class="03" */
.\0030\0033 {
border: solid 1px red;
}
</style>
</head>
<body>
<img src=" card_1.png" class="01" alt="カード No.1" />
<img src=" card_2.png" class="02" alt="カード No.2" />
<img src=" card_3.png" class="03" alt="カード No.3" />
<script src="../lib/other-work-lib/jquery-3.1.1.js"></script>
<script>
'use strict';
console.log(document.querySelector('.\\0030\\0033')); // <img src=" card_3.png" class="03">
console.log(jQuery('.\\0030\\0033')); // <img src=" card_3.png" class="03"> を含むjQueryオブジェクト
</script>
CSSのUnicodeエスケープシーケンスはJavaScriptのUnicodeエスケープシーケンスとよく似ており、JavaScriptの \u0030
は CSS の \0030
になります。
確かに実現可能ですが、セマンティクス的な意味では数字から始まる名前は好ましくないと考えられます。機械的にはそれで良くても人の目には分かりやすい名前ではないからです。 例えば、次のように名前を変えることを検討できます。
<p>[例1] id属性に変更する</p>
<img id="card-01" src=" card_1.png" alt="カード No.1" />
<img id="card-02" src=" card_2.png" alt="カード No.2" />
<img id="card-03" src=" card_3.png" alt="カード No.3" />
<p>[例2] 接頭辞を付けてマルチクラスにする</p>
<img src=" card_1.png" class="card no-01" alt="カード No.1" />
<img src=" card_2.png" class="card no-02" alt="カード No.2" />
<img src=" card_3.png" class="card no-03" alt="カード No.3" />
<p>[例3] data-*独自属性を使う</p>
<img src=" card_1.png" class="card" data-no="01" alt="カード No.1" />
<img src=" card_2.png" class="card" data-no="02" alt="カード No.2" />
<img src=" card_3.png" class="card" data-no="03" alt="カード No.3" />
ハイフン区切りのid名にしているのは、属性セレクタ([att|=val]
)を適用しやすいようにする為です。
例えば、[id|="card"]
で id="card-"
で始まる要素全て([例1] が該当)にマッチ出来ます。