DEV Community

Cover image for Simpler CSS Selectors With :is()

Simpler CSS Selectors With :is()

Steve Sewell on January 19, 2023

Simplifying redundant selectors If you’ve got redundant CSS selectors like this: /* πŸ˜• */ .active a, .active button, .active label { ...
Collapse
 
spo0q profile image
spO0q πŸ’πŸŽƒ

This is very well written. Congrats!

Collapse
 
angelafox777 profile image
Angela Fox

Wonderful info! Thanks!

Collapse
 
fpigeonjr profile image
Frank Pigeon Jr. πŸ‡΅πŸ‡¦πŸ‡ΊπŸ‡Έ

ugh wow, great article. Learned a lot here.

Collapse
 
fininhors profile image
Francisco Junior

Thank you.

Collapse
 
jpcid profile image
Javier PΓ©rez Cid

Nice summary for those out from CSS for some time. Thank you!!!!

Collapse
 
harmonygrams profile image
Harmony

Thank you for this.
There's always something new to learn about CSS.

Collapse
 
alohci profile image
Nicholas Stimpson

I voted for nested option 3. But option 4 has grown on me. When I first saw option 4, I thought it was an abomination too, but the more I've thought about it, the more elegant a solution it seems to be. It solves the problem of telling selectors and declarations apart at a clear syntactic level, whereas option 3 requires a non-obvious "trick" for some cases.

Also, option 4 makes it much clearer - this is CSS nesting, not SASS nesting. The way in which selectors nest is significantly different in CSS to the macro-expansion approach of SASS and there's some merit in being able to view a nested rule in isolation and be able to see which type of nesting the author intended.

Collapse
 
jamesthomson profile image
James Thomson

Is the example written here correct? The brackets don't make any sense compared to...well, pretty much any other language. It seems like there's 2 to many.

Collapse
 
alohci profile image
Nicholas Stimpson • Edited

Yes, they are correct. The idea is the structure syntax for a rule would be

selector { declarations } { nested rules }

where each nested rule would follow the same pattern. The { nested rules } part would be optional, so that existing CSS rules would still be compliant.

There was an early proposal for using

selector { declarations { nested rules } }

but the community voted it out on the (somewhat doubtful in my opinion) grounds that it would result in too rapid indentation of nested rules.

Thread Thread
 
jamesthomson profile image
James Thomson

Ahhh, I see it now once laid out like that. You're right, that's a pretty elegant solution. I do still prefer option 3, but that could be because of the existing familiarity with it. I guess option 3 also potentially could mean you could pull out the sass build step if all you were using it for was nesting.

Collapse
 
rouilj profile image
John P. Rouillard • Edited

One thing I always wondered about with :is():

What color is the example link:

<style>
.active :is(a, .highlight, #pushme) { color: red; } /* 1 */

.active a {color: blue;} /* 2 */
</style>

<a class="active">example link</a>
Enter fullscreen mode Exit fullscreen mode

I think it should be red because #pushme makes the specificity of 1: (1,1,0) compared to (0, 1, 1) for case 2 right? :is() is not the specificity of the matching selector. IIUC all of :is() gets boiled down in the most specific of its selectors (max(selectors)) and not (sum(selectors)).

Would using selectors that have the same base specificity make overiding without !important easier/possible be a best practice?

This is probably where :where() (hmm, pun not intended) could be useful to allow overriding the casade later in the file.

Collapse
 
alohci profile image
Nicholas Stimpson

I've considered using :is(:where(a), #FOO.FOO:not(*)) as a specificity hack. Using :not(*) makes it clear that that entry in the selector list is just for setting the specificity since it can never accidentally match any element, and whatever precedes the :not(*) sets the specificity value.

But it's still a hack, and cannot be considered best practice any more than !important. You should instead be looking to set the selector to play nicely in the room with the other selectors of the page. The selectors should be chosen to describe the semantics of the elements they match, and if you do that, you should never need to hack a specificity.

Collapse
 
cryptographer3301 profile image
user32dll

I'm really stuck in web dev roadmap, I learn html css very well. But when it comes to practice, i can't make a simple web page !!
That's making me feeling sad, i love CSS but i don't know to master it. and sometimes my mind telling me navigate to backeend maybee you'll find your passion thhhere knowing that i coming from low level ( C - C# - C++ - Perl ) but i said how can i become backend developer and i don't know to build a basic ui with html css its really shame !! please help guys