DEV Community

Calin Baenen
Calin Baenen

Posted on

What's the difference between CSS `s1 s2 {}` and `s1 > s2 {}`, and how do they cascade?

So, I tried both .no-markers ::marker and .no-markers > ::marker and did:

<ul class="no-markers">
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
</ul>
Enter fullscreen mode Exit fullscreen mode

And they both removed the markers from the list.
So, my first question is "Do any nested elements, so long as somewhere down the line they are in a .selector mean that that element gets that style?".
And, I thought s1 > s2 styled elements directly under s1, so, logically, my second question is "What's the difference between s1 s2 and s1 > s2?".

Thanks!
Cheers!

Discussion (10)

Collapse
endymion1818 profile image
Ben Read

s1 s2 {…} will select any child of s1, where as s1 > s2 {…} will select only direct children.

Collapse
baenencalin profile image
Calin Baenen Author

Then how come s1 > s2 still removed the ::markers from the li despite no-markers being applied to the ul?

Collapse
endymion1818 profile image
Ben Read

Because of the space between the declarations. Take a look at this for a comparison. codepen.io/endymion1818/pen/WNMMpwO

Thread Thread
baenencalin profile image
Calin Baenen Author • Edited on

But there's no > there.
Or is that only required when two tag selectors need to be disambiguated?

Thread Thread
endymion1818 profile image
Ben Read • Edited on

Yes you're close, the space signifies selecting a child in this case.

Collapse
gabrielpedroza profile image
Gabriel Pedroza

s1 s2 selects all the child(s) of s1.

So anything that is nested in s1 that is an s2 will be selected

s1 > s2 selects the direct child(s) of s1.

So anything that is directly nested and is a child of s1 and is an s2 will be selected

In your example, it would not make a difference which one you chose because you only have direct children in your

    element. If you had something like
<ul>
  <li></li>
  <li></li>
  <li>
    <li>(Nested list item so this means it is not a direct child of the <ul> element)If using ul > li, this **would not** be selected. If using ul li, this **would be** selected</li>
  </li>
</ul>

Collapse
baenencalin profile image
Calin Baenen Author

Alright.
As I told someone else, I was just simply fooled by Chrome's dev console, which straight up lies.
Example of Chrome saying  raw `::marker` endraw s exist inside  raw `li` endraw s.

Collapse
baenencalin profile image
Calin Baenen Author

Speaking of CSS, I think DEV needs a CSS check. . .

Collapse
lukeshiru profile image
Luke Shiru

You can imagine the HTML like this:

<ul class="no-markers">
    {::marker}<li>One</li>
    {::marker}<li>Two</li>
    {::marker}<li>Three</li>
</ul>
Enter fullscreen mode Exit fullscreen mode

The ::marker pseudo-elements are children of ul, so if you do:

.no-markers ::marker
Enter fullscreen mode Exit fullscreen mode

You're selecting the ::marker elements at any level, while this:

.no-markers > ::marker
Enter fullscreen mode Exit fullscreen mode

Will only select the direct children. You can try putting list inside lists to see the differences clearly:

<ul class="no-markers">
    <li>
        One:
        <ul>
            <li>A</li>
            <li>B</li>
        </ul>
    </li>
    <li>
        Two:
        <ul>
            <li>A</li>
            <li>B</li>
        </ul>
    </li>
    <li>
        Three:
        <ul>
            <li>A</li>
            <li>B</li>
        </ul>
    </li>
</ul>
Enter fullscreen mode Exit fullscreen mode

Cheers!

Collapse
baenencalin profile image
Calin Baenen Author • Edited on

Huh. That's weird.
According to the Chrome console it looked like the ::marker elements were children of the li, and I somewhat believed that because no markers appear when there are no list items.
Would you know anything about this?

Thanks for your help.