<table> 受 :first-child 伪类影响,尽管它不是为该规则设置的元素的第一个孩子

问题描述

我在 MDN 页面上通过了使用选择器的测试技巧,我遇到了为 :first-child of div element with class .container 编写的 CSS 规则应用于表元素的情况,该元素在层次结构中处于较低但不是第一个该 div 元素的子元素。为什么会这样?我是否缺少表格元素的一些一般规则?正如我所料,只有第一个 p 元素应该受此规则影响。

我附上了 MDN 上使用的 html 代码和导致此问题的 CSS 解决方案。

.container :first-child {font-size: 150%}

.container :first-child::first-line {color: red}
<div class="container">
  <p>Veggies es
    <a href="http://example.com">bonus vobis</a>,proinde vos postulo essum magis kohlrabi welsh onion daikon amaranth tatsoi tomatillo melon azuki bean garlic.</p>
  <p>Gumbo beet greens corn soko endive gumbo gourd. Parsley shallot courgette tatsoi pea sprouts fava bean collard greens dandelion okra wakame tomato. dandelion cucumber earthnut pea peanut soko zucchini.</p>
  <table>
    <tr>
      <th>Fruits</th>
      <th>vegetables</th>
    </tr>
    <tr>
      <td>Apple</td>
      <td>Potato</td>
    </tr>
    <tr>
      <td>Orange</td>
      <td>Carrot</td>
    </tr>
    <tr>
      <td>Tomato</td>
      <td>Parsnip</td>
    </tr>
    <tr>
      <td>Kiwi</td>
      <td>Onion</td>
    </tr>
    <tr>
      <td>Banana</td>
      <td>Beet</td>
    </tr>
  </table>
</div>

解决方法

您在 .container:first-child 之间使用了后代组合器(空格)。这会导致 CSS 规则适用于表的所有后代,包括 tbody(隐式)、tr、th 和 td,因为

  • (implicit) tbody 是表的第一个(也是唯一的)子元素,
  • 第一个 tr 是 tbody 的第一个孩子,
  • 并且每个第一个 th 和 td 都是其各自 tr 的第一个孩子。

这会导致所有 font-size: 150% 声明以乘法方式堆叠,导致第一行的文本比其余行大,并且 ::first-line 规则适用于每个第一个 th 和 td(其中只有一个单词)每个,所以它是每个单元格的第一个也是唯一一个格式化的行)。

使用 child combinator > 通过确保仅考虑容器 div(p 和 table 元素)的 children 为您提供预期结果:

.container > :first-child {font-size: 150%}

.container > :first-child::first-line {color: red}
<div class="container">
  <p>Veggies es
    <a href="http://example.com">bonus vobis</a>,proinde vos postulo essum magis kohlrabi welsh onion daikon amaranth tatsoi tomatillo melon azuki bean garlic.</p>
  <p>Gumbo beet greens corn soko endive gumbo gourd. Parsley shallot courgette tatsoi pea sprouts fava bean collard greens dandelion okra wakame tomato. Dandelion cucumber earthnut pea peanut soko zucchini.</p>
  <table>
    <tr>
      <th>Fruits</th>
      <th>Vegetables</th>
    </tr>
    <tr>
      <td>Apple</td>
      <td>Potato</td>
    </tr>
    <tr>
      <td>Orange</td>
      <td>Carrot</td>
    </tr>
    <tr>
      <td>Tomato</td>
      <td>Parsnip</td>
    </tr>
    <tr>
      <td>Kiwi</td>
      <td>Onion</td>
    </tr>
    <tr>
      <td>Banana</td>
      <td>Beet</td>
    </tr>
  </table>
</div>