> and ~ expressions in CSS

css, css-selectors

Solution

Your selector means:

Select any element that is a child of an element with the class `content` which follows a `label` which in turn follows a `:checked` input element.

`>` is the child combinator. It selects elements that are children of a certain parent element. Unlike the space (the descendant combinator), it only selects immediately-nested elements. See this answer for an illustration on how it works.

`~` is the general sibling combinator. It selects elements that follow after other elements within the same parent (i.e. are siblings). Unlike `+` (the adjacent sibling combinator), it doesn't require an element to immediately follow another in the same parent. Compare the illustration below to this other answer which covers the `+` combinator.

Be careful, as the `~` combinator does not just select any sibling element. It only selects an element that comes after its sibling, so `:checked ~ label` will not match a `label` that occurs before the checked input element.

An illustration:

<section>
    <input type="radio" name="example1" value="1" checked>
    <label>1</label>
    <input type="radio" name="example1" value="2">
    <label>2</label>
    <input type="radio" name="example1" value="3">
    <label>3</label>

    <div class="content">
        <h3>Subheading 1</h3>     <!-- [1] Selected -->
        <p>Some text              <!-- [1] Selected -->
           <em>with emphasis</em> <!-- [2] Not selected -->
        </p>
        <p>Some text</p>          <!-- [1] Selected -->
    </div>
</section>

<section>
    <input type="radio" name="example2" value="1">
    <label>1</label>
    <input type="radio" name="example2" value="2">
    <label>2</label>
    <input type="radio" name="example2" value="3">
    <label>3</label>

    <div class="content">
        <h3>Subheading 1</h3>     <!-- [3] Not selected -->
        <p>Some text              <!-- [3] Not selected -->
           <em>with emphasis</em> <!-- [2] Not selected -->
        </p>
        <p>Some text</p>          <!-- [3] Not selected -->
    </div>
</section>

What's selected and what's not:

Selected This `h3` or `p` element is located directly inside a `.content` parent element. That `.content` element follows at least one `label`, and this `label` occurs after at least one input element that is `:checked`.

Note that any of the radio buttons here can be checked, and the elements will match, because as mention above `~` doesn't require a label to follow it immediately. Also, given the structure, either one of the `~` selectors can be swapped out for a `+`:

:checked + label ~ .content > *
:checked ~ label + .content > *

But this selector:

:checked + label + .content > *

Will only match if the third radio button is checked, because it's the only one that's immediately followed by a `label` and the `.content` element.

Not selected This `em` element is nested within one of the `p` elements which is itself contained within `.content`. Based on the illustration here, it won't be selected as it's not a child of `.content`.

Not selected Unlike in [1], none of the `label` elements in this section follow any `:checked` input element. Therefore, nothing is selected here, because it doesn't satisfy `:checked ~ label`.

Problem

What is the purpose of ~ and > in CSS? For example what does the following expression mean? ``` :checked ~ label ~ .content > * ```

Original source

Related problems