简体   繁体   English

转义 CSS 类选择器中的字符

[英]Escaping characters in CSS class selectors

I'm trying to implementthis W3 description of character escapes in CSS class selectors.我正在尝试在 CSS 类选择器中实现字符转义的W3描述。

I'm running into problems with the abc\20 def syntax that puts a space after the escape sequence to ensure def is not misread as part of the character code.我遇到了abc\20 def语法的问题,该语法在转义序列后放置一个空格以确保def不会被误读为字符代码的一部分。

Specifically, trying to put abc\XY def into an HTML class attribute or into a command like jQuery().addClass('abc\\20 def') (the \\ here is part of the JS string literal syntax; the string value itself has one slash) will both give the element two classes, abc\20 and def .具体来说,尝试将abc\XY def放入 HTML 类属性或类似jQuery().addClass('abc\\20 def')的命令中(这里的\\是 JS 字符串文字语法的一部分;字符串值本身有一个斜杠)都会给元素两个类, abc\20def

Is this syntax just badly implemented, and I should stick with the six-digit leading zero form?这种语法是否实施得很糟糕,我应该坚持使用六位数前导零形式吗? Or does that document only refer to the escape format in CSS code, and the HTML attribute / jQuery argument require some different form of escaping the space character?或者该文档是否仅引用 CSS 代码中的转义格式,而 HTML 属性/jQuery 参数需要某种不同形式的转义空格字符?

Edit : Thank you very much for explaining, everyone!编辑:非常感谢大家的解释!

I now understand that this syntax only applies to CSS code - not the class names themselves as set in HTML attributes or Javascript.我现在明白这种语法只适用于 CSS 代码——不适用于 HTML 属性或 Javascript 中设置的类名本身。

This also means that characters designated as whitespace can't occur in CSS class values, and no kind of escape mechanism allows them to be added.这也意味着指定为空白的字符不能出现在 CSS 类值中,并且没有一种转义机制允许添加它们。 (Specifically, if I understand correctly, the CSS selector .abc\20 def is valid and selects elements with the class abc def , but is meaningless because no element can have this class.) (具体来说,如果我理解正确的话,CSS 选择器.abc\20 def是有效的并且选择具有类abc def的元素,但是没有意义因为没有元素可以有这个类。)

