为什么不能将供应商特定的伪元素/类组合成一个规则集?

81

在CSS中,可以使用供应商特定的伪类和伪元素(以获得最佳跨浏览器覆盖范围)来样式化输入框内的placeholder文本。

这些都共享相同的基本属性(即文本样式和颜色声明)。

然而,虽然我希望无论浏览器供应商如何都能应用相同的样式,但似乎不可能将它们组合成逗号分隔的选择器(就像您想要两个选择器共享相同样式的任何其他CSS一样)。

例如,我倾向于使用以下四个选择器来定位占位符样式:

  • input:-moz-placeholder
  • input::-moz-placeholder
  • input:-ms-input-placeholder
  • input::-webkit-input-placeholder

(尽管:-moz-placeholder正在被弃用,取而代之的是::-moz-placeholder,但这仅发生在FireFox 19发布时,因此目前需要两者以获得更好的浏览器支持。)

很让人沮丧的是,为每个元素声明并赋予相同的样式会导致CSS中出现大量重复。
因此,为了确保占位文本右对齐和斜体,我最终会得到以下代码:
input:-moz-placeholder{
    font-style: italic;
    text-align: right;
}
input::-moz-placeholder{
    font-style: italic;
    text-align: right;
}
input:-ms-input-placeholder{
    font-style: italic;
    text-align: right;
}
input::-webkit-input-placeholder{
    font-style: italic;
    text-align: right;
}

我真正想做的是将它们合并为一个逗号分隔的规则集,如下所示:
input:-moz-placeholder,
input::-moz-placeholder,
input:-ms-input-placeholder,
input::-webkit-input-placeholder{
    font-style: italic;
    text-align: right;
}

然而,尽管我尝试了很多次,这似乎从未奏效。这让我担心自己可能没有理解CSS的一些基本部分。有人能解释为什么会发生这种情况吗?
2个回答

79

CSS2.1规定

选择器(也可以参见选择器部分)包括左花括号({)之前的所有内容。选择器总是与声明块一起使用。当用户代理无法解析选择器(即它不是有效的CSS 2.1),它必须忽略选择器和随后的声明块(如果有)。

请注意,由于CSS2.1早于CSS3,"它不是有效的CSS 2.1"是在假设用户代理完全符合CSS2.1标准且理论上不存在CSS3的情况下编写的。实际上,无论规范何时说"它不是有效的CSS"或类似的话,都应该理解为"用户代理无法理解它"。请参阅我在此相关问题中的答案,了解更详细的说明。

换句话说,由于一个供应商的浏览器无法理解其他供应商的前缀,它必须放弃任何包含伪类和伪元素选择器中未识别前缀的规则。1

有关为什么会制定这样的规则的一些见解,请参见此答案


1 注意,WebKit因部分违反此规则而声名狼藉:它可以轻松解析具有未经认可的前缀伪元素(在本例中为::-moz-placeholder)的选择器规则。尽管如此,你的组合规则中的:-moz-placeholder伪类将导致其出错。


非常感谢,讲解得非常透彻,很有道理。但仍然相当令人沮丧!供您参考的是::-moz-placeholder 伪类最近才被弃用(请参见 https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-placeholder),随着 FireFox 19 的推出,所以目前必须同时使用 :-moz-placeholder 和它的双冒号继承者 ::-moz-placeholder,以确保最佳的浏览器覆盖率。 - johnkavanagh
回复:脚注1,Firefox 106也部分违反了这个规则。它会忽略多个选择器列表中的带前缀的伪元素,例如input::-webkit-search-cancel-button,并继续应用样式,但是如果加入一个伪类,例如input::-webkit-search-cancel-button:hover,那么它就跳过整个声明。真是疯狂! - jdunning
@jdunning:是的,我不知道那里发生了什么。如果我没记错的话,他们为了兼容性放宽了一些规则(请参见兼容性规范),但我不记得具体细节,也不知道为什么Firefox似乎与其他浏览器略有不同。 - BoltClock

15
规范规定,如果用户代理无法识别选择器的一部分,则必须忽略整个选择器及其块。选择器由左花括号({)之前的所有内容组成(不包括左花括号)。选择器始终与 {} 块一起使用。当用户代理无法解析选择器时(即它不是有效的 CSS3),它还必须忽略 {} 块。 http://www.w3.org/TR/css3-syntax/#rule-sets

这里的链接对我没用(没有引用到相关文本);我找到了这个:http://www.w3.org/TR/selectors/#Conformance。在我看来,解析像 input:-moz-placeholder,:-any-other-bogus-selector 这样的选择器列表应该没有问题,所以这条规则应该能够工作,而放弃它的浏览器则违反了规则。 - Tobias

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接