This content originally appeared on Go Make Things and was authored by Go Make Things
I finally got a chance to work with the :has()
CSS pseudo-class as part of Kelp, my UI library for people who love HTML.
Today, I wanted to quickly look at what it is and how it works. Let’s dig in!
If an element has a child or sibling, style the element
CSS has long had all sorts of interesting selectors for targeting attributes that start or end with certain letters (^=
and $=
, respectively), or that have a certain parent/child (.parent > .child
) or sibling (.sibling + .sibling
) relationship.
But those selectors always target the last item in the selector chain.
For example, this applies styles to the .merlin
class, if it’s a direct descendant of .wizard
.
.wizard > .merlin {
/* ... */
}
But what if you wanted to apply styles to .wizard
if it contained .merlin
as a direct descendant? The :has()
pseudo-selector let’s you do that!
Here, we’re using :has()
to style .wizard
instead of .merlin
.
.wizard:has(> .merlin) {
/* ... */
}
This says that if an element with the .wizard
class :has()
a direct descendant with the .merlin
class, add these styles.
As an aside, this is why I love CSS. You write it basically the way you’d speak it.
Siblings
Another cool use of :has()
is styling elements with siblings.
You may be familiar with a pattern like this…
.wizard + .wizard {
border-block-end: 1px solid #e5e5e5;
}
Let’s say you wanted borders between items but not after the last one.
This approach styles the sibling, not the item before it. So you either need to get weird with your CSS, or add a border before your elements instead of after.
.wizard + .wizard {
border-block-start: 1px solid #e5e5e5;
}
But with :has()
, can you target any item that has a sibling, rather than the sibling itself.
.wizard:has(+ .wizard) {
border-block-end: 1px solid #e5e5e5;
}
How I’m using :has()
In Kelp, I use :has()
to add borders between details
elements when they’re combined into a disclosure group.
I also use to target a label
if it has an input with the [trigger]
attribute on it.
<label>
<input type="checkbox" trigger>
Show Password
</label>
label:has([trigger]) {
/* Style the label */
}
Modern CSS rocks!
Like this? A Lean Web Club membership is the best way to support my work and help me create more free content.
This content originally appeared on Go Make Things and was authored by Go Make Things

Go Make Things | Sciencx (2025-07-22T14:30:00+00:00) The :has() CSS pseudo-class. Retrieved from https://www.scien.cx/2025/07/22/the-has-css-pseudo-class/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.