For my concrete use case, which involves mapping arbitrary values (which can have white space) to valid class names , I need to define my own escape scheme.对于涉及将任意值(可以有空格)映射到有效类名的具体用例,我需要定义自己的转义方案。 Replacing whitespace with - or _ (thanks Praveen) is one possibility;-_替换空格(感谢 Praveen)是一种可能性; if the mapping needs to be one-to-one, replacing them with six-digit Unicode hex values (eg. "abc def" -> "abc\000020def" is a more robust one.如果映射需要一对一,则将它们替换为六位 Unicode 十六进制值(例如, "abc def" -> "abc\000020def"是一种更可靠的方法。

The important thing to keep in mind is that this replacement affects the class name itself - to refer to the class abc\000020def in CSS, the backslash must be escaped again, to form the selector .abc\\000020def .要记住的重要一点是,这种替换会影响类名本身——要在 CSS 中引用类abc\000020def ,必须再次转义反斜杠,以形成选择器.abc\\000020def

Short answer: DOM parses whatever selector you pass to it as string.简短回答:DOM 将您传递给它的任何选择器解析为字符串。 If the (parsed by DOM) result contains spaces or non-breaking-spaces, they will count as class separators.如果(由 DOM 解析)结果包含空格或不间断空格,它们将算作类分隔符。


You shouldn't worry about jQuery, or any other ECMAScript misinterpreting the spaces meant for ending an escape block as a class delimiter.您不必担心 jQuery 或任何其他 ECMAScript 会将用于结束转义块的空格误解为类定界符。

Simply put, because they are not in charge of this matching .简单的说,因为他们不负责这个匹配 Document Object Model is.文档对象模型是。 The same DOM that interprets the escaped CSS classes.解释转义 CSS 类的相同 DOM。 So if an escaped class name works in your stylesheet, it will work as a selector if passed by any JavaScript library.因此,如果转义的类名在您的样式表中有效,那么如果通过任何 JavaScript 库传递,它将作为选择器使用。

On one condition: that it gets passed to DOM in a form that it understands.在一个条件下:它以它理解的形式传递给 DOM。 A form that works in CSS .一种适用于 CSS的表单

Now, let's assume that, for semantics reasons, you'd like to use the class 100% on an element.现在,假设出于语义原因,您希望100%地在元素上使用类。 You'll need to escape at least the first and last characters for your selector to work.您至少需要转义第一个和最后一个字符,您的选择器才能工作。 The ones in the middle may or may not be escaped.中间的可能会或可能不会被转义。 Possible selectors, all translating at DOM level to the 100% class name, would be:可能的选择器,全部在 DOM 级别转换为100%类名,将是:

  • .\31 00\25
  • .\31 0\30\25
  • .\31\30 0\25
  • .\31\30\30\25
  • .\31 \30 \30 \25

As you already know, there are more escaping CSS methods .如您所知,还有更多转义 CSS 方法 However, this applies to all.然而,这适用于所有人。

When you pass a selector to jQuery or JavaScript it will treat it as a string and pass it to the DOM parser.当您将选择器传递给 jQuery 或 JavaScript 时,它会将其视为字符串并将其传递给 DOM 解析器。 However, these libraries have their own escaping mechanisms, allowing us to do fancy stuff.然而,这些库有自己的转义机制,允许我们做一些奇特的事情。 So, to allow any of the above selectors to make it to the DOM parser you need to escape the backslashes, so they are not misinterpreted by JavaScript as escape characters and removed from string.因此,要允许上述任何选择器进入 DOM 解析器,您需要对反斜杠进行转义,这样它们就不会被 JavaScript 误解为转义字符并从字符串中删除。

Basically you need to double your backslashes.基本上你需要加倍你的反斜杠。 Any of the following will do:以下任何一项都可以:

  • .\\31 00\\25 , .\\31 00\\25 ,
  • .\\31 0\\30\\25 , .\\31 0\\30\\25 ,
  • .\\31\\30 0\\25
  • .\\31\\30\\30\\25
  • .\\31 \\30 \\30 \\25

Here's a snippet.这是一个片段。 Test it out.测试一下。 Add elements with class 0% and you will see they don't get selected.添加类0%的元素,您将看到它们未被选中。 Because the DOM parser will turn any of the above selectors into 100% and match them against the 100% class you have put to the element.因为 DOM 解析器会将上述任何选择器转换为100% ,并将它们与您放入元素的100%类进行匹配。

 $('.\\31\\30\\30\\25>div').on('click', function(){ var positions = ['first','second','third']; alert('You clicked the ' + positions[$(this).index()] + ' div.'); })
 .\31 0\30\25 > div{ padding: 20px; }.\31 00\25 > *:first-child { color: red; }.\31\30 0\25 > *:nth-child(2) { color: blue; }.\31\30\30\25 > *:last-child { color: green; }
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="100%"> <div>first</div> <div>second</div> <div>third</div> </div>


Getting back to your example ( abc\\20 def ) it will parse and behave exactly like abc def .回到您的示例( abc\\20 def ),它将解析并表现得与abc def完全一样。 Spaces , when present in the final result of the class name string, will be interpreted as class delimiters .空格,当出现在类名字符串的最终结果中时,将被解释为类分隔符 This goes for both \x20 and \xa0 (space and non-breaking-space) and it is the expected behaviour.这适用于\x20\xa0 (空格和不间断空格),这是预期的行为。

As an interesting (trivial) note, if for some evil reason you wanted to make it hard for people to style up your app, you could always add a command type character to a class name.作为一个有趣的(微不足道的)说明,如果出于某种邪恶的原因你想让人们很难设计你的应用程序,你总是可以在类名中添加一个command类型字符。 Here's an example:这是一个例子:

 $('.space').removeClass('\x73\x70\x61\x63\x65').addClass('\x1a\x73\x70\x61\x63\x65');
 .space { color: red; }
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="space"> inspect me, i should be red! </div>

You are getting confused between the class name as present in the DOM, and the escaped version required in CSS.您对 DOM 中存在的类名和 CSS 中所需的转义版本感到困惑。 The class name is just specified as is:类名只是按原样指定:

elt.classList.add('foo:bar')

It is when this is referenced in a CSS file (or other CSS selector context, such as querySelector ) that it must be escaped:当它在 CSS 文件(或其他 CSS 选择器上下文,例如querySelector )中被引用时,它必须被转义:

.foo\:bar { color: red; }

The same applies to the case where you choose to use a numeric escape:这同样适用于您选择使用数字转义的情况:

elt.classList.add('1234');

.\31 234 { color: red; }

However, no amount of escaping will permit you to have spaces in class names.但是,再多的转义也不允许您在类名中包含空格。 Spaces are absolutely reserved for delimiting multiple class names on the DOM className attribute.空格绝对保留用于分隔 DOM className属性上的多个类名。

I think you can use class="abc&amp;#x0020;def" to solve that problem我想你可以使用class="abc&amp;#x0020;def"来解决这个问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM