This is one of the most well-known examples of authors misunderstanding how :first-child
works.
(这是作者误解:first-child
工作原理的最著名例子之一。)
Introduced in CSS2 , the :first-child
pseudo-class represents the very first child of its parent . (:first-child
伪类在CSS2中引入,代表其parent的第一个孩子 。)
That's it. (而已。)
There's a very common misconception that it picks up whichever child element is the first to match the conditions specified by the rest of the compound selector. (有一个非常普遍的误解,认为它选择第一个与其余复合选择器指定的条件相匹配的子元素。)
Due to the way selectors work (see here for an explanation), that is simply not true. (由于选择器的工作方式(请参阅此处以获取解释),这根本不是事实。)
Selectors level 3 introduces a :first-of-type
pseudo-class , which represents the first element among siblings of its element type.
(选择器级别3引入了:first-of-type
伪类 , 该类代表其元素类型的同级元素中的第一个元素。)
This answer explains, with illustrations, the difference between :first-child
and :first-of-type
. (该答案通过插图说明了:first-child
和:first-of-type
的区别。)
However, as with :first-child
, it does not look at any other conditions or attributes. (但是,与:first-child
,它不会查看任何其他条件或属性。)
In HTML, the element type is represented by the tag name. (在HTML中,元素类型由标记名称表示。)
In the question, that type is p
. (在问题中,该类型为p
。)
Unfortunately, there is no similar :first-of-class
pseudo-class for matching the first child element of a given class.
(不幸的是,没有类似的:first-of-class
伪类可以匹配给定类的第一个子元素。)
One workaround that Lea Verou and I came up with for this (albeit totally independently) is to first apply your desired styles to all your elements with that class: (我和Lea Verou为此(尽管是完全独立的)提出的一种解决方法是,首先将所需的样式应用于该类的所有元素:)
/*
* Select all .red children of .home, including the first one,
* and give them a border.
*/
.home > .red {
border: 1px solid red;
}
... then "undo" the styles for elements with the class that come after the first one , using the general sibling combinator ~
in an overriding rule:
(...然后使用通用的同级组合器~
在覆盖规则中“撤消” 第一个元素之后的类的元素的样式:)
/*
* Select all but the first .red child of .home,
* and remove the border from the previous rule.
*/
.home > .red ~ .red {
border: none;
}
Now only the first element with class="red"
will have a border.
(现在,只有第一个具有class="red"
元素才会有边框。)
Here's an illustration of how the rules are applied:
(这是如何应用规则的说明:)
<div class="home">
<span>blah</span> <!-- [1] -->
<p class="red">first</p> <!-- [2] -->
<p class="red">second</p> <!-- [3] -->
<p class="red">third</p> <!-- [3] -->
<p class="red">fourth</p> <!-- [3] -->
</div>
No rules are applied;
(没有规则适用;)
no border is rendered. (没有边框。)
This element does not have the class red
, so it's skipped.
(该元素没有类red
,因此被跳过。)
Only the first rule is applied;
(仅应用第一个规则;)
a red border is rendered. (呈现红色边框。)
This element has the class red
, but it's not preceded by any elements with the class red
in its parent.
(该元素的类为red
,但是其父元素中没有任何带有red
类的元素。)
Thus the second rule is not applied, only the first, and the element keeps its border. (因此,不应用第二条规则,仅应用第一条规则,并且元素保留其边界。)
Both rules are applied;
(这两个规则都适用;)
no border is rendered. (没有边框。)
This element has the class red
.
(此元素的类为red
。)
It is also preceded by at least one other element with the class red
. (它还至少带有一个其他类别为red
其他元素。)
Thus both rules are applied, and the second border
declaration overrides the first, thereby "undoing" it, so to speak. (因此,两个规则都被应用,第二个border
声明覆盖第一个border
,因此可以“撤消”它。)
As a bonus, although it was introduced in Selectors 3, the general sibling combinator is actually pretty well-supported by IE7 and newer, unlike :first-of-type
and :nth-of-type()
which are only supported by IE9 onward.
(作为奖励,尽管它在选择器3中引入,但通用同级组合器实际上得到了IE7和更高版本的很好支持,这与:first-of-type
和:nth-of-type()
仅受IE9及更高版本支持。)
If you need good browser support, you're in luck. (如果您需要良好的浏览器支持,那么您很幸运。)
In fact, the fact that the sibling combinator is the only important component in this technique, and it has such amazing browser support, makes this technique very versatile — you can adapt it for filtering elements by other things, besides class selectors:
(实际上,同级组合器是该技术中唯一重要的组成部分, 并且具有如此出色的浏览器支持,这一事实使得该技术非常通用-除了类选择器之外,您还可以通过其他方式使它适应过滤元素:)
You can use this to work around :first-of-type
in IE7 and IE8, by simply supplying a type selector instead of a class selector (again, more on its incorrect usage here in a later section):
(您可以使用此方法来解决IE7和IE8中的:first-of-type
,只需提供类型选择器而不是类选择器即可(再次,在后面的部分中将详细介绍其错误用法):)
article > p { /* Apply styles to article > p:first-of-type, which may or may not be :first-child */ } article > p ~ p { /* Undo the above styles for every subsequent article > p */ }
You can filter by attribute selectors or any other simple selectors instead of classes.
(您可以按属性选择器或任何其他简单选择器代替类进行过滤。)
You can also combine this overriding technique with pseudo-elements even though pseudo-elements technically aren't simple selectors.
(即使伪元素在技术上不是简单的选择器,您也可以将此替代技术与伪元素结合使用。)
Note that in order for this to work, you will need to know in advance what the default styles will be for your other sibling elements so you can override the first rule.
(请注意,为了使此功能起作用,您需要事先知道其他兄弟元素的默认样式是什么,以便您可以覆盖第一个规则。)
Additionally, since this involves overriding rules in CSS, you can't achieve the same thing with a single selector for use with the Selectors API , or Selenium 's CSS locators. (此外,由于这涉及CSS中的重写规则,因此,使用一个与Selectors API或Selenium的CSS定位器一起使用的选择器无法实现同一目的。)
It's worth mentioning that Selectors 4 introduces an extension to the :nth-child()
notation (originally an entirely new pseudo-class called :nth-match()
), which will allow you to use something like :nth-child(1 of .red)
in lieu of a hypothetical .red:first-of-class
.
(值得一提的是,选择器4引入<a href="https://stackoom.com/link/aHR0cDovL2Rldi53My5vcmcvY3Nzd2cvc