带有类的第一个元素的CSS选择器

Raj*_*jat 883 css css-selectors

我有一堆带有类名的元素red,但我似乎无法class="red"使用以下CSS规则选择第一个元素:

.red:first-child {
    border: 5px solid red;
}
Run Code Online (Sandbox Code Playgroud)
<p class="red"></p>
<div class="red"></div>
Run Code Online (Sandbox Code Playgroud)

这个选择器有什么问题,我该如何纠正?

感谢这些评论,我发现该元素必须是其父母的第一个孩子才能被选中,这与我的情况不同.我有以下结构,这条规则失败,如评论中所述:

.home .red:first-child {
    border: 1px solid red;
}
Run Code Online (Sandbox Code Playgroud)
<div class="home">
    <span>blah</span>
    <p class="red">first</p>
    <p class="red">second</p>
    <p class="red">third</p>
    <p class="red">fourth</p>
</div>
Run Code Online (Sandbox Code Playgroud)

我怎样才能让第一个孩子上课red

Bol*_*ock 1351

这是作者误解作用的最着名的例子之一:first-child.在CSS2中引入,:first-child伪类代表其父的第一个子级.而已.有一种非常普遍的误解,即它会选择第一个匹配复合选择器其余部分指定的条件的子元素.由于选择器的工作方式(参见此处的解释),这根本不是真的.

选择器级别3引入了一个:first-of-type伪类,它表示其元素类型的兄弟之间的第一个元素.这个答案解释,图文并茂,之间的差异:first-child:first-of-type.但是,与其一样:first-child,它不会查看任何其他条件或属性.在HTML中,元素类型由标记名称表示.在这个问题中,那种类型是p.

不幸的是,没有类似的:first-of-class伪类来匹配给定类的第一个子元素.Lea Verou和我为此提出的一个解决方法(尽管完全独立)是首先将所需的样式应用于该类的所有元素:

/* 
 * Select all .red children of .home, including the first one,
 * and give them a border.
 */
.home > .red {
    border: 1px solid red;
}
Run Code Online (Sandbox Code Playgroud)

...然后在最重要的规则中使用通用兄弟组合子 "撤消"具有第一个之后的类的元素的样式:~

/* 
 * Select all but the first .red child of .home,
 * and remove the border from the previous rule.
 */
.home > .red ~ .red {
    border: none;
}
Run Code Online (Sandbox Code Playgroud)

现在只有第一个元素class="red"将具有边框.

以下是如何应用规则的说明:

<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>
Run Code Online (Sandbox Code Playgroud)
  1. 没有规则适用; 没有渲染边框.
    这个元素没有类red,所以它被跳过了.

  2. 只应用第一条规则; 呈现红色边框.
    这个元素有类red,但它的red父元素之前没有任何元素.因此,不应用第二个规则,仅应用第一个规则,并且元素保持其边界.

  3. 这两条规则都适用; 没有渲染边框.
    这个元素有类red.它之前还有至少一个其他元素red.因此,两个规则都被应用,第二个border声明会覆盖第一个规则,从而"撤消"它,可以这么说.

作为奖励,但它是在选择器3介绍,一般的兄弟组合子是实际上是相当的IE7及更高版本,不像良好支持:first-of-type:nth-of-type()其仅仅通过IE9起支持.如果您需要良好的浏览器支持,那么您很幸运.

实际上,兄弟组合器是这种技术中唯一重要的组件,并且它具有如此惊人的浏览器支持,这使得这种技术非常通用 - 除了类选择器之外,你可以通过其他方式调整它以过滤元素:

  • 您可以使用它:first-of-type在IE7和IE8中解决,只需提供一个类型选择器而不是类选择器(再次,更多关于它在以后的部分中的错误用法):

    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 */
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 您可以按属性选择器或任何其他简单选择器而不是类进行筛选.

  • 您也可以将此重写技术与伪元素结合使用,即使伪元素在技术上不是简单的选择器.

请注意,为了使其正常工作,您需要事先知道其他同级元素的默认样式,以便您可以覆盖第一个规则.此外,由于这涉及覆盖CSS中的规则,因此单个选择器无法与Selectors APISelenium的CSS定位器一起使用.

值得一提的是,Selectors 4引入:nth-child()符号的扩展(最初是一个全新的伪类:nth-match()),它允许你使用类似于:nth-child(1 of .red)假设的东西.red:first-of-class.作为一个相对较新的提案,还没有足够的可互操作的实现,以便它可以在生产站点中使用.希望这会很快改变.与此同时,我建议的解决方法应该适用于大多数情况.

