惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Cloudflare Blog
Microsoft Security Blog
Microsoft Security Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
L
LangChain Blog
W
WeLiveSecurity
P
Proofpoint News Feed
月光博客
月光博客
NISL@THU
NISL@THU
L
LINUX DO - 最新话题
Webroot Blog
Webroot Blog
T
Threatpost
Y
Y Combinator Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Threat Research - Cisco Blogs
Vercel News
Vercel News
Jina AI
Jina AI
阮一峰的网络日志
阮一峰的网络日志
S
Schneier on Security
J
Java Code Geeks
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
小众软件
小众软件
MyScale Blog
MyScale Blog
N
News and Events Feed by Topic
Stack Overflow Blog
Stack Overflow Blog
有赞技术团队
有赞技术团队
The Hacker News
The Hacker News
Schneier on Security
Schneier on Security
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Help Net Security
Help Net Security
Recent Announcements
Recent Announcements
S
Security @ Cisco Blogs
C
CXSECURITY Database RSS Feed - CXSecurity.com
S
Securelist
T
The Exploit Database - CXSecurity.com
云风的 BLOG
云风的 BLOG
C
Cisco Blogs
雷峰网
雷峰网
量子位
Google DeepMind News
Google DeepMind News
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Spread Privacy
Spread Privacy
L
Lohrmann on Cybersecurity
I
Intezer
T
The Blog of Author Tim Ferriss
G
GRAHAM CLULEY
D
DataBreaches.Net
V
Vulnerabilities – Threatpost
P
Privacy & Cybersecurity Law Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
罗磊的独立博客

Matthias Ott

Hello Again, World This, Still Not for Everyone The Shape of Friction WeissKlang L1 – Punching Above Its Weight Continvoucly Morged Value Webspace Invaders To Affinity and Beyond The Mystery of Storytelling Amateurs! Echoes of Connection Linear() Is Not (That) Linear View Transitions: The Smooth Parts Adding AVIF and WebP Support to My Craft CMS Site Challenge Acoustic Room Treatment and Building Sound Panels, Part 1: Planning Play On Overshoot The HTML Output Element Listening Closely Compressed Fluid Typography The Lifeblood of the Web What Could Go Wrong? That’s My Rank Making Space Visual Regression Testing for External URLs With Playwright Jane Goodall’s Famous Last Words European Tech Alternatives 🇪🇺 Independent Type Foundry Advent Calendar – Day 24: NaN Independent Type Foundry Advent Calendar – Day 23: Typotheque Independent Type Foundry Advent Calendar – Day 22: 205TF Independent Type Foundry Advent Calendar – Day 21: HvD Fonts Independent Type Foundry Advent Calendar – Day 20: Frere-Jones Type Independent Type Foundry Advent Calendar – Day 19: Fontwerk Independent Type Foundry Advent Calendar – Day 18: Vectro Independent Type Foundry Advent Calendar – Day 17: Studio René Bieder Independent Type Foundry Advent Calendar – Day 16: R-Typography Independent Type Foundry Advent Calendar – Day 15: David Jonathan Ross Independent Type Foundry Advent Calendar – Day 14: Interval Type Independent Type Foundry Advent Calendar – Day 13: Newglyph Independent Type Foundry Advent Calendar – Day 12: Swiss Typefaces Independent Type Foundry Advent Calendar – Day 11: Sharp Type Independent Type Foundry Advent Calendar – Day 10: Colophon Foundry Independent Type Foundry Advent Calendar – Day 9: Commercial Type Independent Type Foundry Advent Calendar – Day 8: Letters from Sweden Independent Type Foundry Advent Calendar – Day 7: Lineto Independent Type Foundry Advent Calendar – Day 6: Ohno Type Company Independent Type Foundry Advent Calendar – Day 5: Milieu Grotesque Independent Type Foundry Advent Calendar – Day 4: TypeMates Independent Type Foundry Advent Calendar – Day 3: Klim Type Foundry Independent Type Foundry Advent Calendar – Day 2: Dinamo Independent Type Foundry Advent Calendar – Day 1: Grilli Type The Independent Type Foundry Advent Calendar 2022 A Conversation With ChatGPT ChatGPT, please explain websites in the words of William Shakespeare Transient Frameworks Leaving Twitter Behind Converting Your Twitter Archive to Markdown The Wrong Question It Wasn’t Written Syndicating Posts from Your Personal Website to Twitter and Mastodon Suspension None of Your Business Shitty Code Prototypes Doing Our Part Patch That Package Brain Dump Generating Accessibility Test Results for a Whole Website With Evaluatory The CSS Cascade, a Deep Dive Updates About Updates How to Delete Your Commit History in Git Unblocking Your Writing Blocks, Part 2: I’m Not an Expert nor a “Thought Leader” Connections No Wrong Notes Better Options Design Debt Finite and Infinite Games Don’t Assume, Validate. Necessity Is the Ultimate Teacher One Egg Go Deep There Is No Secret Code Balancing Risk Blue Eyes, Brown Eyes The Shortcut Boomerang My RSS Feed Collection of Personal Websites Frequency The Illusion of Control The Decisions Journey Write It Down Nownownow Into the Personal-Website-Verse Considering the Opposite What is it for? Unlimited Bowling. Never done. We Are Team Internet. We Need to Save #NetNeutrality. Progressive Search Data loss (also) by JavaScript Books I Will Definitely Maybe Read in 2017 Starting to Write Notes
CSS :is() :where() the Magic Happens
Matthias Ott · 2025-10-08 · via Matthias Ott

