首页 文章

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

提问于
浏览
743

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

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

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

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

.home .red:first-child {
    border: 1px solid red;
}
<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>

如何针对第 red 类的第一个孩子?

18 回答

  • 306

    Try this :

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

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

    div > .b ~ .b:not(:first-child) {
    	background: none;
    }
    div > .b {
        background: red;
    }
    
    <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>
    
  • 8

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

    <body>
        <p class="red">first</p>
        <div class="red">second</div>
    </body>
    

    也许您已将标签嵌套在不同的父标签中?您的类 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>
    

    firstthird 将是红色的 .

    Update:

    我不知道为什么马丁删除了他的答案,但他有解决方案, :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>
    

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

  • 7

    我在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;
    }
    
    <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>
    
  • 13

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

    <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>
    

    这对你有用

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

    这是来自SnoopCode的CSS参考 .

  • -1

    只需要第一个,只有一个段落变红 . 怎么样?

    <!DOCTYPE html><html><head><style>
    
    article p:nth-child(1){background: red}
    article p:first-child{background: red}
    
    </style></head><body>
    
    <p style="color:blue">Needed only first and only one paragraph had red. How?</p>
    
    <article>
    <p>The first paragraph.</p>
    <div><p>The second paragraph.</p></div>
    <p>The third paragraph.</p>
    <div><p>The fourth paragraph.</p></div>
    </article>
    
    </body></html>
    
  • 2

    正确答案是:

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

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

    Fiddle or it didn't happen.

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

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

  • 3

    以上答案太复杂了 .

    .class:first-of-type { }
    

    这将选择第一类类 . MDN Source

  • 3

    出于某种原因,上述答案似乎都没有解决父母的 the real firstonly first child 的问题 .

    #element_id > .class_name:first-child
    

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

    <aside id="element_id">
      Content
      <div class="class_name">First content that need to be styled</div>
      <div class="class_name">
        Second content that don't need to be styled
        <div>
          <div>
            <div class="class_name">deep content - no style</div>
            <div class="class_name">deep content - no style</div>
            <div>
              <div class="class_name">deep content - no style</div>
            </div>
          </div>
        </div>
      </div>
    </aside>
    
  • 1

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

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

    .home p:first-of-type
    

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

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

  • 0

    由于其他答案涵盖了它的错误,我知道你在这里有一个 CSS only 解决方案,至少不是我能想到的 . 还有其他一些选择....

    • 在生成元素时为其分配 first 类,如下所示:
    <p class="red first"></p>
    <div class="red"></div>
    

    CSS:

    .first.red {
      border:5px solid red;
    }
    

    此CSS仅匹配 both firstred 类的元素 .

    • 或者,在JavaScript中执行相同的操作,例如,使用与上面相同的CSS,您可以使用jQuery执行此操作:
    $(".red:first").addClass("first");
    
  • 62

    这是作者误解 :first-child 如何运作的最着名的例子之一 . Introduced in CSS2:first-child 伪类代表 the very first child of its parent . 那个_152616是一个非常普遍的误解,它选择了第一个匹配由复合选择器其余部分指定的条件的子元素 . 由于选择器的工作方式(请参阅here作为解释),这根本不是真的 .

    Selectors level 3 introduces a :first-of-type pseudo-class,表示其元素类型的兄弟姐妹中的第一个元素 . This answer用插图解释了 :first-child:first-of-type 之间的区别 . 但是,与 :first-child 一样,它不会查看任何其他条件或属性 . 在HTML中,元素类型由标记名称表示 . 在这个问题中,该类型是 p .

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

    /* 
     * Select all .red children of .home, including the first one,
     * and give them a border.
     */
    .home > .red {
        border: 1px solid red;
    }
    

    ...然后"undo"具有类的元素的样式,在第一个元素之后,在覆盖规则中使用the general sibling combinator ~

    /* 
     * Select all but the first .red child of .home,
     * and remove the border from the previous rule.
     */
    .home > .red ~ .red {
        border: none;
    }
    

    现在只有 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>
    
    • No rules are applied; no border is rendered.
      此元素没有类 red ,因此它被跳过 .

    • Only the first rule is applied; a red border is rendered.
      此元素具有类 red ,但它的父级之前没有类 red 的任何元素 . 因此,不应用第二个规则,仅应用第一个规则,并且元素保持其边界 .

    • Both rules are applied; no border is rendered.
      该元素的类为 red . 它之前还有至少一个具有类 red 的其他元素 . 因此,两个规则都被应用,第二个 border 声明会覆盖第一个,因此可以说是它 .

    作为奖励,虽然它是在选择器3中引入的,但是IE7和更新版本实际上支持一般兄弟组合器,不像 :first-of-type:nth-of-type() ,它们仅由IE9向前支持 . 如果您需要良好的浏览器支持,那么您很幸运 .

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

    • 你可以使用它来解决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 */
    }
    
    • 您可以按attribute selectors或任何其他简单选择器而不是类进行过滤 .

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

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

    值得一提的是,Selectors 4引入了an extension to the :nth-child() notation(最初是一个名为 :nth-match() 的全新伪类),它允许你使用像 :nth-child(1 of .red) 这样的东西来代替假想的 .red:first-of-class . 作为一个相对较新的提案,没有人建议应该适用于大多数情况 .

    请记住,此答案假定问题是查找具有给定类的每个第一个子元素 . 对于整个文档中复杂选择器的第n个匹配,既没有伪类也没有通用的CSS解决方案 - 是否存在解决方案在很大程度上取决于文档结构 . jQuery为此目的提供 :eq():first:last 等,但请再次注意they function very differently from :nth-child() et al . 使用Selectors API,您可以使用 document.querySelector() 获取第一个匹配项:

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

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

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

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

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

    <p class="red"></p>
    <div class="red"></div>
    

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

    当某个类的第一个元素也是它的第一个类型时,伪类将起作用,但 this happens only by coincidence . 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>
    

    使用 .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>
    

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

  • 0

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

    .red {
      color: green;  
    }
    
    /* .red:nth-of-type(1) */
    .red:first-of-type {
      color: red;  
    }
    
    <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>
    
  • 2

    要匹配您的选择器,该元素必须具有 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>
    
  • 1

    根据您更新的问题

    <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>
    

    怎么样

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

    这将选择 class home ,然后是元素 span ,最后是所有 .red elements ,它们紧跟在span元素之后 .

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

  • 3

    Try This Simple and Effective

    .home > span + .red{
          border:1px solid red;
        }
    
  • 5

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

  • 2

    试试这个解决方案

    .home p:first-of-type {
      border:5px solid red;
      width:100%;
      display:block;
    }
    
    <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>
    

    CodePen link

相关问题