请记住,这个答案假设问题是查找具有给定类的每个第一个子元素.对于整个文档中的复杂选择器的第n次匹配,既没有伪类也没有通用的CSS解决方案- 是否存在解决方案在很大程度上取决于文档结构.jQuery提供:eq(),:first,:last多用于这一目的,但同样注意,它们的功能从非常不同:nth-child().使用Selectors API,您可以使用document.querySelector()获取第一个匹配项:

var first = document.querySelector('.home > .red');
Run Code Online (Sandbox Code Playgroud)

或者使用document.querySelectorAll()索引器来选择任何特定匹配:

var redElements = document.querySelectorAll('.home > .red');
var first = redElements[0];
var second = redElements[1];
// etc
Run Code Online (Sandbox Code Playgroud)

尽管Philip Daubmeier.red:nth-of-type(1)最初接受的答案中的解决方案(最初由Martyn编写但后来被删除),但它的行为并不像您期望的那样.

例如,如果您只想p在原始标记中选择:

<p class="red"></p>
<div class="red"></div>
Run Code Online (Sandbox Code Playgroud)

...然后你不能使用.red:first-of-type(等价于.red:nth-of-type(1)),因为每个元素是它的第一个(也是唯一的)类型(pdiv分别),所以两者都将被选择器匹配.

当某个类的第一个元素也是它的第一个类型时,伪类将起作用,但这只是巧合.Philip的回答证明了这种行为.在此元素之前粘贴在相同类型的元素中的那一刻,选择器将失败.采用更新的标记:

<div class="home">
  <span>blah</span>
  <p class="red">first</p>
  <p class="red">second</p>
  <p class="red">third</p>
  <p class="red">fourth</p>
</div>
Run Code Online (Sandbox Code Playgroud)

应用规则.red:first-of-type将起作用,但一旦添加另一个p没有该类:

<div class="home">
  <span>blah</span>
  <p>dummy</p>
  <p class="red">first</p>
  <p class="red">second</p>
  <p class="red">third</p>
  <p class="red">fourth</p>
</div>
Run Code Online (Sandbox Code Playgroud)

...选择器将立即失败,因为第一个.red元素现在是第二个 p元素.

  • 那么,有没有办法模仿`:last-of-class`?选择类的最后一个元素. (12认同)
  • 与兄弟姐妹很好的技术.值得注意的是,这也适用于多个兄弟组合器,例如p~p~p将选择第三项以及更多:https://jsfiddle.net/zpnnvedm/1/ (4认同)
  • @BoltClock是的,对不起,我来这里寻求解决方案,我对OP的具体情况并不在意.其实,我不明白为什么了`一般兄弟选择〜`就像一个':没有(:第一 - - *)`为特定类型的,我认为它应该将规则应用于每个匹配的元素,但它是即使有3个或更多可能的匹配,也仅适用于第一场比赛. (2认同)

Phi*_*ier 318

:first-child选择的目的是,像它的名字说,选择父标签的第一个孩子.孩子必须嵌入在同一个父标签中.您的确切示例将起作用(刚试过这里):

<body>
    <p class="red">first</p>
    <div class="red">second</div>
</body>
Run Code Online (Sandbox Code Playgroud)

也许您已将标签嵌套在不同的父标签中?您的类标签red真的是父母下的第一个标签吗?

另请注意,这并不仅适用于整个文档中的第一个此类标记,而是每次将新父项包裹在其中时,例如:

<div>
    <p class="red">first</p>
    <div class="red">second</div>
</div>
<div>
    <p class="red">third</p>
    <div class="red">fourth</div>
</div>
Run Code Online (Sandbox Code Playgroud)

first然后third会变红.

更新:

我不知道为什么马丁删除了他的答案,但他有解决方案,:nth-of-type选择器:

<html>
<head>
<style type="text/css">
.red:nth-of-type(1)
{
    border:5px solid red;
} 
</style>
</head>

<body>
    <div class="home">
        <span>blah</span>
        <p class="red">first</p>
        <p class="red">second</p>
        <p class="red">third</p>
        <p class="red">fourth</p>
    </div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

