0

I went through test skills on MDN page for using selectors and I met the situation the CSS rule written for :first-child of div element with class .container is applied to table element which is down in the hierarchy but not the first child of that div element. Why is it so? Am I missing some general rule for table element? As I expected only first p element should be affected by this rule.

I attach the html code used on MDN and my CSS solution which causes this issue.

.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>
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356

1 Answers1

1

You're using the descendant combinator (space) between .container and :first-child. This causes the CSS rules to apply to all the descendants of the table, including tbody (implicit), tr, th and td, because

  • the (implicit) tbody is the first (and only) child of the table,
  • the first tr is the first child of the tbody,
  • and every first th and td is the first child of its respective tr.

This causes all the font-size: 150% declarations to stack multiplicatively resulting in the first row having bigger text than the rest, and the ::first-line rule to apply to every first th and td (there's just one word in each, so it's the first and only formatted line of each cell).

Using the child combinator > gives you the expected result by ensuring only the children of the container div (the p and table elements) are considered:

.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>
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356