:first-child 不工作,除非 parent 是 <div>

:first-child not working unless the parent is <div>

有人可以解释这背后的理论吗? 我有这个代码; https://jsfiddle.net/vikaskulkarni/cnLdwxza/1/

<html>

  <head>
    <meta charset="utf-8">
    <title>Articles</title>
    <style>
      .bodyCls {
        float: left;
      }

      .bodyCls article {
        width: 50%;
        float: left;
      }

      article:first-child {
        background-color: red;
      }

      article:nth-child(2) {
        background-color: yellow;
      }

      article:nth-child(3) {
        background-color: blue;
      }

      article:last-child {
        background-color: green;
      }

    </style>
  </head>

  <body class="bodyCls">
    <div>
      <article>First</article>
      <article>Second</article>
      <article>Third</article>
      <article>Fourth</article>
    </div>
  </body>

</html>

这很好用。 但是,如果我像 link 那样从正文中删除 DIV,first-child 选择器将不起作用, https://jsfiddle.net/vikaskulkarni/95gbpmf8/1/

<html>

  <head>
    <meta charset="utf-8">
    <title>Articles</title>
    <style>
      .bodyCls {
        float: left;
      }

      .bodyCls article {
        width: 50%;
        float: left;
      }

      article:first-child {
        background-color: red;
      }

      article:nth-child(2) {
        background-color: yellow;
      }

      article:nth-child(3) {
        background-color: blue;
      }

      article:last-child {
        background-color: green;
      }

    </style>
  </head>

  <body class="bodyCls">
      <article>First</article>
      <article>Second</article>
      <article>Third</article>
      <article>Fourth</article>
  </body>

</html>

我在网上搜索了一下,发现在使用选择器的时候,总有一个DIV参与进来。所以我对这些选择器的工作方式有点困惑。

文章是父元素 div 的子元素。 :first-child 选择器要求该元素是其父元素中的第一个子元素。在这种情况下不是。如果删除父项,子项将不再是 div 的子项,而是 body 的子项,并且无法使用 :first-child 选择器。请注意,这对 :last-child

也是一样的

如果您检查 DOM,就会发现浏览器在 <body> 标签内添加了另外 3 个元素。 :first-child 运算符仅在目标元素是 <article> 并且是其父元素的第一个子元素时才起作用。事实并非如此,因为 <first-child> 实际上是 <meta> 标签。这就是当您删除 div.

时您的逻辑失败的原因

要使其在没有 <div> 的情况下也能正常工作,您可以将 CSS 样式更新为如下内容:

  article:nth-child(4) {
    background-color: red;
  }

  article:nth-child(5) {
    background-color: yellow;
  }

  article:nth-child(6) {
    background-color: blue;
  }

  article:nth-child(7) {
    background-color: green;
  }

我个人建议使用包装 <div>,因为它可以让您的 HTML 和相应的 CSS 井井有条。此外,浏览器添加的额外标签的顺序可能因浏览器而异,因此不能保证上述设置适用于所有浏览器。使用 <div> 将保证它,因为您的 <article> 标签将始终是包装 div.

的唯一子代

<body></body> 中的每个节点都是 body 的子节点,因此在您的 css 中,您不必在子 class 选择器前加上 a body class

看我的演示来理解这个想法

https://jsfiddle.net/95gbpmf8/3/

article {
    width: 50%;
    float: left;
  }
  article:first-child {
    background-color: red;
  }

  article:nth-child(2) {
    background-color: yellow;
  }

  article:nth-child(3) {
    background-color: blue;
  }

  article:last-child {
    background-color: green;
  }

浮动节点使其显示为 "inline-block",因此您的文章节点现在是 div,具有内联块显示。