您可能知道这一点:如果选择器的任何部分无效,则会使整个选择器无效。例如
div, span::butt {
background: red;
}
即使 div
是一个完全有效的选择器,span:butt
却不是,因此整个选择器被视为无效 - 页面上的 div 或 span::butt
元素都不会拥有红色背景。
通常情况下,这不是一个特别大的问题。根据具体情况,它甚至可能很有用。但也有很多情况会让人感到头疼,比如,嗯,:butt
。
这是一个经典例子
::selection {
background: lightblue;
}
很长一段时间以来,Firefox 都不识别该选择器,需要使用供应商前缀 (::-moz-selection
) 来实现相同的效果。(在 Firefox 62+ 中 这种情况不再存在,但你明白我的意思了。)
换句话说,这是不可能的
/* would break for everyone */
::selection, ::-moz-selection {
background: lightblue;
}
这会使能够识别 ::selection
的浏览器出现错误,同时也会使仅识别 ::-moz-selection
的 Firefox 出现错误。这无疑为预处理器 @mixin
提供了一个理想的应用场景。
这里还有一个例子。
/* For navigation with submenus */
ul.submenu {
display: none;
}
ul.menu li:hover ul.submenu,
ul.menu li:focus ul.submenu,
ul.menu li:focus-within ul.submenu {
display: block;
}
/* Oh no! We've broken all menu functionality in IE 11,
because it doesn't know what `:focus-within` is so it
throws out the entire selector */
这种行为非常令人讨厌,以至于浏览器已经开始对此进行修复。在与 Estelle Weyl 的交谈中,我了解到正在进行更改。她在 MDN 文档 中写道
通常情况下,如果选择器链或组中存在无效的伪元素或伪类,则整个选择器列表将无效。如果伪元素(但不是伪类)具有
-webkit-
前缀,截至 Firefox 63,Blink、Webkit 和 Gecko 浏览器将假定它是有效的,不会使选择器列表无效。
这并非适用于所有选择器,而是专门针对伪元素。也就是说,双冒号 (::
)。
这是一个测试
我认为这是一个积极的改变。
我正在收听 Shoptalk 的 Google Podcasts,你提到了这个主题;不久之后,Google 助理推荐了这篇文章。非常有用,但也很可怕。
好消息!
我最近在使用 :focus-within 时遇到过这个问题。在现代浏览器中可以正常工作,因为它得到支持,但在旧版浏览器(IE 又来了!)中会失效!修复起来并不难,但确实很烦人。希望他们能更改它,让浏览器忽略无效的选择器,而不是导致失效。:/
几个月前我在 Firefox 上遇到了类似的问题。它曾经将带有 ::webkit- 前缀的选择器视为无效,从而忽略了整个选择器及其包含的规则。当使用 Autoprefixer 等工具为您应用前缀并导致 Firefox 上的样式失效时,这尤其令人讨厌。
(顺便说一句,他们在解决这个问题方面做得很好,因为我在他们的 Bugzilla 上报告了这个问题,我认为它已在浏览器的 63 版本中修复。)
可能值得注意的是,这并非适用于所有伪元素(至少现在还没有),它只适用于带有
-webkit
前缀的伪元素。这是为了 兼容性原因,因为基于 WebKit 和 Blink 的浏览器一直以这种方式处理这些伪元素,并且许多网站依赖于这种行为。有一个 提案 想要颠覆这条规则,将所有伪元素(甚至可能包括伪类)都视为潜在的有效选择器,除了那些经常用于浏览器选择器技巧的选择器。但这个提案似乎没有获得足够的重视……