DEV Community

Cover image for Stop Writing Walls of CSS: Refactoring Complex Selectors with :is()
Komeyl Mohebian
Komeyl Mohebian

Posted on • Originally published at Medium

Stop Writing Walls of CSS: Refactoring Complex Selectors with :is()

Today I found myself writing CSS rules that felt like I was solving a complex math problem instead of styling a webpage.

I needed to style nested list bullets at different depths, but because the lists could be either unordered (<ul>) or ordered (<ol>), and they appeared in three different sections of the site, I ended up with a massive "combinatorial explosion."

The "Brute-Force" Way:
I started with this wall of selectors just to cover every possible nesting combination:

.box__description ul ul ul > li::before,
.box__context ul ul ul > li::before,
.box__overflow-content ul ul ul > li::before,
.box__description ol ul ul > li::before,
.box__context ol ul ul > li::before,
.box__overflow-content ol ul ul > li::before,
.box__description ul ol ul > li::before,
.box__context ul ol ul > li::before,
.box__overflow-content ul ol ul > li::before,
.box__description ol ol ul > li::before,
.box__context ol ol ul > li::before,
.box__overflow-content ol ol ul > li::before { 
  /* 12 lines of code for one simple style! */
}
Enter fullscreen mode Exit fullscreen mode

It was repetitive, hard to read, and a nightmare to maintain. If I wanted to add a fourth container or a new list type, I’d have to manually multiply all those lines again.

The "Smart" Way:
Then I remembered the modern CSS :is() pseudo-class. It allows you to group multiple selectors into one, acting like a multiplier for your CSS. I refactored that entire block into this:

:is(.box__description, .box__context, .box__overflow-content) :is(ul, ol) :is(ul, ol) ul > li::before {
  /* Clean, efficient, and identical behavior */
}
Enter fullscreen mode Exit fullscreen mode

The Result:
I cut the code down by about 80% while keeping the exact same behavior. Now, instead of scanning a wall of text, I can see the logic at a glance. It’s a great reminder that sometimes the most "intelligent" code isn't about adding more, but about finding the right tool to simplify what's already there.

Top comments (0)