[6] [[CSS]] ではほとんどあらゆるところで[[文字]]を [DFN[[[escape]]]] して使うことができます。

[8] [[CSS]] の他、共通の構文を使っている、[[選択子]]や[[媒体照会]]でも [[escape]] を使えます。

* 仕様書

[REFS[
- [7] [CITE@en[Syntax and basic data types]] ([TIME[2011-06-07 22:09:52 +09:00]] 版) <http://www.w3.org/TR/CSS21/syndata.html#characters>
]REFS]

* 構文

- [15] [CODE(char)[[[\]]]] の後に[[十六進数]] ([[大文字]]または[[小文字]]) が続く場合、
-- [16] その[[十六進数]]で表される[[符号位置]]の [[ISO/IEC 10646]] の[[文字]]を表します [SRC[>>7]]
--- [17] なぜかここでの定義は [[Unicode]] ではなく [[ISO/IEC 10646]] になっています
--- [20] [[符号位置]]は 0 であっては[['''なりません''']] [SRC[>>7]]
---- [21] 0 であるときの解釈は未定義とされています [SRC[>>7]]
--- [25] [[符号位置]]が [[Unicode]] の範囲外 ([CODE(char)[[[U-00110000]]]] [[以上]]) であるなら、
[[利用者エージェント]]は [CODE(charname)@en[[[U+FFFD]]]] に置き換えても[['''構いません''']]。
[[表示]]するときは「[[文字]]なし」[[グリフ]]など可視な[RUBYB[記号]@en[symbol]]を表示する[['''べきです''']]。 [SRC[>>7]]
-- [18] [[十六進数]]は高々6桁です [SRC[>>7]]
-- [19] [[十六進数]]の後に[[空白]]があれば、それは (高々1[[文字]]だけ) 無視されます [SRC[>>7]]
- [12] [CODE(char)[[[\]]]] の後に[[改行]]が続く場合、
-- [13] [[文字列]]の中では、 [CODE(char)[[[\]]]] と[[改行]]は無視されます [SRC[>>7]]
-- [14] [[文字列]]の外では、 [CODE(CSS)[[[DELIM]]]] [[字句]]の後に[[改行]]が続いているものとみなされます [SRC[>>7]]
- [23] [CODE(char)[[[\]]]] の後にそれ以外が続く場合、その続いた[[文字]]自体を表します [SRC[>>7]]
-- [24] その[[文字]]が [[CSS]] の構文上特別な意味を持っていたとしても、 [[escape]] すると打ち消されます [SRC[>>7]]
- [26] これら [[escape]] は、[[文字列]]内ならその[[文字列]]の一部として、[[文字列]]外なら[[識別子]]の一部としてみなされます
[SRC[>>7]]
- [10] [[スタイル・シート]]の末尾の [CODE(char)[[[\]]]] は [CODE(CSS)[[[DELIM]]]] [[字句]]とみなされます [SRC[>>7]]
-- [11] 実際には現時点でこれを使った構文は存在していないので、[[非妥当]]になります
- [9] なお、[[注釈]]内の [CODE(char)[[[\]]]] は特別な意味を持たず、単なる[[注釈]]の中の文字列とみなされます [SRC[>>7]]

;; [22] [[CSS]] の[[改行]]は [CODE(charname)@en[[[CRLF]]]], [CODE(charname)@en[[[CR]]]],
[CODE(charname)@en[[[LF]]]], [CODE(charname)@en[[[FF]]]] のいずれかです。[[空白]]はそれに加えて
[CODE(charname)@en[[[HT]]]], [CODE(charname)@en[[[SP]]]] です。

** \0000

