Conditional Styles with CSS `:has()`

A simple example of conditional styling with :has and :checked, no JS needed.

I was setting up a simple landing page for Fandwagon and just wanted some text to be strike-through when the user checks a checkbox. So far my landing page has no need for any JavaScript, and thankfully I can keep it that way and still get conditional styles with the :has() pseudo-class.

Demo

Want to know when it's ready? I'll send you one email when it's ready, then delete your email address forever.

❇️ Bonus: inspect the demo above ☝️ in your browser dev tools to see how to use :has in nested CSS, and also how to use color-mix to create a semi-transparent background color.

Code

First, the HTML - a simple form with a checkbox.

<form>
  <p>
    Want to know when it's ready?
    <span
      >I'll send you one email when it's ready, then delete your email address
      forever.</span
    >
  </p>
  <div>
    <input type="checkbox" switch name="subscribe" id="subscribe" />
    <label for="subscribe">Check this box to subscribe to updates</label>
  </div>
</form>

And the CSS for the conditional strike-through

#example-form:has(input:checked) span {
  text-decoration: line-through;
}

Breaking down the selector

The first part #example-form:has(input:checked) is basically saying "find the element with id of example-form that has a child input element that is checked".

:has is basically a very-flexible "parent selector".

Once we've selected the parent that contains the checked input then we select the descendent span element and apply the text-decoration: line-through style.

💥 Done! No JavaScript needed!

You can get pretty far in conditional styling by combining :has and :checked pseudo-classes. If you have any cool example of combining the two then send me an email, I'd love to see!

Hopefully you found this post helpful, if you have any questions you can find me on Twitter.

Don't use TypeScript enum