Shopping cart
Three cart lines with − / + / Remove, a subtotal per line, the item count and total, an "empty cart" message, and Checkout and "Empty cart" buttons that are disabled while the cart is empty. Local only: Checkout does nothing.
A pressed-state toggle button and a disclosure button. Their aria-pressed and aria-expanded attributes are real DOM attributes, kept in sync with Reactive CSS state.
| name | value | previous | changes |
|---|---|---|---|
| Waiting for the preview to start. | |||
state(initial, bind(attribute)) (0.5.2):
aria-pressed="true" starts pressed);.toggle { --pressed: state(false, bind(aria-pressed)); on: click(toggle(--pressed)); }
.toggle[aria-pressed="true"] { background: #1d4ed8; color: #fff; }
<button>.[aria-pressed="true"], [aria-expanded="true"] + .panel).<details>/<summary> needs no script and no library: prefer it when its look fits;Keeping aria-pressed and aria-expanded in sync with the visual state: one click listener per button that flips the attribute.
bind() only writes the owner’s own attribute: here, the button. The panel’s visibility follows from CSS, not from its own hidden attribute. Binding hidden on the panel would need the panel to own a state that the button’s click changes, and an action reaches only the clicking element and its ancestors.aria-expanded later is not read back; the next click overwrites it (reported once).content: … / "" gives them empty alternative text).aria-controls links the disclosure to its panel./* ---- toggle: the state is bound to the button's own aria-pressed (0.5.2) ---------------------- The markup gives the initial value (aria-pressed="true" starts pressed). Each click writes the attribute; native CSS styles it, and assistive technology reads it. */.toggle { --pressed: state(false, bind(aria-pressed)); on: click(toggle(--pressed)); }.toggle[aria-pressed="true"] { background: #1d4ed8; border-color: #1d4ed8; color: #fff; }.toggle[aria-pressed="true"]::after { content: " ✓" / ""; }/* ---- disclosure: the button's aria-expanded, and its panel next to it ------------------------ */.disclosure { --open: state(false, bind(aria-expanded)); on: click(toggle(--open)); }.disclosure + .panel { display: none; padding: 8px 0 0; }.disclosure[aria-expanded="true"] + .panel { display: block; }.disclosure::before { content: "▸ " / ""; }.disclosure[aria-expanded="true"]::before { content: "▾ " / ""; }Source: the library's examples/accessible-toggle/. style.css from its first section comment; the layout above it runs but is not shown. Written in the 0.8 syntax (on:, bind:, text:, attr:), which 0.9.0 still runs; see Migrating from 0.8 for the 0.9 forms.
Three cart lines with − / + / Remove, a subtotal per line, the item count and total, an "empty cart" message, and Checkout and "Empty cart" buttons that are disabled while the cart is empty. Local only: Checkout does nothing.
A collapsible list of three sample notifications. Each can be marked read (a toggle with aria-pressed) or dismissed. "Undo dismiss" restores the last dismissed one, "Dismiss all" clears the list, and the unread count updates as real text.
A sign-up form using native constraint validation: required fields, type="email", minlength. A company field appears and becomes required only for business accounts. Submit is disabled until the terms are accepted, and error messages appear after the first submit attempt. Nothing is sent.