Technology

How Do You Use CSS :has() to Build Smarter Webflow Layouts in 2026?

Written by
Pravin Kumar
Published on
May 25, 2026

Why was my client's pricing grid buried under a pile of helper classes?

Because the Webflow Designer cannot style a parent based on its children, so we faked it with combo classes. I run a solo Webflow practice in Bengaluru, and on one client's pricing grid I found a stack of helper classes built just to highlight the card that held a "popular" badge. It worked, but it was fragile and hard to read.

Every time the client added a plan, the helper classes had to be reapplied by hand. Miss one, and a card styled wrong. The whole thing existed to answer a simple question: does this card contain a badge? That is exactly the kind of question the CSS :has() selector answers in one line. So I deleted the stack of helper combo classes and replaced them with a single :has() rule. The grid got simpler and stopped breaking.

What is the CSS :has() selector in plain terms?

CSS :has() is the parent selector. It lets you style an element based on what sits inside it. You can say "style this card, but only if it contains a badge" in one rule. Until :has(), CSS could only style children based on parents, never the other way around.

This is the feature web developers asked for over many years. The team at Igalia did much of the engineering work to make it real across browsers. Before it existed, you reached for JavaScript or, in Webflow, a tower of helper classes. Now the browser does it natively. The Webflow Designer's visual styling panel still cannot express :has(), which is the whole reason it belongs in custom code. It is one of the few times a small piece of custom code clearly earns its keep.

Is :has() safe to use in 2026?

Yes, it is safe. The CSS :has() selector became Baseline "newly available" in December 2023, and per the web-features data on web.dev it is scheduled to reach Baseline "widely available" on June 19, 2026. So by the time you read this, it sits in the safest tier of web features.

The support timeline backs that up. Per MDN, browser support arrived in Safari 15.4 in March 2022, Chrome 105 in September 2022, and Firefox 121 in December 2023, so Chrome, Safari, Firefox, and Edge have all shipped it. And as of March 2024, Can I Use put global support for :has() at about 92%. That is a high number for a CSS feature. I treat anything at Baseline "widely available" as ready for client work, which I dig into more in my post on which Baseline features are safe in Webflow.

Where do I actually paste :has() code in Webflow?

You paste it in one of two places. For a rule you want across the whole site, put it in the site-wide custom code in your site settings, inside a style tag in the head. For a rule you want on one page only, drop a custom code embed on that page and put the style tag there.

I lean toward site settings for anything that touches global pieces like the navbar. I use a custom code embed when the rule is tied to one layout, like a single pricing page. Either way, you wrap your CSS in a style tag, and you target Webflow's class names. So if your card has the class "plan-card," you write your :has() rule against ".plan-card" and it just works alongside everything the Webflow Designer already output. No plugin, no extra tool, just plain CSS the browser understands.

What can :has() do on a real Webflow site?

It solves a handful of layout problems cleanly. You can style a CMS Collection Item differently when it contains an image, so cards with art look richer than text-only ones. You can change a form label's color when its input is :invalid, giving instant feedback. And you can hide an empty CMS wrapper that has no children, so blank sections do not leave gaps.

There is more. You can restyle the navbar when a dropdown is open, which is handy for dimming the page behind an open menu. The pattern is always the same. You ask, "Does this parent contain a certain child, or is a child in a certain state?" and then you style the parent. For example, a rule like ".plan-card:has(.badge)" targets only the cards that hold a badge. That single line replaced the whole stack of helper classes on my client's grid. The Finsweet community has shared similar :has() patterns for the Webflow CMS, and they all rest on this one idea.

How did the pricing grid cleanup actually go?

It went from messy to one line. On that client's pricing grid, I deleted the stack of helper combo classes that marked the popular plan. In their place I wrote a single :has() rule that styled any card containing the badge. The visual result was identical, but the build was far simpler.

The real win showed up later. When the client added a new plan and tagged it as popular, the highlight appeared on its own. No helper class to remember, no manual step to forget. The CSS handled it because the rule looked at the card's contents, not at a label I had to apply by hand. That is the quiet power of the parent selector. It moves the logic into one place and keeps it there. I have since reached for :has() on forms and CMS lists for the same reason. Fewer moving parts means fewer ways for a client's site to break when they edit it themselves.

Does :has() slow down my pages?

It can if you write it carelessly, but a tidy rule is fine. The browser has to check the contents of elements to apply a :has() rule, so a broad or deeply nested selector makes it work harder. Keep your :has() selectors shallow and specific, and that cost stays tiny.

I follow one habit. I anchor :has() to a specific class, like ".plan-card:has(.badge)," instead of writing something loose that scans the whole page. A targeted rule only checks a small set of elements, so the browser barely notices. A sloppy rule that watches everything can hurt INP, the responsiveness metric inside Core Web Vitals. I have never seen a clean :has() rule cause a problem in the field, but I have seen overly broad CSS do it. So I treat specificity as a performance choice, not just a style choice. Test your page after adding the rule and watch your Core Web Vitals to be sure.

How does :has() fit with other modern CSS in Webflow?

It fits as one tool in a small kit of modern CSS that Webflow's panel does not expose yet. The parent selector pairs well with newer layout features that also need a touch of custom code. Together they let you build smart layouts without dragging in JavaScript or heavy helper classes.

For example, I use :has() to ask about content and structure, then reach for other features to position things. I covered one of those in my piece on anchor positioning tooltips, which pins a tooltip to its trigger without scripts. And I lean on container queries, which I wrote about in my guide to container queries, to make a component respond to its own width rather than the whole screen. Each of these is a small embed in Webflow, and each does something the visual editor cannot. :has() is the one I reach for most because the parent selector solves so many everyday layout puzzles.

How do I start using :has() in Webflow this week?

Pick one spot where you are already fighting the editor. This week, find a place where you used a helper combo class just to style a parent based on its child, like a highlighted pricing card or a card that holds an image. Note the parent's class name and the child you want to detect. Then write one rule, such as ".plan-card:has(.badge)," wrap it in a style tag, and paste it either in your site settings for a global rule or in a custom code embed for a single page. Keep the selector shallow, test the page, and check your Core Web Vitals afterward.

To go further, read my notes on which Baseline features are safe in Webflow before you add anything new, then explore my guides to anchor positioning tooltips and container queries for the rest of the modern CSS kit. Together they cover most layouts the Webflow Designer cannot handle alone.

If you want help replacing a pile of helper classes with one clean :has() rule on your site, reach out. I would be happy to take a look with you. Let's chat.

Get your website crafted professionally

Let's create a stunning website that drive great results for your business

Contact

Get in Touch

This form help clarify important questions in advance.
Please be as precise as possible as it will save our time.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.