简体   繁体   English

CSS 选择器中允许的注释语法

[英]Allowed syntax of comments within CSS selectors

In CSS, often it improves code readability to not wrap long lines, but instead ensure all lines fit horizontally within the code editor's viewport.在 CSS 中,它通常会提高代码可读性,而不是将长行换行,而是确保所有行在代码编辑器的视口中水平放置。

But whitespace is very significant in CSS, often making this goal challenging.但是空白在 CSS 中非常重要,常常使这个目标具有挑战性。

Thus, sometimes embedding a comment within a long CSS selector (in a CSS ruleset) is a reasonable choice.因此,有时在长 CSS 选择器(在 CSS 规则集中)中嵌入注释是一个合理的选择。

I have found that selectors like:我发现选择器像:

div./*  
 */class

work reliably, but selectors like:工作可靠,但选择器如:

div/*  
 */.class

are less supported.支持较少。 At least, I'm getting an error in Stylish when using CSS Lint with this one.至少,我在使用 CSS Lint 时遇到了 Stylish 错误。

Are either (or both) of these technically valid, and if so, where in the RFC is this indicated?这些中的任何一个(或两者)在技术上是否有效,如果是,在 RFC 中的何处指出?

Before I answer your question, I want to assure you that whitespace is not as much of a problem in CSS selectors as you may think, and that it is actually insignificant most of the time.在我回答你的问题之前,我想向你保证,在 CSS 选择器中,空白并不像你想象的那么严重,而且在大多数情况下它实际上是无关紧要的。 There are very few places where it is and only one of them you encounter in everyday use: descendant combinators.它存在的地方很少,在日常使用中只会遇到其中一个:后代组合器。 And even then you can still use a line break in place of a space and it'll still be parsed as a descendant combinator.即便如此,您仍然可以使用换行符代替空格,它仍然会被解析为后代组合器。 There's only one situation I can think of and that is if the identifiers (class, ID, attribute, etc) in your compound selectors are getting too long, and you want to break up your compound selectors.我只能想到一种情况,那就是如果复合选择器中的标识符(类、ID、属性等)变得太长,而您想要拆分复合选择器。 That's probably a sign of issues out of your control though, so I won't judge.不过,这可能是您无法控制的问题的迹象,所以我不会判断。 Now let's get to your question.现在让我们来回答你的问题。

These specific examples aren't documented in the spec.这些特定示例未记录在规范中。 To answer your question upfront: they are both valid.预先回答您的问题:它们都是有效的。 To understand why, you'll need to understand how tokenization works in CSS, which is covered in a specification called css-syntax .要理解其中的原因,您需要了解标记化在 CSS 中的工作原理,该规范​​包含在名为css-syntax的规范中。 Thankfully, one crucial thing CSS has in common with many other languages whose comments have start and end delimiters, is that if a comment is sitting cleanly between two distinct tokens and neither is being broken up, then those two tokens will parse exactly the same as if the comment wasn't there.值得庆幸的是,CSS 与许多其他具有开始和结束分隔符的语言的共同点是,如果注释完全位于两个不同的标记之间并且都没有被分解,那么这两个标记的解析将完全相同如果评论不在那里。

But how CSS is tokenized can be a bit of a surprise.但是 CSS 是如何被标记化的可能有点令人惊讶。 One might assume that a class selector such as .class would be considered a single token, based on the Selectors grammar , and therefore a comment anywhere within it would break it and cause a parse error:根据Selectors 语法,人们可能会假设诸如.class类的类选择器将被视为单个标记,因此其中任何位置的注释都会破坏它并导致解析错误:

<class-selector> = '.' <ident-token>

However, <class-selector> is a production , that consists of two tokens: the dot which is considered a <delim-token> , followed by an <ident-token> .但是, <class-selector>是一个产生式,它由两个标记组成:被认为是<delim-token> ,后跟一个<ident-token> Since the dot exists as a separate token from the ident that would form the class name, a comment may exist cleanly between both tokens ( ./**/class ) while still allowing this to be parsed as a valid class selector.由于点作为与构成类名的 ident 分开的标记存在,因此注释可能会在两个标记 ( ./**/class ) 之间干净地存在,同时仍允许将其解析为有效的类选择器。

