Kalga
Kalga

Reputation: 11

I don't understand the ~ * css selectors combination

I am trying to reconstruct the 'Toggling elements with a hidden checkbox' code by myself, but I don't understand the selectors syntax:

#expand-toggle:checked ~ * .expandable {visibility: visible;}

Why we need both ~ and *?

Why using just the ~ selector is not enough?

Thank you

Upvotes: 1

Views: 97

Answers (1)

BoltClock
BoltClock

Reputation: 723628

Let's review the HTML for that sample:

<input type="checkbox" id="expand-toggle" />

<table>
  <thead>
    <tr><th>Column #1</th><th>Column #2</th><th>Column #3</th></tr>
  </thead>
  <tbody>
    <tr class="expandable"><td>[more text]</td><td>[more text]</td><td>[more text]</td></tr>
    <tr><td>[cell text]</td><td>[cell text]</td><td>[cell text]</td></tr>
    <tr><td>[cell text]</td><td>[cell text]</td><td>[cell text]</td></tr>
    <tr class="expandable"><td>[more text]</td><td>[more text]</td><td>[more text]</td></tr>
    <tr class="expandable"><td>[more text]</td><td>[more text]</td><td>[more text]</td></tr>
  </tbody>
</table>

<label for="expand-toggle" id="expand-btn">Toggle hidden rows</label>

Recall that the ~ combinator is a sibling combinator. If the selector were to read #expand-toggle:checked ~ .expandable, that would require the .expandable element to follow after the checkbox but not within some other element. In this case, .expandable is a tr within a table. That table is a sibling of the checkbox.

Perhaps swapping the * for a table would make the selector clearer:

#expand-toggle:checked ~ table .expandable {
  visibility: visible;
}

Either one could be used; I'm guessing the author went with * to save space — evidently, at the cost of readability.

Upvotes: 1

Related Questions