一个无效的伪选择器会导致整个选择器被忽略

Avatar of Chris Coyier
Chris Coyier 发布

DigitalOcean 为您的旅程的每个阶段提供云产品。立即开始使用 价值 200 美元的免费信用额度!

您可能知道这一点:如果选择器的任何部分无效,则会使整个选择器无效。例如

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 浏览器将假定它是有效的,不会使选择器列表无效。

这并非适用于所有选择器,而是专门针对伪元素。也就是说,双冒号 (::)。

这是一个测试

我认为这是一个积极的改变。