无效的CSS选择器导致规则被删除:什么是理由?

前端之家收集整理的这篇文章主要介绍了无效的CSS选择器导致规则被删除:什么是理由?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在寻找更多的链接邮件列表讨论等,而不是投机。

任何人都可以帮助我找出CSS Selectors Level 3规范中引用的错误处理规则背后的理由。

User agents must observe the rules for handling parsing errors:

  • a simple selector containing an undeclared namespace prefix is invalid
  • a selector containing an invalid simple selector,an invalid combinator or an invalid token is invalid.
  • a group of selectors containing an invalid selector is invalid.

Specifications reusing Selectors must define how to handle parsing errors. (In the case of CSS,the entire rule in which the selector is used is dropped.)

我有以下规则:

#menu li.last,#menu li:last-child {
  ...
}

为了补偿IE8缺少最后一个孩子的支持,我使用了一个类和一个JavaScript垫片。但是,由于IE8符合CSS规范的错误处理,因此无法识别一个选择器,因此无效。这可以通过将两个选择器分为单个规则来修复。

为什么这是可取的?为什么规范不建议简单地丢弃无法识别的选择器,但是保留其余的规则?

我想知道理由,因为这些规则目前似乎是反直觉的。

解决方法

Why is this desirable? Why doesn’t the spec suggest simply discarding the unrecognised selector,but keeping the rest of the rule?

简单的答案是因为实现过程难以确定什么是“剩余的规则”(或“剩余的选择器列表”),而不会错误,无意中弄乱了布局,以及错误处理的一致性,以及与未来规范的转发兼容性。

我将以连接another answer of mine的方式介绍我的长途答案,处理无效选择器。该答案的评论直接指向section 4.1.7 of the CSS2.1 spec处理规则集中的选择器中的错误,其中提到选择器中的逗号作为示例。我认为它很好地总结了:

CSS 2.1 gives a special meaning to the comma (,) in selectors. However,since it is not known if the comma may acquire other meanings in future updates of CSS,the whole statement should be ignored if there is an error anywhere in the selector,even though the rest of the selector may look reasonable in CSS 2.1.

虽然逗号本身仍然意味着将两个或多个选择器分组到选择器,但事实证明,选择器4引入了接受选择器组(或选择器列表)作为参数的新功能伪类,例如:matches()(甚至更改:not()所以它接受一个列表,使其类似于:matches(),而在3级,它只接受一个简单的选择器)。

这意味着不仅会找到与规则相关联的逗号分隔的选择器组,还可以在功能性伪类中找到它们(请注意,这仅在样式表中;在CSS之外,选择器可以出现在JavaScript代码,由选择器库和本机Selectors API使用)。

虽然不是迄今唯一的原因,但这只是一个足够的可能会使解析器的错误处理规则过度复杂化,而且可能会破坏选择器,规则集或布局。在使用逗号分析错误的情况下,解析器将无法确定此选择器组是否对应于整个规则集或另一个选择器组的一部分,以及如何相应地处理选择器的其余部分及其关联的规则集。而不是试图猜测,冒险猜测错误,并以某种方式违反规则(例如通过匹配和设计所有错误的元素),最安全的赌注是丢弃规则并继续前进。

例如,考虑以下规则,其选择器在级别4中有效但不在级别3中,取自this question of mine

#sectors > div:not(.alpha,.beta,.gamma) {
    color: #808080;
    background-color: #e9e9e9;
    opacity: 0.5;
}

不理解选择器4的朴素解析器可能会尝试将其分为三个不同的选择器,它们共享相同的声明块,而不是单个选择器,其中包含接受列表的伪类,仅基于逗号:

#sectors > div:not(.alpha
.beta
.gamma)

如果它简单地丢弃明显无效的第一个和最后一个选择器,离开第二个选择器是有效的,那么它是否应该将规则应用于具有类beta的任何元素?这显然不是作者打算做的,所以如果浏览器这样做,那将是do something unexpected to this layout.通过用无效选择器,the layout looks just a little saner丢弃规则,但这是一个过度简化的例子;具有布局更改样式的规则可能会导致更大的问题,如果应用错误

当然,选择器解析中的其他歧义也可能发生,这可能导致以下情况:

>不知道复选框结束的位置
>不知道选择器列表在哪里结束
>不知道声明块开始的位置
>上述的组合

所有这些,再次,通过放弃规则集而不是玩猜测游戏最容易解决

在没有被认可的看似格局良好的选择器的情况下,例如:在你的例子中,最后一个孩子作为伪类,这个规范没有区分不可识别的选择器和只是简单格式的选择器。两者都会导致解析错误。从您链接到的同一部分:

Invalidity is caused by a parsing error,e.g. an unrecognized token or a token which is not allowed at the current parsing point.

并且通过做出关于:last-child的声明,我假设浏览器首先解析一个冒号,然后是一个任意的ident作为伪类;实际上,你不能假设一个实现将知道解析:最后一个孩子作为一个伪类正确,或类似:lang()或:not()与功能符号,因为功能伪类没有出现直到CSS2。

选择器定义了一组特定的已知伪类和伪元素,它们的名称在每个实现中最有可能被硬编码。最朴素的解析器对于每个伪类和伪元素都有整个符号,包括单/双冒号,硬编码(如果主要浏览器实际上这样做,那么我不会感到惊讶:之前,之后: ,:第一个字母和第一行作为special case)。那么对于一个实现来说,似乎是一个伪类似乎可能会变成另外一个。

由于执行失败的方法有很多,因此规范没有区别,使错误处理更加可预测。如果选择器无法识别,无论是因为不支持还是格式不正确,都会丢弃该规则。简单,直接,容易,让你的头脑。

所有这一切,www风格的公共邮件列表中至少有one discussion表明规范被改变,因为可能不是很难通过拆分选择器来实现错误处理。

我还应该提到一些布局引擎的行为是不一样的,比如WebKit忽略规则中的非WebKit前缀选择器,应用自己的前缀,而其他浏览器完全忽略该规则(可以在Stack Overflow上找到更多示例,这里是a slightly different one) 。在某种程度上,您可以说WebKit正在围绕规则,尽管它尽可能地巧妙地解析逗号分隔的选择器组,尽管有这些前缀选择器。

我不认为工作组有一个引人注目的理由来改变这种行为。事实上,如果有什么,他们有一个令人信服的理由不改变它,这是因为网站已经依赖这种行为多年了。过去,我们使用了选择器黑客来过滤旧版本的IE;今天,我们为其他浏览器过滤了前缀选择器。这些黑客都依赖于某些浏览器丢弃他们无法识别的规则的相同行为,其他浏览器如果认为它们是正确的则应用它们。通过识别前缀(或仅将无法识别的引用,作为WebKit)。如果这个规则是要改变的,这些浏览器的版本可能会更新,这绝对不会像我们这样多元化(分散)的网页发生。

截至April 2013,由于上述原因,Telecon认为此行为保持不变:

   - RESOLVED: Do not adopt MQ-style invalidation for Selectors
               due to Web-compat concerns.

媒体查询式无效是指以逗号分隔的列表中的无效媒体查询,不会破坏整个@media规则。

原文链接:https://www.f2er.com/css/219210.html

猜你在找的CSS相关文章