原文:CSS character escape sequences
做者:Mathias 發表時間:12th July 2010
譯者:西樓聽雨 發表時間: 2018/11/5 (轉載請註明出處)javascript
There are some other cases where you might want or need to escape a character in CSS. You could be writing a selector for a funky id
, class
, attribute or attribute value, for example; or maybe you want to insert some weird characters using the content
property without changing your CSS file’s character encoding.css
當爲一些 class 或 id 屬性值比較奇怪的標籤 編寫 CSS 樣式時,咱們須要考慮到一些限制。例如:不能直接使用 ## { color: #foo; }
來匹配到 id="#"
這樣的元素;而是應該將這些怪異的字符進行轉義(這個例子中,指第二個「#」),這樣作就能夠消除標識符中包含的特殊 CSS 字符的涵義,還能夠引用到不能簡單敲出來的字符,如使人抓狂的 Unicode 符號。html
還有一些其餘狀況你可能或須要在 CSS 中使用轉義來對一個字符進行轉義。舉個例子:你可能會爲一個有趣的 id 、class、屬性或屬性值寫一個選擇器;或者你想要在不改變 CSS 文件的字符編碼的條件下使用 content
屬性表達式來插入一個奇怪的字符。html5
The grammar for identifiers is used for various things throughout the specification, including element names, class names, and IDs in selectors.java
The spec definition for strings says that strings can either be written with double quotes or with single quotes. Double quotes cannot occur inside double quotes, unless escaped (e.g., as '\"'
or as '\22'
). The same goes for single quotes (e.g., "\'"
or "\27"
). A string cannot directly contain a newline. To include a newline in a string, use an escape sequence representing the line feed character (U+000A), such as "\A"
or "\00000a"
. Newlines can also be represented as "\D \A "
(CRLF), "\D "
(i.e. \r
in other languages), or "\C "
(i.e. \f
in other languages). It’s possible to break strings over several lines, for aesthetic or other reasons, but in such a case the newline itself has to be escaped with a backslash (\
).git
As you can see, character escapes are allowed in both identifiers and strings. So, let’s find out how these escape sequences work!github
CSS 語法規範中用 token 圖定義了標識符:能夠包含 a 到 z 、A 到 Z、0 到 九、下劃線、鏈接符、非 ASCII 字符及針對任何字符的轉義序列;但不能以數字符號或者鏈接符號緊接一個數字符號開頭;且標識符至少包含一個字符(即空字符是不正確的標識符)。web
標識符的語法被這個規範的許多地方所引用,包括元素名稱,class 名稱,選擇器中的 id。api
對於字符串的定義,這個規範講到:能夠用雙引號或者單引號來表達,但雙引號不能出如今雙引號內,除非對其進行轉義(例如,'\"'
或'\22'
);同理,單引號也同樣;字符串不能直接包含換行,須要使用轉義序列來表示換行符(U+000A),如 「\A」 或 「\00000a」 ;換行也能夠用 「\D \A」 (CRLF) 、「\D 」(即其餘語言中的 "\r")或 「\C 」(即其餘語言中的 「\f」)來表示;爲了美觀或其餘緣由的須要,字符串能夠拆分爲幾行,但須要用反斜槓(\
)對換行符自己進行轉義。瀏覽器
如今咱們知道,字符的轉義在標識符和字符串中都支持,因此,下面咱們來看一下這些轉義序列是如何用的。
在 CSS 中對一個字符進行轉義時,你應該記住下文中的這些規則。若是對一個 class 或 id 寫一個選擇器,須要對其使用嚴格語法;若是要在 CSS 中使用字符串(包含引號),你只須要對引號和換行符進行轉義。
If the first character of an identifier is numeric, you’ll need to escape it based on its Unicode code point. For example, the code point for the character 1
is U+0031
, so you would escape it as \000031
or \31
.
Basically, to escape any numeric character, just prefix it with \3
and append a space character (). Yay Unicode!
若是一個標識符的第一個字符是數字時,須要用其 Unicode 碼來進行轉義。例如,1
的 Unicode 代碼點爲 U+0031
,那麼就用 \000031
或者 \31
來轉義。
基本上,全部數字字符的轉義,都只須要在其以前附加 \3
及以後附加空格便可。
The following characters have a special meaning in CSS: !
, "
, #
, $
, %
, &
, '
, (
, )
, *
, +
, ,
, -
, .
, /
, :
, ;
, <
, =
, >
, ?
, @
, [
, \
, ]
, ^
, ```, {
, |
, }
, and ~
.
There are two options if you want to use them. Either you use the Unicode code point — for example, the plus sign (+
) is U+002B, so if you would want to use it in a CSS selector, you would escape it into \2b
(note the space character at the end) or \00002b
(using exactly six hexadecimal digits).
The second option is far more elegant though: just escape the character using a backslash (\
), e.g. +
would escape into \+
.
Theoretically, the :
character can be escaped as \:
, but IE < 8 doesn’t recognize that escape sequence correctly. A workaround is to use \3A
instead.
任何不是 16 進制的數字 (即 0到9 和 a-f ——譯註)、換行、回車、換頁的字符均可以經過反斜槓來消除它的特殊含義。
後面這些字符在 CSS 中是有特殊含義的:!
, "
, #
, $
, %
, &
, '
, (
, )
, *
, +
, ,
, -
, .
, /
, :
, ;
, <
, =
, >
, ?
, @
, [
, \
, ]
, ^
, `
, ,
, {
, |
, }
, and ~
。
若是你想使用這些字符,有兩種選擇:第一種,使用 Unicode 代碼點,例如,加號 (+
) 的代碼點是 U+002B,則使用 \2b
(注意結尾處的空格)或者 \00002b
(使用完整的 6 位16進制數字)來轉義。第二種則比較優雅一點,只需使用反斜槓 (\
) 便可,例如,+
使用 \+
轉義。
理論上,:
可使用 \:
來轉義,但 IE8 如下版本不能正確地識別出這個轉義序列,一個解決方案是轉而使用 \3A
。
Whitespace — even some characters that are technically invalid in HTML attribute values — can be escaped as well.
Any characters matching [\t\n\v\f\r]
need to be escaped based on their Unicode code points. The space character () can simply be backslashed (
\
). Other whitespace characters don’t need to be escaped.
空白字符——雖然有些字符從技術上講,在 HTML 屬性值裏是錯誤——也可使用轉義。
可以匹配 [\t\n\v\f\r]
的字符都須要根據 Unicode 碼來進行轉義;空格字符 () 僅需用反斜槓進行轉義(
"\ "
);其餘空白字符則不須要轉義。
CSS doesn’t require you to escape underscores (_
) but if it appears at the start of an identifier, I’d recommend doing it anyway to prevent IE6 from ignoring the rule altogether.
CSS 對下劃線 (_
) 沒有轉義要求,但若是是出如今標識符的開頭的話,我仍是建議必定要作一下轉義,以此避免 IE6 把總體樣式規則都忽略。
In theory (as per the spec), any character can be escaped based on its Unicode code point as explained above (e.g. for 𝌆
, the U+1D306 「tetragram for centre」 symbol: \1d306
or \01d306
), but older WebKit browsers don’t support this syntax for characters outside the BMP (fixed in April 2012).
Because of browser bugs, there is another (non-standard) way to escape these characters, namely by breaking them up in UTF-16 code units (e.g. \d834\df06
), but this syntax (rightfully) isn’t supported in Gecko andOpera 12.
Since there is currently no way to escape non-BMP symbols in a cross-browser fashion without breaking backwards compatibility with older browsers, it’s best to just use these characters unescaped.
除了上面說的這些字符外,其餘沒有任何含義的字符均可以也應該保持不轉義。
從規則上講,全部字符均可以用其 Unicode 代碼點來進行轉義——就像上面提到的那樣。(例如:四橫線𝌆
的代碼點爲 U+1D306,能夠用 \1d306
或者 \01d306
來轉義),但老的 Webkit 瀏覽器對於不在 BMP 平面(BMP 是 Unicode 規範所劃分的一種字符平面,包含最經常使用的字符。每一個平面都有 65536 即 2 的 16 次方個字符。——譯註)以內的字符是不支持這種轉義的](older WebKit browsers don’t support this syntax for characters outside the BMP。(2012年4月已修復)
由於瀏覽器存在的 bug,還有另一種方式(非標準方式)來對這些 BMP 以外的字符進行轉義,即,將他們的 UTF-16 的代碼點拆分開(如:\d834\df06),但這種語法不被 Gecko 和 Opera 12 所支持。
因爲目前沒有任何一種跨瀏覽器兼容的方式來對非 BMP 平面的字符進行轉義,因此最好就是不要對其進行轉義。
The space character following a hexadecimal escape sequence can only be omitted if the next character is not another space character and not a hexadecimal digit. For example, foo©bar
becomes foo\A9 bar
, but foo©qux
could be written as foo\A9qux
.
緊接在十六進制轉義序列以後的空格字符(U+0020)都會自動被視爲這個轉義序列的一部分。例如,對文本foo © bar
進行轉義,須要使用 foo \A9 bar
來完成,其中 \A9
以後須要用到兩個空格,第一個空格會被吸取掉,只有第二個空格纔會被保留。
緊接在十六進制轉義序列以後的空格字符只有在其下一個字符不是空格字符且不是十六進制的數字字符的狀況下,才能夠省略。例如,foo©bar
對應 foo\A9 bar
,而 foo©qux
則能夠寫成 foo\A9qux
。
下面用一些隨便舉的例子來進行演示:
.\3A \`\( { } /* 匹配 class=":`(" 的元素 */
.\31 a2b3c { } /* 匹配 class="1a2b3c" 的元素 */
#\#fake-id {} /* 匹配 id="#fake-id" 的元素 */
#-a-b-c- {} /* 匹配 id="-a-b-c-" 的元素 */
#© { } /* 匹配 id="©" 的元素*/
複製代碼
查看更多,請點擊爲這篇貼文 (HMTL5 中的 @id 和 @class) 寫的 demo 頁面。
document.getElementById()
and similar functions like document.getElementsByClassName()
can just use the unescaped attribute value, the way it’s used in the HTML. Of course, you would have to escape any quotes so that you still end up with a valid JavaScript string.
On the other hand, if you were to use these selectors with the Selectors API (i.e. document.querySelector()
and document.querySelectorAll()
) or libraries that rely on the same syntax (e.g. jQuery/Sizzle), you would have to take the escaped CSS selectors and escape them again. All you really have to do is double every backslash in the CSS selector (and of course escape the quotes, where necessary):
對於 JavaScript 來講,要看狀況來。
document.getElementById()
及相似的方法,如 document.getElementsByClassName()
直接使用未經轉義以前的屬性值便可 (指 HMTL 中所使用的那種轉義方式) 。固然,對於引號來講你仍然還須要進行轉義,以確保字符串語法正確。
而若是你使用的 Selectors API (即 document.querySelector() 和 document.querySelectorAll() ) 或者使用的是依賴一樣語法的庫時,你必須使用轉義後的 CSS 選擇器,而後再進行轉義——你所須要作的就是把每一個反斜線加倍(若是有須要的話,固然也包括引號的轉義)。
<!-- HTML -->
<p class=":`("></p>
複製代碼
/* CSS */
.\3A \`\( { }
複製代碼
/* JavaScript */
document.getElementsByClassName(':`(');
document.querySelectorAll('.\\3A \\`\\(');
複製代碼
Remembering all these rules sure sounds like fun, but to make life a little easier I created a simple CSS escaper tool that does all the hard work for you.
這些規則確實比較有趣,但爲了讓事情更簡單,我製做了[一個簡單地 CSS 轉義工具,它能夠幫你完成這些複雜的工做](a simple CSS escaper tool that does all the hard work for you)。
Need to escape text for use in CSS strings or identifiers? I’ve packaged the code that powers this tool as an open-source JavaScript library named cssesc. Check it out!
只需(在高亮的位置——譯註)輸入一個值,它就會告訴你如何基於以上所述規則在 CSS 和 JavaScript 中進行轉義。雖然這裏使用的是 id
屬性,但其實你也把獲取到的轉義後的字符串用於 class
屬性值及 content
屬性。請享用!
沒有在 CSS 中對字符串或標識符進行轉義的需求?我把支撐這個工具的代碼打包成了一個開源的 JavaScript 庫,名字叫作 cssesc,請查看!
更新: CSS 對象模型規範如今已經定義了一個 CSS.escape()` 方法,該方法能夠用來執行轉義。我製做了一個它的墊片庫。