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

Counter

A number controlled entirely through CSS state and events.

Live previewreal runtime

Click − or +, or Tab to a button and press Enter or Space.

How it works

  • state()line 2Makes each matching element the owner of an independent state with an initial value.
  • :on()lines 4, 5An event rule: when the event happens on the matched element (or inside it, for bubbling events), the rule’s state mutations run. The cascade picks one winning mutation per state, per trigger and per element.
  • increment()line 4Adds a step to a number or dimension state. In an :on() rule it is the mutation --count: increment(1).
  • decrement()line 5Subtracts a step from a number or dimension state. In an :on() rule it is the mutation --count: decrement(1).
  • contentline 7On elements, a content value that reads state also becomes the element’s DOM text: a real text node, never HTML. The native declaration is kept as written.

A mutable number. state() declares it on .counter, an :on(click) rule on each button changes it with increment() or decrement(), and content writes it into the <output> as real text.

Native CSS alternative

None for a number that changes on click: CSS has no writable values. Without Reactive CSS this needs a few lines of JavaScript.

Limitations

  • The value lives in the page only: a reload starts at 0 again (see the persistent preference example).
  • <output aria-live="polite"> asks screen readers to announce changes; not verified with a screen reader.

Implementation

2 files · 7 lines
style.cssreactive
/* ---- Reactive CSS -------------------------------------------------------------------------- */.counter { --count: state(0); }                  /* each .counter owns a number */.counter .inc:on(click) { --count: increment(1); }.counter .dec:on(click) { --count: decrement(1); }.counter .value { content: var(--count); }        /* the number as real DOM text */
state()Function · hover any red tokenMakes each matching element the owner of an independent state with an initial value.Reference →

Source: site/src/catalog/api/counter/. style.css from its Reactive CSS divider; the layout above it and the shared api.css run but are not shown.

Related

Form mirror

Type in the field and the preview follows; the Clear button resets both.

experimentalstate()bind():on()event()content