Documents v0.9.0 · previews run the real runtime · experimental features are marked exp

on:

declarationsince 0.20.8 syntax

Connects triggers to the actions they run. A normal declaration: specificity, source order, @media and :hover decide which one applies. 0.8 syntax, still supported in 0.9.

On this page · 8 sections+
Caution · 0.8.x compatibility syntax

This page documents 0.8 syntax that Reactive CSS 0.9.0 still runs. New code uses the 0.9 form: see Legacy 0.8.x compatibility.

Syntax

on: <trigger>(<action>#)#;

registry syntax: on: trigger(action, ...), ...

Parameters

triggerclick(), change(), input(), pointerenter(), pointerleave(), focus(), blur(); since 0.5.1 focusin(), focusout(), reset(), animationend(), animationcancel(), transitionend(), transitioncancel(); and key(), outside()one or more
Each trigger lists the actions to run. See Triggers and Lifecycle triggers.
actionset(), toggle(), increment(), decrement(), cycle(), prevent() (experimental)one or more
Applied in order. Each state action may end with an optional closest(selector) scope; prevent() takes no arguments.

Effect

No value. One delegated listener per event type runs the actions of the on: that currently applies to the element.

Example

.switch {  --on: state(false);  --attr-aria-checked: var(--on);  background: when(--on, #f2542d, #d9d5cf);  transition: background 200ms;}.switch::after {  translate: when(--on, 32px, 0);}.switch:on(click) {  --on: toggle();}
state()Function · hover any red tokenMakes each matching element the owner of an independent state with an initial value.Reference →
Resultvisual only
waiting for interaction

Behavior

  • 0.9. The new form is one :on() rule per trigger: .b:on(click) { --open: toggle(); }. on: keeps working in 0.9 with its 0.8 behavior: its actions run one after another, so two increment() of one shared state in one event give +2, where two :on() mutations give +1. on: is still the way to target an explicit owner with closest().
  • When the event fires, the computed on: of the candidate elements is read, so the cascade, :hover and @media are respected at that moment.
  • Only one on: value applies per element. Put every trigger for an element in one declaration.
  • A single unconditional on: rule is checked against its sheet’s disabled state and media before running.
  • Actions change state; one action, prevent(), cancels the event's native default instead (experimental, click() and key() only).

Supported contexts

  • Element rules in inline or same-origin stylesheets.
  • Ignored, with a warning, in cross-origin sheets, and in <style> when trustInlineStyles is false.

Limitations

  • Can change only declared state cells: no DOM, network, storage or script.
  • Needs CSS.registerProperty() (Chrome 78+, Firefox 128+, Safari 16.4+).
  • State values cannot contain commas.
  • If styles are dirty when the event fires, reading the computed value forces a style recalculation.
Experimental · syntax may change between minor versions