Martyn的学分.更多信息,例如这里.请注意,这是一个CSS 3选择器,因此并非所有浏览器都能识别它(例如IE8或更早版本).

  • 读这篇文章我有点困惑.严格地`.red:nth-​​of-type(1)`将选择任何元素,其中(a)是其元素类型的第一个子元素,(b)具有类"red".因此,如果在示例中,第一个<p>没有类"red",则不会选中它.或者,如果<span>和第一个<p>都具有类"红色",则它们都被选中.http://jsfiddle.net/fvAxn/ (24认同)
  • @Dan Mundy:`:first-of-type`相当于`:nth-​​of-type(1)`,所以当然它也有效.由于我的回答中陈述的相同原因,它也可能以同样的方式失败. (7认同)
  • @David我确定`:nth-​​of-type`在表示"type"时表示"element/tag".所以它只考虑元素,而不是类. (4认同)
  • @David 几个月前所说的是正确的;`:nth-of-type()` 并不是一个好的解决方案。我提供了一个替代答案,它应该更可靠,而且作为奖励,它可以在 IE7+ 中工作,与 `:nth-of-type()` 不同。 (2认同)
  • @gcampbell:是的,这就是它的意思,这就是为什么这个答案有缺陷的原因。选择“类型”一词的原因是为了避免将选择器与HTML / XML耦合,因为并非所有语言都具有定义元素的“标签”概念。 (2认同)

Sam*_*ody 70

正确答案是:

.red:first-child, :not(.red) + .red { border:5px solid red }
Run Code Online (Sandbox Code Playgroud)

第一部分:如果元素是第一个到它的父级并且具有类"红色",它将获得边界.
第二部分:如果".red"元素不是第一个到它的父元素,而是紧跟一个没有类".red"的元素,它也应该得到所述边界的荣誉.

小提琴或它没有发生.

Philip Daubmeier的回答虽然被接受,但却是不正确的 - 请参阅随附的小提琴.
BoltClock的答案可行,但不必要地定义和覆盖样式
(特别是否则会继承不同边框的问题 - 你不想声明其他边框:none)

编辑:如果你有几次非红色的"红色",每个"第一"红色将获得边框.为了防止这种情况,人们需要使用BoltClock的答案.看小提琴

  • 这个解决方案是最好的IMO,因为你可以轻松地为最后一个孩子做同样的事情. (3认同)
  • 对不起,但是它与"具有类.red的第一个子元素"不匹配,而是匹配"第一个元素,如果它有类.red和非.red元素之后的第一个.red元素".这两个不等同.小提琴:http://jsfiddle.net/Vq8PB/166/ (3认同)
  • 这个答案没有错,选择器*对于给定的标记是正确的,但是我应该重申编辑中提到的情况是我说至少在你不能保证标记结构时需要覆盖的原因 - 只是因为`.red`跟在一个`:not(.red)`并不总是使它成为兄弟姐妹中的第一个`.red`.如果边界需要继承,那么只需要在覆盖规则中声明`border:inherit`而不是`border:none`. (2认同)

Lea*_*ics 39

我很惊讶没有人提到最干净的解决方案:

.red:not(.red ~ .red) {
    border: 1px solid red;
}
Run Code Online (Sandbox Code Playgroud)
<div class="home">
    <span>blah</span>
    <p class="red">first</p>
    <p class="red">second</p>
    <p class="red">third</p>
    <p class="red">fourth</p>
</div>
Run Code Online (Sandbox Code Playgroud)

  • 一个 `.red` 不是“`.red` 前面有一个 `.red`”。本例中只有第一个。但如果中间插入另一个类就不行了。注意: `.red:not(.red ~ *)` 也应该有效(“一个 `red` 不是“前面有一个 `.red` 的任何东西”) (3认同)
  • @hl037_ 为什么它不起作用?您确定您没有弄错“+”和“~”选择器、直接兄弟和任意距离兄弟吗? (2认同)
  • 需要一些解释。不鼓励仅使用代码的答案。 (2认同)

Moe*_*oes 18

你可以使用first-of-typenth-of-type(1)

.red {
  color: green;  
}

/* .red:nth-of-type(1) */
.red:first-of-type {
  color: red;  
}
Run Code Online (Sandbox Code Playgroud)
<div class="home">
  <span>blah</span>
  <p class="red">first</p>
  <p class="red">second</p>
  <p class="red">third</p>
  <p class="red">fourth</p>
</div>
Run Code Online (Sandbox Code Playgroud)

  • 如果你在`span`和你的第一个'p`元素和`red`类之间有一个`<p> </ p>`,它将无效.看看这个[JSFiddle](https://jsfiddle.net/4k5zp4wL/). (5认同)

Che*_*try 9

要匹配您的选择器,该元素必须具有类名,red并且必须是其父级的第一个子级.

<div>
    <span class="red"> <!-- MATCH -->
</div>

<div>
    <span>Blah</span>
    <p class="red"> <!-- NO MATCH -->
</div>

<div>
    <span>Blah</span>
    <div><p class="red"></div> <!-- MATCH -->
</div>
Run Code Online (Sandbox Code Playgroud)


Nic*_*ver 9