For Blogtober, I dug up a draft about the two CSS pseudo-class functions :is() and :where() that I’d had lying around in my drafts folder for quite some time. Actually, when I originally started writing this post, :is() and :where() had just landed in CSS, and — just like with so many other new CSS features — I was expecting them to “change the way we write CSS.” Both are now widely available baseline features supported by all modern browsers.

We often write about CSS features when they are brand new, but it is equally interesting to see how those shiny new features are actually being used in the wild after they’ve been around for a while. In the case of :is() and :where(), it seems like although browsers support is great and they are two of the most useful modern CSS features, they remain a bit underused. In the latest State of CSS Survey, only 45 % of respondents answered that they have used :where(), for example. So it might make sense to take another look at how these two functions are best used in practice. But first, let’s quickly recap what :is() and :where() actually do.

Both pseudo-class functions, which are included in the CSS Selectors Level 4 Working Draft, take a selector list as their argument. They will then select any element that matches any of the selectors in the list. This allows you to simplify your code significantly. For example, you can stop to repeat to repeat to repeat yourself:

/* A selector list like this… */
main h1, main h2, main h3, main h4, main h5, main h6,
section h1, section h2, section h3, section h4, section h5, section h6, 
article h1, article h2, article h3, article h4, article h5, article h6, 
aside h1, aside h2, aside h3, aside h4, aside h5, aside h6 {
  color: blue;
}

/* …becomes this. */
:is(main, section, article, aside) :is(h1, h2, h3, h4, h5, h6) {
  color: blue;
}

In the example above, all headlines within any of the HTML elements main, section, article, or aside will be styled. The improvements in terms of readability and selector length are obvious. This alone is reason enough to use :is() and :where() more often.

The Forgiven #

But using :is() and :where() has another huge advantage: Usually, when you write a list of selectors and the browser doesn’t understand just one of the selectors in the list, the whole list is deemed invalid and will be ignored by the browser. Like, completely. I wasn’t aware of this for a very long time.

Not so with :is() and :where()! If a selector fails, it will be ignored, but the rest of the selector list will still be used by the browser. This forgiving selector list makes your CSS more flexible and also makes it much easier to use new selectors in your CSS.

