【问题标题】:Interaction of pseudo-elements with :not pseudo-class伪元素与 :not 伪类的交互
【发布时间】:2015-11-03 02:05:33
【问题描述】:

短版:

使用 Chrome,我注意到选择器

#main-content p:first-of-type::first-letter:not(.subhead) { ... }

无论段落的类别如何,似乎都无法应用首字母样式,但是如果我将 :not 伪类放在前面,就像在任何一个中一样

#main-content p:first-of-type:not(.subhead)::first-letter { ... }
#main-content p:not(.subhead):first-of-type::first-letter { ... }

然后它会按我的预期工作。这是 Chrome 中的问题,还是 CSS 选择器的某些方面解释了这一点,我只是不明白?

(另外,如果这不仅仅是 Chrome 中的问题,有人可以为这个问题建议一个更好的标题吗?)


长版:

简短的版本似乎是一个很好的独立问题,但有一些更复杂的背景信息可能有其有趣的后果。 (这可能需要它自己单独的问题,或者是另一个错误。非常感谢帮助???)

最初我试图将初始首字母下沉应用于 div 中的第一段以及紧随水平规则的任何后续段落,除非它们是副标题的一部分。这是页面结构的高度缩写模拟:

<div id="main-content">
<section class="panel">
  <header>
    <h1>Welcome Friend!</h1>
    <p class="subhead">This is a subheader! (0)</p>
  </header>
  <div class="customhr"></div> <!-- consciously NOT an hr tag -->
  <p>Here's a paragraph (1)</p>
  <hr>
  <p>First paragraph of a new content section (2)</p>
  <p>And another paragraph. (3)</p>
</section>
</div>

还有极其缩写的 CSS:

#main-content p:first-of-type::first-letter,
#main-content hr + p::first-letter {
  /* Drop-cap styles */
}
.subhead::before {
  /* Indent sub-headings with a cute fleuron */
  content: "\00a0\00a0\2767\00a0";
}

在 Firefox 中进行测试时,这导致第 (1) 和 (2) 段有首字下沉,这正是我想要的。然而,在 Chrome 中,段落 (0) 的 ::before 规则中的 fleuron 也应用了首字下沉样式。我相当确信 Firefox 在这里是错误的,因为 :first-letter 应该匹配 ::before 伪元素中的文本(如果存在),但 ::before 会导致 :first-letter 不匹配任何内容。

在尝试为 Chrome 修复它时,我在第一个选择器的末尾添加了 :not 伪类(请参阅简短版本中的第一个 CSS 规则)。具有讽刺意味的是,在 Firefox 中,这与以前一样产生了预期的效果,但在 Chrome 中,现在导致第 (1) 段不再应用首字下沉样式。对此,我没有任何解释,但我确定它与 .subhead 元素无关; Chrome 显然从不应用该规则,并且遵循水平规则的段落是唯一获得样式的段落。但是,如果我在规则的前面移动 :not 伪类,就像我在简短版本中给出的两个替代方案一样,它会再次按预期工作。

我感觉好像我同时在 Firefox 和 Chrome 中偶然发现了两个不同的错误,但是伪类和伪元素的使用对我来说有点神秘,我并不完全有信心跟他们。所以我很好奇 a) 是否有任何符合规范的内容可以解释这两种浏览器中的 CSS 行为是正确的,b) 如果没有,这些是否已经存在在某处记录的具有一致行为的已知错误。 [和 c) 如果没有,请告诉我您是否打算报告上述错误,以免我意外提交副本。]

【问题讨论】:

  • 另外,这不是问题的一部分,但我觉得我应该澄清一下:我很快意识到 :first-of-type 规则对我的目的来说是不必要的,并摆脱了它。任何试图通过提供比我开始时不那么愚蠢的 CSS 规则来“回答真正问题”的响应都是不需要的。这个问题纯粹是关于 CSS 这些方面的行为(无论是在规范还是在实践中)的学术问题。

标签: css google-chrome firefox cross-browser css-selectors


【解决方案1】:

::first-letter::after/::before 确实在 Firefox 中交互,但仅当第一个字符是字母、数字或某些标点符号时。无论::after/::before 是否存在(JSFiddle),::first-letter 似乎都忽略了其他符号(如 fleuron)。

对于:not() 和伪元素之间的关系,Chrome 是 IMO 正确的。 The documentation 表示伪元素必须始终出现在末尾(这就是为什么短版本中的第一个选择器不起作用的原因):

每个选择器只能出现一个伪元素,如果存在的话 必须出现在代表 选择器的主题

【讨论】:

  • 太棒了!有道理,并且与以前在我看来高度不一致的例子是一致的。这真是一种解脱。
猜你喜欢
  • 1970-01-01
  • 2021-08-19
  • 1970-01-01
  • 2017-12-14
  • 2015-07-29
  • 2017-01-22
  • 1970-01-01
  • 2020-01-19
  • 1970-01-01
相关资源
最近更新 更多