Search code examples
csslistcss-selectors

How do you select the nth item in a list based on that item’s child's attributes using only CSS selectors


So if I have a list like this:

<ul>
 <li><button disabled/></li>
 <li><button disabled/></li>
 <li><button /></li>
 <li><button /></li>
 <li><button /></li>
</ul>

And the amount of disabled buttons is never known - but will always be consecutive and appear before the enabled buttons, how do I select the second enabled button?

Right now I have:

  • “ul li:nth-of-type(2) button:not([disabled])”

but this only selects the second <li> with a child button that is not disabled - if it is disabled, it doesn’t select anything. In other words it doesn’t ‘find’ the second enabled button, it just checks if the second button is enabled or not and selects it accordingly.

I’ve tried

  • “ul li button:not([disabled]):nth-of-type(2)”

but the problem with that is the button is the only child of <li>, so nth-of-type(2) doesn’t have anything to select.

What I think I need to be able to write is something like this:

  • “ul (li button:not([disabled])):nth-of-type(2)”

but I don’t think that’s the correct syntax :(

Any help would be greatly appreciated! If it helps anyone, I'm writing a UDF test to find (and select) the second available time slot for a time picker component in React.


Solution

  • Here is an easier selector where you only have to update one number to select the needed button

    li:nth-child(2 of :has(button:not([disabled]))) button {
      color: red;
    }
    li:nth-child(3 of :has(button:not([disabled]))) button {
      color: blue;
    }
    <ul>
     <li><button disabled>button</button></li>
     <li><button disabled>button</button></li>
     <li><button >button</button></li>
     <li><button >button</button></li>
     <li><button >button</button></li>
    </ul>