由于其他答案涵盖了它的错误,我会尝试另一半,如何解决它.不幸的是,我不知道你这里只有一个CSS解决方案,至少不是我能想到的.还有其他一些选择....

  1. first在生成元素时为其分配一个类,如下所示:

    <p class="red first"></p>
    <div class="red"></div>
    
    Run Code Online (Sandbox Code Playgroud)

    CSS:

    .first.red {
      border:5px solid red;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    此CSS仅匹配包含两者 firstred类的元素.

  2. 或者,在JavaScript中执行相同的操作,例如,使用与上面相同的CSS,您可以使用jQuery执行此操作:

    $(".red:first").addClass("first");
    
    Run Code Online (Sandbox Code Playgroud)


Gab*_*air 8

上面的答案太复杂了。

.class:first-of-type { }
Run Code Online (Sandbox Code Playgroud)

这将选择第一类。MDN来源

  • 我找不到对first-type的任何引用,并且first-of-type仅适用于标签名称;您确定这个答案正确吗? (4认同)
  • `first-type` [已重命名为](https://developer.mozilla.org/en-US/docs/Web/CSS/:first-of-type) `first-of-type` (2认同)
  • **这不适用于类。**这就是**的工作方式,因为选择类的第n个比选择标签的第n个更有用。但是':first-of-type'只能由tagName使用。如果恰好碰巧“一流”和“标签第一”指的是同一元素,而他们经常这样做,那么很容易使自己困惑,以为它确实如此工作。然后想知道当您遇到的情况没有解决时,有什么坏处。 (2认同)
  • @Bernesto,当您遇到具有相同“类型”的多个元素时,可以说“&lt;span&gt;”,并且其中一些元素具有“highlight”类。`.highlight:first-of-type` 选择器将选择具有所选类的“type”的第一个实例,在本例中是第一个“&lt;span&gt;”,而不是“highlight”类的第一个实例。仅当 span 的第一个实例也具有类突出显示时,才会实现该样式。(https://codepen.io/andrewRmillar/pen/poJKJdJ) (2认同)
  • 我的答案之所以如此复杂,是因为它的最后一部分以及我对其他几个答案的评论**准确地解释了为什么这是有缺陷的**。当您还没有尝试将 MDN 材料与其关联起来时,在两年后的答案中添加 MDN 链接并不能完全支持它 - 大概是因为您做不到。 (2认同)

Sti*_*Cat 5

根据您更新的问题

<div class="home">
  <span>blah</span>
  <p class="red">first</p>
  <p class="red">second</p>
  <p class="red">third</p>
  <p class="red">fourth</p>
</div>
Run Code Online (Sandbox Code Playgroud)

怎么样

.home span + .red{
      border:1px solid red;
    }
Run Code Online (Sandbox Code Playgroud)

这将选择class home,然后是元素span,最后是span元素之后的所有.red元素.

参考:http://www.w3schools.com/cssref/css_selectors.asp


li *_*hao 5

我使用下面的 CSS 为列表 ul li 提供背景图像

#footer .module:nth-of-type(1)>.menu>li:nth-of-type(1){
  background-position: center;
  background-image: url(http://monagentvoyagessuperprix.j3.voyagesendirect.com/images/stories/images_monagentvoyagessuperprix/layout/icon-home.png);
  background-repeat: no-repeat;
}
Run Code Online (Sandbox Code Playgroud)
<footer id="footer">
  <div class="module">
    <ul class="menu ">
      <li class="level1 item308 active current"></li>
      <li> </li>
    </ul> 
  </div>
  <div class="module">
    <ul class="menu "><li></li>
      <li></li> 
    </ul>
  </div>
  <div class="module">
    <ul class="menu ">
      <li></li>
      <li></li>
    </ul>
  </div>
</footer>
Run Code Online (Sandbox Code Playgroud)


小智 5

我在我的项目中得到了这个。

div > .b ~ .b:not(:first-child) {
	background: none;
}
div > .b {
    background: red;
}
Run Code Online (Sandbox Code Playgroud)
<div>
      <p class="a">The first paragraph.</p>
      <p class="a">The second paragraph.</p>
      <p class="b">The third paragraph.</p>
      <p class="b">The fourth paragraph.</p>
  </div>
Run Code Online (Sandbox Code Playgroud)


PJC*_*der 5

使用最新的nth-childof <selector>语法,您可以这样做来实现您想要的。

希望你喜欢。

.home :nth-child(1 of .red) {
    border: 1px solid red;
}
Run Code Online (Sandbox Code Playgroud)
<div class="home">
    <span>blah</span>
    <p class="red">first</p>
    <p class="red">second</p>
    <p class="red">third</p>
    <p class="red">fourth</p>
</div>
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

931558 次

最近记录:

6 年,8 月 前