Table of Contents
For years, CSS had a big blind spot: it couldn't look up the DOM.
If you wanted to style a parent based on its child, like making a blog post tile look different when it has an image or highlighting a slot card if it includes a "Jackpot" badge, you had to reach for JavaScript.
Not anymore.
With :has()
, CSS can now style elements based on their descendants or child state. And for affiliate marketers managing structured content - casino listings, broker reviews, blog grids - this opens up practical design options with just minimal CSS. They used to require hacks, extra markup, or scripts.
In this article, we'll walk through five real-world use cases where :has()
simplifies common UI challenges. We'll also check an application form completely done in CSS. But first, a quick explanation.
What is :has()
?
:has()
is pseudo-class that allows you to style an element based on what's inside it.
In simpler terms: it acts like a parent selector, letting you apply styles to an element if it contains a specific child or matches a condition within.
For example:
.card:has(.featured-badge) {
background: #fff8dc;
}
This means: if a .card element contains an element with the class .featured-badge anywhere inside it, apply the specified background color.
This unlocks a whole new level of flexibility in your CSS. You can react to inner elements without relying on JavaScript or adding classes manually to parent elements.
Browser support
It's now supported in all major browsers and ready for production use, no fallbacks needed.
Use Case 1: Filter UI That Reacts to Selected State
In any form with grouped checkboxes - like selecting categories, skills, tags, or interests - you often want the group container (e.g. a <fieldset>
, .card
, or .filter-group
) to visually respond when any of its internal checkboxes are selected. This provides instant feedback and helps users keep track of active filters.
Old JavaScript solution
Without :has()
you would have a JavaScript solution like this.
document.querySelectorAll('.filter-group').forEach(group => {
const inputs = group.querySelectorAll('input')
inputs.forEach(input => {
input.addEventListener('change', () => {
const isActive = [...inputs].some(i => i.checked)
group.classList.toggle('active', isActive)
})
})
})
Then you would apply your desired styles to .filter-group.active
selector:
.filter-group.active {
box-shadow: 0 0 0 2px #8bb0ff;
border-color: #5591ff;
}
Now with :has()
.filter-group:has(input:checked) {
box-shadow: 0 0 0 2px #8bb0ff;
border-color: #5591ff;
}
No listeners, no JS. It just works.
Use Case 2: Highlighting Rows in a Table
In review tables, be it for casinos, sportsbooks, brokers or any other type, sometimes you need to higlight a row based on an element "type". For example, You want to highlight rows in a review table that have a "Top Picks" element - a common use case.
Old JavaScript method
You would go over all rows, check if any of them had the specific child element, and if so, you would add another class to the row element, then style it.
document.querySelectorAll('.review-row').forEach(row => {
if (row.querySelector('.badge-top')) {
row.classList.add('highlight');
}
});
.review-row.highlight {
background-color: #fffbea;
border-left: 4px solid gold;
}
Now with :has()
.review-row:has(.badge-top) {
background-color: #fffbea;
border-left: 4px solid gold;
}
Much lighter and easy to maintain in templated layouts.
Use Case 3: Hiding Sibling Elements
There might be cases when you would like to hide an element because a sibling element is missing. For example, you may want to hide the bonus text in certain countries if the terms are not available.
Without :has()
document.querySelectorAll('.review-row').forEach(row => {
if (!row.querySelector('.bonus-terms')) {
const bonus = row.querySelector('.bonus');
if (bonus) bonus.style.display = 'none';
}
});
CSS solution using :has()
.review-row:not(:has(.bonus-terms)) .bonus {
display: none;
}
Use Case 4: Blog Layout That Adapts to Content
You know when a grid of blog posts looks a bit off, one card has a huge title, another has no excerpt, and another is missing an image entirely? Yeah, that.
CSS :has() helps you deal with this kind of uneven content and fill in the missing pieces. You can conditionally style posts based on what's inside, or rather what's not. Check the CodePen below for an example with details, you may want to open the pen in a new tab to see it full-width.
Sure, you could solve this server-side or with utility classes. But sometimes, you're working with third-party content or a CMS that outputs fixed HTML - and all you've got is CSS. :has() is a lifesaver in that case.
Use Case 5: Reorder Items in a Grid
You know stikcy posts in WordPress that stick to the top of the loop? What if you want to do something similar using just CSS? Well, you guessed it, :has()
can help you with that. This can be useful if you want to promote to top a slot game, for example.
CSS with :has()
.slot-card:has(.badge-top) {
order: -1;
}
Note: this may be a poor user experience for people using screen readers, keyboard navigation, etc. as this only changes the visual order, the actual HTML element will be still at its original positon. Use this for your own projects but perhaps not in live websites.
Conclusion
CSS :has()
isn't a new experiment, it's fully supported, fast, and production-ready.
If you build or manage affiliate layouts full of structured content like cards, filters, review tables, and blog posts, this pseudo-class gives you a cleaner, smarter way to build logic directly into your CSS.
And here's a bonus that utlizes all the options described above and some more to create a CSS-only quite interactive form.
No JavaScript required. Better performance - you're doing it all in CSS. And best of all, more control where it used to be impossible. It's time to start using it if you're doing it already.

Written by Levon, Founder of DinoMatic
Hey, I'm Levon - a web developer who loves helping gambling and Forex affiliates build fast, SEO-friendly websites that convert. I've created WP themes like Spinoko, Akurai, and FXT, designed for lean setups that don't compromise on performance or rankings. I write from hands-on experience - I test, tweak, and share what works.