Monday, June 29, 2026

The Shifting Line Between CSS States and JavaScript Occasions


CSS is listening to us. No, not like that. Slightly, CSS is accumulating increasingly pseudo-classes to assist us reply to JavaScript occasions in order that we don’t have to take action with JavaScript itself. However whereas pseudo-classes observe states, not occasions, they certain can really feel like occasion listeners typically (not that it actually issues within the context of CSS).

Then once more, what is CSS lately? For instance, there’s a proposal for event-trigger within the Animation Triggers spec, which might principally hear for occasions and set off animations. In the event you ask me although, the syntax is able to much more than that (suppose: invoker instructions however for CSS).

However to remain in in the present day’s actuality, I’ll stroll you thru the completely different CSS pseudo-classes on the market which might be type of like occasion listeners, earlier than doing the identical for event-trigger, the place I’ll present you the way (I feel) this presently unsupported characteristic would work.

“Occasion listening” pseudo-classes

:hover and :lively

The :hover state captures the second from when the pointerenter occasion fires to when the pointerleave occasion fires, which completely illustrates why pseudo-classes are states, not occasions.

:lively matches the goal (e.g., a hyperlink or button) that’s presently being pressed with a mouse, finger, or stylus, which makes it akin to pointerdown and pointerup/pointercancel.

By the way in which, the pointer-events: none CSS declaration prevents pointer occasions from firing on the chosen aspect!

:focus and :focus-visible

The :focus pseudo-class is akin to the focus and blur (unfocus) JavaScript occasions, however :focus-visible is a little more advanced. :focus-visible triggers when :focus does, however as well as, the browser makes use of a wide range of heuristics to find out whether or not or not a spotlight indicator needs to be proven. Is the person working with a keyboard? Is the aspect a kind management? This actually makes me respect what CSS gives. In truth, one of the best ways to deal with this utilizing JavaScript is to question the CSS pseudo-class:

aspect.addEventListener("focus", (occasion) => {
  if (occasion.goal.matches(":focus-visible")) {
    /* Do one thing */
  }
});

:focus-within (and :has())

JavaScript excels on the “if A is Y, then do Z to B” type of stuff. We will traverse the DOM, leverage occasion propagation, and way more. In that regard, CSS can really feel a bit restricted. Nonetheless, CSS is evolving shortly. It has many new if-this-do-that options similar to scroll-driven animations, and it’ll have extra sooner or later. HTML is doing the identical with devoted elements similar to

, which all have accompanying CSS options.

I’ll point out a few of that later, truly. In a extra holistic sense, what we have now is :focus-within, which matches if a toddler has focus, and :has(), which accepts any legitimate selector and matches if such a relationship exists between the 2 selectors.

For instance, these two selectors do the very same factor:

kind:focus-within {
  /* Fashion the shape when one thing inside has focus */
}

kind:has(:focus) {
  /* Fashion the shape when one thing inside has focus */
}

:checked

It’s pretty apparent what :checked does. The JavaScript occasion that’s most synonymous with it’s change, which fires when the worth of an ,