【问题标题】:Same specificity, after taking placement into consideration, :first-letter always wins?同样的特异性,考虑到位置后, :first-letter 总是赢?
【发布时间】:2013-10-07 17:19:51
【问题描述】:

看看这个 jsfiddle:http://jsfiddle.net/ZNddz/

.intro:first-letter {
    font-size: 130px;
}
span.letter {
    background-color: red;
    font-size: 30px;
}
p {
    font-size: 80px;
}

第一条规则由一个类选择器和一个pseudo-element选择器= 11组成

第二条规则由一个类选择器.letter和一个标签选择器span = 11组成

两条规则具有相同的特殊性,因此有理由相信获胜者应该是最后一种风格。显然事实并非如此。所以我决定在第二条规则中添加一个background-color 属性,你可以看到它的高度为 30px。

我由此推断出两条规则都没有选择相同的元素。但是我想要一个官方的解释,这有点太奇怪了。

【问题讨论】:

  • 好问题。这与此处描述的效果没有直接关系,但我想我会注意到,伪元素在 CSS3 中使用双冒号 ::,而不是在 CSS2 中由伪元素和伪类共享的单冒号。
  • 似乎 :first-letter 是字母的 font-size 属性的赢家......而背景色只是作用于设置为 30px 大小的 span 元素。跨度>
  • 似乎特异性不是这里的问题,因为即使我们用更具体制定规则 - 首字母规则仍然胜出jsfiddle.net/danield770/ZNddz/2

标签: css css-selectors pseudo-element css-specificity


【解决方案1】:

据此推断,两条规则都没有选择相同的元素。

正确。你不必推断这一点。只需打开检查元素。

给定以下标记:

<p class="intro first"><span class="letter">L</span>sometext</p>

以下代码在&lt;p&gt;标签上设置:first-letter伪元素:

.intro:first-letter {
    font-size: 130px;
}

以下代码在 span 元素上设置font-size

span.letter {
    background-color: red;
    font-size: 30px;
}

span 上的代码不会覆盖&lt;p&gt; 上的代码 - 因为它们针对的是不同的属性

如果我在 span 上设置了 first-letter 伪元素 - 那么它将覆盖 &lt;p&gt; 上的代码

Here's a jsFiddle as proof

所以你看这里没有特异性问题。

【讨论】:

  • "以下代码在&lt;p&gt; 标签上设置:first-letter 伪元素:" 不,它没有。它不会将伪元素应用于任何东西,因为.letter 作为span 默认情况下是内联的,并且该伪元素不适用于内联。这条规则被完全忽略了。
  • @BoltClock - 我有一个错字。谢谢,我修好了。
  • @BoltClock - 看看小提琴 - .letter:first-letter 确实覆盖了 .intro:first-letter 类
  • 我迷茫了一阵子,直到我开始打开其他浏览器。 Chrome 似乎是唯一一个 .letter:first-letter 有任何影响的。那是……不对。
【解决方案2】:

据此推断,两条规则都没有选择相同的元素。

这是因为.intro 匹配p 元素,而span.letter.intro 的后代。 As already mentioned, specificity is not relevant when selectors are matching different elements.但是由于每个选择器确实匹配了一些元素,所以两个规则都适用,导致你的红色背景在span.letter上生效。

但我想对这个大意有一个官方的解释,这有点太离奇了。

spec 包含一些与您所拥有的非常相似的示例:以包含文本的内联级元素开头的块级元素,以及应用于块级元素的样式,:first-letter块级元素上的伪元素,以及它的内联子元素。在所有示例中,:first-letter 伪元素在格式化结构方面始终是最内层的后代;这意味着它嵌套在行内级子元素中。

最后一个示例说明了包含伪元素在内的元素层次结构,尽管之前的示例在其样式表中包含一个覆盖规则,该规则演示了级联方面发生的情况:

以下 CSS 将使首字母首字母跨越两行:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
 <HEAD>
  <TITLE>Drop cap initial letter</TITLE>
  <STYLE type="text/css">
   P              { font-size: 12pt; line-height: 1.2 }
   P::first-letter { font-size: 200%; font-style: italic;
                    font-weight: bold; float: left }
   SPAN           { text-transform: uppercase }
  </STYLE>
 </HEAD>
 <BODY>
  <P><SPAN>The first</SPAN> few words of an article
    in The Economist.</P>
 </BODY>
</HTML>

这个例子的格式可能如下:

虚构的标签序列是:

<P>
<SPAN>
<P::first-letter>
T
</P::first-letter>he first
</SPAN> 
few words of an article in the Economist.
</P>

注意::first-letter伪元素标签紧挨着内容(即起始字符),而::first-line伪元素开始标签被插入到块元素的开始标签之后。

在您的情况下,两个 font-size 声明都照常适用,但由于 .intro:first-letter 嵌套在 span.letter,它使用自己的 font-size 值。如果您使用了相对值it would be calculated based on span.letter,并且您根本没有包含font-size 样式it would simply inherit it from span.letter

请注意,:first-letter 伪元素适用于内联级元素(但它确实适用于内联块):

在 CSS 中,::first-letter 伪元素适用于块状容器,例如块、列表项、表格单元格、表格标题和内联块元素。

内联框(使用display: inline 生成的)不是block container box。 (块容器框的内联级框的示例是内联块。)

如果浏览器将伪元素应用于内联,则违反规范。虽然没有任何迹象表明当您对块容器和内联框后代都有 :first-letter 规则时会发生什么,因为它确实说它不适用于内联,理想情况下浏览器应该始终忽略针对内联的规则盒子的后代。显然,Chrome 不这么认为。见Danield's answer

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 2019-02-15
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    • 2016-06-16
    相关资源
    最近更新 更多