This applies to class selectors, pseudo-classes ( :nth-child() ) and pseudo-elements ( ::first-letter ).这适用于类选择器、伪类( :nth-child() )和伪元素( ::first-letter )。 However it does not apply to ID selectors because an ID selector is actually a single <hash-token> (think hex color values), a comment cannot appear before a ( because reasons , nor can it appear next to a hyphen within an ident because it's part of the ident.但是它不适用于 ID 选择器,因为 ID 选择器实际上是一个<hash-token> (想想十六进制颜色值),注释不能出现在 a (因为原因,也不能出现在 ident 中的连字符旁边,因为它是身份的一部分。

Having said that, a comment sitting between two characters doesn't cause a parse error right away if the resulting two tokens can still parse.话虽如此,如果生成的两个标记仍然可以解析,则位于两个字符之间的注释不会立即导致解析错误。 But context matters.但上下文很重要。 Here's an example:下面是一个例子:

.cla/**/ss

This gets parsed into the following tokens:这被解析为以下标记:

  1. <delim-token> '.'
  2. <ident-token> 'cla'
  3. <comment-token> (empty) <comment-token> (空)
  4. <ident-token> 'ss'

This isn't an error in and of itself, because if we forget the dot for a moment then we really just have two idents with a comment between them, and such cases are valid CSS anywhere you may have two or more idents otherwise separated by whitespace, like border: thin/**/dashed being equivalent to border: thin dashed .这本身并不是一个错误,因为如果我们暂时忘记点,那么我们实际上只有两个标识符,它们之间有一个注释,并且这种情况在任何可能有两个或多个标识符的地方都是有效的 CSS,否则由空白,如border: thin/**/dashed等价于border: thin dashed

But this becomes an error in Selectors because the Selectors grammar doesn't allow two consecutive idents in that context (there's a limited number of places where it's allowed such as unquoted attribute selectors with an i / s flag).但这在 Selectors 中成为一个错误,因为Selectors 语法不允许在该上下文中出现两个连续的 idents(允许的地方数量有限,例如带有i / s标志的未加引号的属性选择器)。

As for div/**/.class , since div and .class are two distinct productions (a <type-selector> followed by a <class-selector> ), a comment sitting cleanly between them won't have any effect on parsing, so this'll still be parsed as a compound selector without a descendant combinator.至于div/**/.class ,由于div.class是两个不同的产生式(一个<type-selector>后跟一个<class-selector> ),它们之间的注释不会对解析产生任何影响,所以这仍然会被解析为没有后代组合器的复合选择器。

The only browsers that I know have trouble parsing selectors with comments inside them are IE8 and older.我所知道的唯一在解析带有注释的选择器时遇到问题的浏览器是 IE8 及更早版本。 This fact has been exploited over the years to produce reliable selector hacks.多年来,这一事实已被利用来产生可靠的选择器黑客。 If you really have to use comments to hide line breaks that would otherwise break your selectors (because you've run out of places you could substitute regular line breaks), I'd recommend using them to separate entire simple selectors rather than delimiters from names because it's a little bit more readable that way.如果您真的必须使用注释来隐藏换行符,否则会破坏您的选择器(因为您已经用完了可以替换常规换行符的位置),我建议使用它们来分隔整个简单的选择器而不是分隔符与名称因为它是一个有点更具可读性的方式。 Nevertheless, the Selectors level 4 spec helpfully provides a list of places where whitespace isn't allowed within a selector and you can therefore substitute a comment in a way CSS Lint has evidently failed to account for:然而,选择器级别 4 规范提供了一个列表,其中列出了选择器中不允许使用空格的位置,因此您可以用 CSS Lint 显然无法解释的方式替换注释:

White space is forbidden:空白是被禁止的:

  • Between any of the top-level components of a <compound-selector> (that is, forbidden between the <type-selector> and <subclass-selector> , or between the <subclass-selector> and <pseudo-element-selector> , etc). <compound-selector>任何顶级组件之间(即,禁止在<type-selector><subclass-selector>之间,或在<subclass-selector><pseudo-element-selector> , 等等)。
  • Between any of the components of a <type-selector> or a <class-selector> .<type-selector><class-selector>任何组件之间。
  • Between the ':'s, or between the ':' and <ident-token> or <function-token> , of a <pseudo-element-selector> or a <pseudo-class-selector> . <pseudo-element-selector><pseudo-class-selector>的 ':' 之间,或 ':' 和<ident-token><function-token> <pseudo-class-selector>
  • Between any of the components of a <wq-name> .<wq-name>任何组件之间。
  • Between the components of an <attr-matcher> .<attr-matcher>的组件之间。
  • Between the components of a <combinator> .<combinator>的组件之间。

Note that whitespace (and therefore line breaks) is allowed in most parts of an attribute selector , so the use of comments is unnecessary.请注意, 在属性选择器的大多数部分都允许使用空格(因此换行) ,因此不需要使用注释。 Note also that the one exception to this list is <attr-matcher> , which appears to be a single token rather than two <delim-token> s.另请注意,此列表的一个例外是<attr-matcher> ,它似乎是单个标记而不是两个<delim-token> I can't find this documented anywhere.我在任何地方都找不到这方面的记录。

Again, I really can't imagine having to do this, but hey, at least you learned something about CSS tokenization, right?再说一次,我真的无法想象必须这样做,但是嘿,至少你学到了一些关于 CSS 标记化的知识,对吧?

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

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