[REFS[
- [31] [[型選択子]] <http://suika.suikawiki.org/gate/2007/cssom/viewer?c=element%5C000000x%20%7B%0D%0A%20%20color%3A%20red%3B%0D%0A%7D%0D%0Aelement%5C000001y%20%7B%0D%0A%20%20color%3A%20green%3B%0D%0A%7D%0D%0Aelement%5C000021y%20%7B%0D%0A%20%20color%3A%20green%3B%0D%0A%7D;h=%3Celement%3Eelement%3C%2Felement%3E%0D%0A%3Celementx%3Eelementx%3C%2Felementx%3E%0D%0A%3Celementy%3Eelementy%3C%2Felementy%3E%0D%0A%3Celement000000x%3Eelement000000x%3C%2Felement000000x%3E%0D%0A%3Celement!y%3Eelement!y%3C%2Felement!y%3E;p=n;x=style-element;i=html-div>
- [29] [[クラス選択子]] <http://suika.suikawiki.org/gate/2007/cssom/viewer?c=.class%5C000000x%20%7B%0D%0A%20%20color%3A%20red%3B%0D%0A%7D%0D%0A.class%5C000001y%20%7B%0D%0A%20%20color%3A%20green%3B%0D%0A%7D%0D%0A.class%5C000021y%20%7B%0D%0A%20%20color%3A%20green%3B%0D%0A%7D;h=%3Cp%20class%3Dclass%3E.class%0D%0A%3Cp%20class%3Dclassx%3E.classx%0D%0A%3Cp%20class%3Dclassy%3E.classy%0D%0A%3Cp%20class%3Dclass000000x%3E.class000000x%0D%0A%3Cp%20class%3Dclass%26%230%3Bx%3E.class%20U%2B0000%20x%0D%0A%3Cp%20class%3Dclass%26%23xFFFD%3Bx%3E.class%20U%2BFFFD%20x%0D%0A%3Cp%20class%3Dclass%26%231%3By%3E.class%20U%2B0001%20y%20-%20This%20paragraph%20must%20be%20green.%0D%0A%3Cp%20class%3Dclass!y%3E.class!y%20-%20This%20paragraph%20must%20be%20green.%0D%0A;p=n;x=style-element;i=html-div>
]REFS]

[30] >>29 [[Firefox]] は [CODE(CSS)[\000000]] を [CODE(CSS)[000000]] と解釈します。
[[chrome]] は [CODE(char)@en[[[U+0000]]]] と解釈します。
[[WinIE8]] と [[Opera]] はその[[字句]]の当該 [[escape]] 以降を無視します。 [TIME[2011-10-29T01:27:45.700Z]]

[32] [[Chrome]] だと >>29 は [CODE(DOMa)@en[[[cssText]]]] で
[CODE(CSS)[\0]] とか [CODE(CSS)[\1]] になってるけど、 >>28 では [[escape]] されないでそのまま入ってるっぽい。

** \ + 10FFFF より上

[REFS[
- [34] <http://suika.suikawiki.org/gate/2007/cssom/viewer?c=di%5C110000v%20%7B%0D%0A%20%20color%3A%20green%3B%0D%0A%7D%0D%0A;h=%3Cp%3E%3Cbutton%20type%3Dbutton%20onclick%3D'%0D%0A%20%20var%20name%20%3D%20%22di%22%20%2B%20String.fromCharCode%20(0xFFFD)%20%2B%20%22v%22%3B%0D%0A%20%20try%20%7B%20document.createElement%20(name)%3B%20%7D%20catch%20(e)%20%7B%20%7D%0D%0A%20%20this.parentNode.innerHTML%20%3D%20%22%3C%22%20%2B%20name%20%2B%20%22%3Edi%20U%2BFFFD%20v%20-%20This%20paragraph%20should%20be%20green.%3C%2F%22%20%2B%20name%20%2B%20%22%3E%22%3B%0D%0A'%3EPush%20this%20button%3C%2Fbutton%3E%0D%0A%3Cp%3E%3Cbutton%20type%3Dbutton%20onclick%3D'%0D%0A%20%20var%20name%20%3D%20%22di%3Fv%22%3B%0D%0A%20%20document.createElement%20(name)%3B%0D%0A%20%20this.parentNode.innerHTML%20%3D%20%22%3C%22%20%2B%20name%20%2B%20%22%3Edi%3Fv%20-%20This%20paragraph%20should%20be%20green.%3C%2F%22%20%2B%20name%20%2B%20%22%3E%22%3B%0D%0A'%3EPush%20this%20button%3C%2Fbutton%3E%0D%0A;p=n;x=style-element;i=html-div>
]REFS]

