The:has() Selector: Twelve Patterns That Replaced My JavaScript
:has() is the parent selector CSS needed for decades. Here are the real-world patterns where it eliminated JavaScript for me. The:has() selector is the most impactful CSS addition in a decade. For the first time, you can style an element based on its descendants. the parent selector that CSS lacked since the beginning. I have been using it in production for over a year, and it has replaced JavaScript in dozens of patterns. I want to share the real-world patterns where it eliminated JavaScript for me. The first time I used:has() was on a form. I needed the submit button to disable when any input was invalid. The old approach was a JavaScript validation loop that toggled a disabled class. With:has(), it was one CSS rule. That single rule replaced thirty lines of JavaScript and an event listener. I was hooked. Form Validation Styling Before:has(), styling a form differently when it contained invalid inputs required JavaScript to check validity and toggle classes. Now it is one selector. /* Disable submit when form has invalid inputs */ form:has(input:invalid).submit-btn { opacity: 0.5; pointer-events: none; } /* Highlight invalid fields with error styling…