/* The whole selector list fails – the heading won’t be red ☹️ */
h1:-moz-shimmy-shimmy-ya, h1.heading {
  color: red;
}

/* This still styles all h1s with a .heading class 🥳 */
h1:is(:-moz-shimmy-shimmy-ya, .heading) {
  color: red;
}

See how this little detail allows you to use new CSS selectors more easily without breaking your code? Huge for using progressive enhancement in your styles.

A Tale of Two Specificities #

But what is the difference between :is() and :where()? The difference lies in how both selectors handle specificity. When you use :is(), the whole rule will always take on the specificity of the most specific selector in the list you provide. If you are using an ID selector, for example, all the other selectors will also share the specificity of this selector, even if they don’t include this or any other ID.

If you use :where(), however, the specificity will always be 0. Both things are important to consider. Let’s say you are writing a rule like this to style the links within a header element and, more specifically, your .site-header:

:is(header, .site-header) a {
  color: black;
}

If we later want to override the color of our link with a element selector, we run into a problem.

header a {
  color: blue;
}

Because the :is() selector includes a class, its specificity is higher than a selector that only uses element names. As a result, the second rule can’t override it because it has lower specificity.

This is where :where() comes in handy. Because the specificity of :where() is always 0, we can use it to write global styles that can easily be overwritten with rules that even have a low specificity. No need to use !important anymore or to artificially increase the specificity of a rule when you want to overwrite the code of a CSS framework or the components of your design system. If you set the margin for the text elements inside a card component like this, for example:

.card :where(h1, h2, h3, p) {
  margin: 0;
}

The specificity of the whole sector will be the same as if we were just using .card, which makes it much easier to override the styles with more specific rules later.

More Use-Cases for :is() and :where() #

When it comes to how people have started applying :is() and :where() in the wild, using it for scoped resets that shouldn’t override component styles might actually be the most common use-case. You will find a lot of CSS resets, layout and typography base styles, and also utility frameworks using :is() and :where(). Manuel, for example, recently revealed his “different type of reset style sheet”, UA+ (user agent plus) in his talk at Smashing Conference. In the reset, he is using :where() almost every:where(), for instance to inherit font styling in form elements:

:where(button, input, select, textarea) {
  font-family: inherit;
  font-size: inherit;
}

But it doesn’t stop there. If we think about how we can combine the two pseudo-class functions with other selectors, it gets really interesting.

Combining :is() and :where() with :has() #

If we throw :has() into the mix, for example, we can create really flexible selectors. Like in this example:

section:has(:is(figure, video, iframe)) {
  padding: 2rem;
  background: var(--media-background-color);
}

We are styling the section, but only if it is the parent container of a figure, video, or iframe element.

We could also use :where() to style layout containers with zero specificity. In this case only if they contain a direct child that we later want to style with a container query:

:where(article, section, aside):has(> .flexible-card) {
  container-type: inline-size;
}

@container (width > 30em) {
  .flexible-card {
    display: grid;
    grid-template-columns: 1fr 2fr;
  }
}

Or, we could style form labels differently when they are followed up by any :invalid form element, using :is() to keep the selector concise:

label:has(+ :is(input, select, textarea):invalid) {
  color: red;
  font-weight: bold;
}

And here’s Manuel again, turning labels into block elements:

:where(label):has(+:where(textarea, input, select)) {
  display: block; 
}

As you can see, both :is() and :where() come with many advantages beyond just reducing the complexity of your code and provide a lot of ways to write more flexible, useful, and maybe even a bit magical CSS. There are a lot of reasons to include them in your arsenal of modern CSS tools today.

And now, I’m curious again: How do use :is() and :where()? Are there any smart techniques that you are using often? Let me know, for example on Mastodon, Bluesky, or by email

This is post 7 of Blogtober 2025.

~

53 Webmentions

13 Reposts

37 Likes

ⓘ Webmentions are a way to notify other websites when you link to them, and to receive notifications when others link to you. Learn more about Webmentions.