[35] [[十六進数]]が [CODE(char)[[[U+10FFFF]]]] よりも大きい時、 [[Gecko]] と [[Chrome]]
は [CODE(char)[[[U+FFFD]]]] とみなし、 [[WinIE8]] は [CODE(char)[[[U+003F]]]] とみなします。
[[Opera]] は [[high surrogate]] を [[UTF-16]] の範囲より先に進めた [[surrogate pair]] のようなものとして表現した値
([CODE(char)[[[U-00110000]]]] → [CODE(char)[[[U+DC00]] [[U+DC00]]]]) とみなします。

** \ + surrogate

[REFS[
- [36] 正しい [[surrogate pair]] の [[escape]] <http://suika.suikawiki.org/gate/2007/cssom/viewer?c=di%5C00D800%5C00DC00v%20%7B%0A%20%20color%3A%20green%3B%0A%7D%0A;h=%3Cp%3E%3Cbutton%20type%3Dbutton%20onclick%3D%27%0A%20%20var%20name%20%3D%20%22di%22%20%2B%20String.fromCharCode%20(0xFFFD%2C%200xFFFD)%20%2B%20%22v%22%3B%0A%20%20try%20%7B%20document.createElement%20(name)%3B%20%7D%20catch%20(e)%20%7B%20%7D%0A%20%20this.parentNode.innerHTML%20%3D%20%22%3C%22%20%2B%20name%20%2B%20%22%3Edi%20U%2BFFFD%20U%2BFFFD%20v%20-%20This%20paragraph%20should%20not%20be%20green.%3C%2F%22%20%2B%20name%20%2B%20%22%3E%22%3B%0A%27%3EPush%20this%20button%3C%2Fbutton%3E%0A%3Cp%3E%3Cbutton%20type%3Dbutton%20onclick%3D%27%0A%20%20var%20name%20%3D%20%22di%3F%3Fv%22%3B%0A%20%20try%20%7B%20document.createElement%20(name)%3B%20%7D%20catch%20(e)%20%7B%20%7D%0A%20%20this.parentNode.innerHTML%20%3D%20%22%3C%22%20%2B%20name%20%2B%20%22%3Edi%3F%3Fv%20-%20This%20paragraph%20should%20not%20be%20green.%3C%2F%22%20%2B%20name%20%2B%20%22%3E%22%3B%0A%27%3EPush%20this%20button%3C%2Fbutton%3E%0A%3Cp%3E%3Cbutton%20type%3Dbutton%20onclick%3D%27%0A%20%20var%20name%20%3D%20%22di%22%20%2B%20String.fromCharCode%20(0xD800%2C%200xDC00)%20%2B%20%22v%22%3B%0A%20%20try%20%7B%20document.createElement%20(name)%3B%20%7D%20catch%20(e)%20%7B%20%7D%0A%20%20this.parentNode.innerHTML%20%3D%20%22%3C%22%20%2B%20name%20%2B%20%22%3Edi%20U%2BD800%20U%2BDC00%20v%20-%20This%20paragraph%20should%20be%20green.%3C%2F%22%20%2B%20name%20%2B%20%22%3E%22%3B%0A%27%3EPush%20this%20button%3C%2Fbutton%3E%0A;p=n;x=style-element;i=html-div>
- [37] 不正な [[surrogate]] の [[escape]] <http://suika.suikawiki.org/gate/2007/cssom/viewer?c=di%5C00DC00%5C00D800v%20%7B%0D%0A%20%20color%3A%20green%3B%0D%0A%7D;h=%3Cp%3E%3Cbutton%20type%3Dbutton%20onclick%3D'%0D%0A%20%20var%20name%20%3D%20%22di%22%20%2B%20String.fromCharCode%20(0xFFFD%2C%200xFFFD)%20%2B%20%22v%22%3B%0D%0A%20%20try%20%7B%20document.createElement%20(name)%3B%20%7D%20catch%20(e)%20%7B%20%7D%0D%0A%20%20this.parentNode.innerHTML%20%3D%20%22%3C%22%20%2B%20name%20%2B%20%22%3Edi%20U%2BFFFD%20U%2BFFFD%20v%20-%20This%20paragraph%20should%20be%20green.%3C%2F%22%20%2B%20name%20%2B%20%22%3E%22%3B%0D%0A'%3EPush%20this%20button%3C%2Fbutton%3E%0D%0A%3Cp%3E%3Cbutton%20type%3Dbutton%20onclick%3D'%0D%0A%20%20var%20name%20%3D%20%22di%3F%3Fv%22%3B%0D%0A%20%20try%20%7B%20document.createElement%20(name)%3B%20%7D%20catch%20(e)%20%7B%20%7D%0D%0A%20%20this.parentNode.innerHTML%20%3D%20%22%3C%22%20%2B%20name%20%2B%20%22%3Edi%3F%3Fv%20-%20This%20paragraph%20should%20not%20be%20green.%3C%2F%22%20%2B%20name%20%2B%20%22%3E%22%3B%0D%0A'%3EPush%20this%20button%3C%2Fbutton%3E%0D%0A%3Cp%3E%3Cbutton%20type%3Dbutton%20onclick%3D'%0D%0A%20%20var%20name%20%3D%20%22di%22%20%2B%20String.fromCharCode%20(0xDC00%2C%200xD800)%20%2B%20%22v%22%3B%0D%0A%20%20try%20%7B%20document.createElement%20(name)%3B%20%7D%20catch%20(e)%20%7B%20%7D%0D%0A%20%20this.parentNode.innerHTML%20%3D%20%22%3C%22%20%2B%20name%20%2B%20%22%3Edi%20U%2BDC00%20U%2BD800%20v%20-%20This%20paragraph%20should%20not%20be%20green.%3C%2F%22%20%2B%20name%20%2B%20%22%3E%22%3B%0D%0A'%3EPush%20this%20button%3C%2Fbutton%3E;p=n;x=style-element;i=html-div>
]REFS]

