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

CSS selector for first element with class

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

1
2
3
.red:first-child {
    border: 5px solid red;
}
1
2
<p class="red">
</p>

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

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

1
2
3
.home .red:first-child {
    border: 1px solid red;
}
1
2
3
4
5
6
7
8
9
    <span>blah</span>
    <p class="red">first
</p>
    <p class="red">second
</p>
    <p class="red">third
</p>
    <p class="red">fourth
</p>

如何定位具有red类的第一个孩子?


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

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

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

1
2
3
4
5
6
7
/*
 * Select all .red children of .home, including the first one,
 * and give them a border.
 */

.home > .red {
    border: 1px solid red;
}

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

1
2
3
4
5
6
7
/*
 * Select all but the first .red child of .home,
 * and remove the border from the previous rule.
 */

.home > .red ~ .red {
    border: none;
}

现在只有class="red"的第一个元素才会有边框。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  <span>blah</span>         <!-- [1] -->
  <p class="red">first
</p>Ok.

  <!-- [2] -->
  <p class="red">second
</p>Ok.

 <!-- [3] -->
  <p class="red">third
</p>Ok.

  <!-- [3] -->
  <p class="red">fourth
</p>Ok.

 <!-- [3] -->
  • 没有规则适用;没有渲染边框。
    此元素没有类red,因此它被跳过。

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

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

  • 作为奖励,虽然它是在Selectors 3中引入的,但是一般的兄弟组合器实际上得到了IE7和更新版本的支持,不像:first-of-type:nth-of-type()只有IE9以后才支持。如果您需要良好的浏览器支持,那么您很幸运。

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

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

    1
    2
    3
    4
    5
    6
    7
    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 */
    }
  • 您可以按属性选择器或任何其他简单选择器而不是类进行筛选。

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

  • 请注意,为了使其正常工作,您需要事先知道其他同级元素的默认样式,以便您可以覆盖第一个规则。此外,由于这涉及覆盖CSS中的规则,因此无法使用单个选择器与Selectors API或Selenium的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()获取第一个匹配项:

    1
    var first = document.querySelector('.home > .red');

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

    1
    2
    3
    4
    var redElements = document.querySelectorAll('.home > .red');
    var first = redElements[0];
    var second = redElements[1];
    // etc

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

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

    1
    2
    <p class="red">
    </p>Ok.

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

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

    <预> <代码>
    <跨度>嗒嗒

    首先

    第三名

    第四名

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
      <span>blah</span>
      <p>
    dummy
    </p>Ok.


      <p class="red">first
    </p>Ok.


      <p class="red">second
    </p>Ok.


      <p class="red">third
    </p>Ok.


      <p class="red">fourth
    </p>Ok.

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

    好。


    与名称一样,:first-child选择器用于选择父标记的第一个子标记。孩子必须嵌入在同一个父标签中。您的确切示例将起作用(刚试过这里):

    1
    2
    3
    4
    5
    <body>
        <p class="red">first
    </p>
        second
    </body>

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

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

    1
    2
    3
    4
    5
    6
    7
    8
        <p class="red">first
    </p>
        second


        <p class="red">third
    </p>
        fourth

    然后firstthird将为红色。

    更新:

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <html>
    <head>
    <style type="text/css">
    .red:nth-of-type(1)
    {
        border:5px solid red;
    }
    </style>
    </head>

    <body>
       
            <span>blah</span>
            <p class="red">first
    </p>
            <p class="red">second
    </p>
            <p class="red">third
    </p>
            <p class="red">fourth
    </p>
       
    </body>
    </html>

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


    正确答案是:

    1
    .red:first-child, :not(.red) + .red { border:5px solid red }

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

    小提琴或它没有发生。

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

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


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

    1
    2
    3
    4
    5
    6
    7
    8
    .red {
      color: green;  
    }

    /* .red:nth-of-type(1) */
    .red:first-of-type {
      color: red;  
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
      <span>blah</span>
      <p class="red">first
    </p>
      <p class="red">second
    </p>
      <p class="red">third
    </p>
      <p class="red">fourth
    </p>


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        <span class="red"> <!-- MATCH -->



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



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


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

  • 在生成元素时为元素分配first类,如下所示:

    1
    2
    <p class="red first">
    </p>

    CSS:

    1
    2
    3
    .first.red {
      border:5px solid red;
    }

    此CSS仅匹配具有firstred类的元素。

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

    1
    $(".red:first").addClass("first");

  • 以上答案太复杂了。

    1
    .class:first-of-type { }

    这将选择第一类类。 MDN来源


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

    1
    2
    3
    4
    5
    6
    div > .b ~ .b:not(:first-child) {
        background: none;
    }
    div > .b {
        background: red;
    }
    1
    2
    3
    4
    5
    6
    7
    8
          <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>


    根据您更新的问题

    1
    2
    3
    4
    5
    6
    7
    8
    9
      <span>blah</span>
      <p class="red">first
    </p>
      <p class="red">second
    </p>
      <p class="red">third
    </p>
      <p class="red">fourth
    </p>

    怎么样

    1
    2
    3
    .home span + .red{
          border:1px solid red;
        }

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

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


    您可以将代码更改为此类代码以使其正常工作

    1
    2
    3
    4
    5
    6
    7
    8
    9
      <span>blah</span>
      <p class="red">first
    </p>
      <p class="red">second
    </p>
      <p class="red">third
    </p>
      <p class="red">fourth
    </p>

    这适合你

    1
    2
    3
    .home span + .red{
          border:3px solid green;
        }

    这是来自SnoopCode的CSS参考。


    我在CSS下面使用列表ul li的背景图像

    1
    2
    3
    4
    5
    #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;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    <footer id="footer">
     
        <ul class="menu">
          <li class="level1 item308 active current">
    </li>

         
    <li>
     
    </li>

       
    </ul>
     
     
     
        <ul class="menu">
    <li>

    </li>

         
    <li>

    </li>
     
       
    </ul>

     
     
        <ul class="menu">
         
    <li>

    </li>

         
    <li>

    </li>

       
    </ul>

     
    </footer>


    你可以使用nth-of-type(1)但是确保该站点不需要支持IE7等,如果是这种情况使用jQuery添加body类然后通过IE7 body class找到元素然后是元素名,然后添加在第n个孩子的造型上。


    尝试这个 :

    1
    2
    3
        .class_name > *:first-child {
            border: 1px solid red;
        }

    试试这简单有效

    1
    2
    3
     .home > span + .red{
          border:1px solid red;
        }

    出于某种原因,上述答案似乎都没有解决父母的第一个也是唯一的第一个孩子的情况。

    1
    #element_id > .class_name:first-child

    如果您想将样式仅应用于此代码中的第一个类子,则上述所有答案都将失败。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
      Content
      First content that need to be styled
     
        Second content that don't need to be styled
       
         
            deep content - no style
            deep content - no style
           
              deep content - no style
           
         
       
     
    </aside>


    尝试此解决方案:

    1
    2
    3
    4
    5
     .home p:first-of-type {
      border:5px solid red;
      width:100%;
      display:block;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
      <span>blah</span>
      <p class="red">first
    </p>
      <p class="red">second
    </p>
      <p class="red">third
    </p>
      <p class="red">fourth
    </p>

    CodePen链接


    我相信使用相对选择器+来选择紧接着放置的元素,在这里工作最好(之前建议的少)。

    这种情况也可以使用此选择器

    1
    .home p:first-of-type

    但这是元素选择器而不是第一类。

    这里有很好的CSS选择器列表:https://kolosek.com/css-selectors/