Toggle

A two-state press button: outline-neutral at rest, highlight-filled when active.

Basic

Active comes from aria-pressed, data-state="active", or a checked .toggle-input — all paint identically. A button toggle gets its press wiring from @stisla/vanilla via data-stisla-toggle (the demos below are live); the native .toggle-input form-data path works with no JS. A <button class="toggle"> with aria-pressed. The active state is shown below.

Keyboard

The toggle behaves like a native button with a sticky pressed state.

  • Tab: focus the toggle
  • Space / Enter: flip aria-pressed

Form data

For a toggle whose state submits with a form, pair a hidden <input class="toggle-input"> with a sibling <label class="toggle">. The browser owns selection, so this is fully interactive with no JS.

Sizes

Add .toggle--sm or .toggle--lg to match the button size cadence.

Icon-only

Add .toggle--icon-only for a square slot. Add an aria-label so the affordance is named for assistive tech.

Circle

Add .toggle--circle alongside .toggle--icon-only for a circular silhouette.

Disabled

Native :disabled on the button (or the paired .toggle-input) dims the chip and blocks pointer events.

Events

Two events fire on the toggle. Both carry the upcoming or new state in detail.pressed.

stisla:toggle:changing fires before the flip and is cancelable. Call preventDefault() on the event to keep the current state, useful when an external check has to confirm the flip first.

stisla:toggle:changed fires after the flip lands. Use it to mirror the state somewhere else or to save the choice.

Customization

These variables retune .toggle. Geometry mirrors .button; the surface follows the interactional trio (rest, accent hover, highlight active).

VariableUse
--toggle-radiusCorner radius
--toggle-heightHard height; sm/lg reassign this
--toggle-padding-inlineHorizontal padding; sm/lg reassign this
--toggle-padding-blockVertical padding; defaults to 0 since the height owns the rhythm
--toggle-gapSpace between an icon and its label
--toggle-font-sizeLabel size
--toggle-font-weightLabel weight
--toggle-bg / -colorRest fill / text
--toggle-border-color / -border-widthRim color / thickness
--toggle-bg-hover / -color-hoverHover fill / text (accent, transient)
--toggle-bg-active / -color-activeActive fill / text (highlight, persistent)
--toggle-border-color-activeActive rim; defaults to the active bg for a clean solid fill
--toggle-ringFocus outline color