[38] [[Chrome]], [[Firefox]], [[WinIE8]], [[Opera]] のいずれも、 [[surrogate pair]]
を [[escape]] したものをそのまま解釈します。 [TIME[2011-10-29T02:21:40.200Z]]

[39] [[Chrome]], [[WinIE8]], [[Opera]] は正しい [[surrogate pair]] になっていない
[[surrogate code point]] を [[escape]] したものをそのまま解釈します。
[[Firefox]] は [CODE(char)[[[U+FFFD]]]] と解釈します。 [TIME[2011-10-29T02:22:29.900Z]]

[REFS[
- [40] 片方だけ [[escape]] な [[surrogate]] <http://software.hixie.ch/utilities/js/live-dom-viewer/?%3C!DOCTYPE%20html%3E%0D%0A%3Cstyle%3E%3C%2Fstyle%3E%0D%0A%0D%0A%3Cdiv%3Eaaaaaa%3C%2Fdiv%3E%0D%0A%0D%0A%3Cscript%3E%0D%0A%20%20var%20div%20%3D%20document.getElementsByTagName%20('div')%5B0%5D%3B%0D%0A%20%20div.className%20%3D%20'c'%20%2B%20String.fromCharCode%20(0xD800%2C%200xDC00)%20%2B%20'x'%3B%0D%0A%20%20%0D%0A%20%20var%20style%20%3D%20document.getElementsByTagName%20('style')%5B0%5D%3B%0D%0A%20%20style.textContent%20%3D%20'.c'%20%2B%20String.fromCharCode%20(0xD800)%20%2B%20'%5C%5CDC00x%20%7B%20color%3A%20blue%20%7D'%3B%0D%0A%3C%2Fscript%3E>
- [42] <http://software.hixie.ch/utilities/js/live-dom-viewer/?%3C!DOCTYPE%20html%3E%0A%3Cstyle%3E%3C%2Fstyle%3E%0A%0A%3Cdiv%3Eaaaaaa%3C%2Fdiv%3E%0A%0A%3Cscript%3E%0A%20%20var%20div%20%3D%20document.getElementsByTagName%20(%27div%27)%5B0%5D%3B%0A%20%20div.className%20%3D%20%27c%27%20%2B%20String.fromCharCode%20(0xD800%2C%200xFFFD)%20%2B%20%27x%27%3B%0A%20%20%0A%20%20var%20style%20%3D%20document.getElementsByTagName%20(%27style%27)%5B0%5D%3B%0A%20%20style.textContent%20%3D%20%27.c%27%20%2B%20String.fromCharCode%20(0xD800)%20%2B%20%27%5C%5CDC00x%20%7B%20color%3A%20blue%20%7D%27%3B%0A%3C%2Fscript%3E>
]REFS]

[41] [[Chrome]] と [[Opera]] は、片割れだけ [[escape]] された [[surrogate]]
はそのまま [[surrogate pair]] であるものと解釈します。
[[Firefox]] は解釈しません (>>42 は青くなり、 [[escape]] の方は [CODE(char)[[[U+FFFD]]]] とみなしています)。
[TIME[2011-10-29T03:18:06.00Z]]

** \ + 空白

[1]  [CODE(CSS)@en[[[IDENT]]]] 中、 [CODE(CSS)[[[\]]]] の直後に[[空白]]:
[REFS[
- [CODE(char)[[[U+0020]]]] <http://suika.suikawiki.org/gate/2007/cssom/viewer?c=di%5C%20v%20%7B%0D%0A%20%20color%3A%20blue%3B%0D%0A%7D;h=%3Cdiv%3Exxxxxx%3C%2Fdiv%3E;p=n;x=style-element>
- [CODE(char)[[[U+0009]]]] <http://suika.suikawiki.org/gate/2007/cssom/viewer?c=di%5C%09v%20%7B%0D%0A%20%20color%3A%20blue%3B%0D%0A%7D;h=%3Cdiv%3Exxxxxx%3C%2Fdiv%3E;p=n;x=style-element>
- [CODE(char)[[[U+000A]]]] <http://suika.suikawiki.org/gate/2007/cssom/viewer?c=di%5C%0Av%20%7B%0D%0A%20%20color%3A%20blue%3B%0D%0A%7D;h=%3Cdiv%3Exxxxxx%3C%2Fdiv%3E;p=n;x=style-element>
- [CODE(char)[[[U+000D]]]] <http://suika.suikawiki.org/gate/2007/cssom/viewer?c=di%5C%0Dv%20%7B%0D%0A%20%20color%3A%20blue%3B%0D%0A%7D;h=%3Cdiv%3Exxxxxx%3C%2Fdiv%3E;p=n;x=style-element>
- [CODE(char)[[[U+000D]]]] [CODE(char)[[[U+000A]]]] <http://suika.suikawiki.org/gate/2007/cssom/viewer?c=di%5C%0D%0Av%20%7B%0D%0A%20%20color%3A%20blue%3B%0D%0A%7D;h=%3Cdiv%3Exxxxxx%3C%2Fdiv%3E;p=n;x=style-element>
- [CODE(char)[[[U+000C]]]] <http://suika.suikawiki.org/gate/2007/cssom/viewer?c=di%5C%0Cv%0D%7B%0D%0A%20%20color%3A%20blue%3B%0D%0A%7D;h=%3Cdiv%3Exxxxxx%3C%2Fdiv%3E;p=n;x=style-element>
- [CODE(char)[[[U+00A0]]]] <http://suika.suikawiki.org/gate/2007/cssom/viewer?c=di%5C%C2%A0v%0D%7B%0D%0A%20%20color%3A%20blue%3B%0D%0A%7D;h=%3Cdiv%3Exxxxxx%3C%2Fdiv%3E;p=n;x=style-element>
- [CODE(char)[[[U+2000]]]] <http://suika.suikawiki.org/gate/2007/cssom/viewer?c=di%5C%E2%80%80v%0D%7B%0D%0A%20%20color%3A%20blue%3B%0D%0A%7D;h=%3Cdiv%3Exxxxxx%3C%2Fdiv%3E;p=n;x=style-element>
- [CODE(char)[[[U+3000]]]] <http://suika.suikawiki.org/gate/2007/cssom/viewer?c=di%5C%E3%80%80v%0D%7B%0D%0A%20%20color%3A%20blue%3B%0D%0A%7D;h=%3Cdiv%3Exxxxxx%3C%2Fdiv%3E;p=n;x=style-element>
- [CODE(char)[[[U+FEFF]]]] <http://suika.suikawiki.org/gate/2007/cssom/viewer?c=di%5C%EF%BB%BFv%0D%7B%0D%0A%20%20color%3A%20blue%3B%0D%0A%7D;h=%3Cdiv%3Exxxxxx%3C%2Fdiv%3E;p=n;x=style-element>
]REFS]

[2]
>>1 [[WinIE 6]] は [CODE(char)[[[\]]]] の後に[[空白]]があると、 [[escape]]
全体を無視するようです。

;; [CODE(char)[[[\]]]] の後が [CODE(char)[[[U+000D]]]] や 
[CODE(char)[[[U+000A]]]] の場合、[CODE(HTMLe)@en[[[textarea]]]] にいれた時点で
[CODE(char)[[[U+000D]]]] [CODE(char)[[[U+000A]]]] に[[正規化]]されてしまうので、
>>1 の方法では検証できないのですが・・・。

>>1 の [CODE(char)[[[U+000D]]]] [CODE(char)[[[U+000A]]]] の例は
[CODE(CSS example)[[[di]]]] ([[空白]]) [CODE(CSS example)[[[v]]]]
と解釈されているようです。

** \ + NULL

[3]
[CODE(CSS)@en[[[IDENT]]]] 中の
[CODE(char)[[[\]]]] の後に [CODE(char)[[[U+0000]]]]:
[REFS[
- <http://suika.suikawiki.org/gate/2007/cssom/viewer?c=di%5C%00v%20%7B%0D%0A%20%20color%3A%20blue%3B%0D%0A%7D;h=%3Cdiv%3Exxxxxx%3C%2Fdiv%3E;p=n;x=style-element>
]REFS]

[4]
>>3 [[WinIE 6]] では [CODE(HTMLe)@en[[[textarea]]]] に入れた時点 (or もっと前) で
[CODE(char)[[[U+0000]]]] 以下が捨てられてるみたいです。。。

[33] >>3 [[WinIE8]] と [[Opera]] は >>4 と同じでよくわかりません。 [[Chrome]] は[[非妥当]]とみなします。
[[Firefox]] は [CODE(char)[[[U+0000]]]] と解釈します。 [TIME[2011-10-29T01:51:17.600Z]]

** その他

[5]
[[WinIE 6]] では [CODE(char)[[[\]]]] の後に[[数字]]や[[空白]]以外があるときは
[CODE(char)[[[\]]]] を捨てるみたいです。

* 例

[EG[
[27] [CODE(CSS)[te\st]] は [CODE(CSS)[test]] と同じ意味の[[識別子]]です。
]EG]

[EG[
[28] [CODE[B&W?]] は直接[[識別子]]として書き表せませんが、
[CODE(CSS)[B\&W\?]] や [CODE(CSS)[B\26 W\3F]] のように表すことはできます。
]EG]

[43] [CITE@ja[SSEを使ってHTMLエスケープを高速化してみた - k0kubun's blog]]
([TIME[2016-08-15 11:20:20 +09:00]])
<http://k0kubun.hatenablog.com/entry/hescape>

[44] [CITE[Big Sky :: SSE を使わなくても HTML エスケープはある程度速くできる。]]
([TIME[2016-08-17 11:07:47 +09:00]])
<http://mattn.kaoriya.net/software/lang/c/20160817011915.htm>

[45] [CITE@en['''['''cssom''']''' Serialize U+0000 in string as U+FFFD, NOT escaped as code point]]
([[zcorpan]]著, [TIME[2017-03-16 18:32:19 +09:00]])
<https://github.com/w3c/csswg-drafts/commit/f8b1bcccbd543fae5eebc04730a7e647c197fa2e>