axi0motion

Segmented

A segmented control whose thumb stretches across the gap as it travels and squashes into place.

  • enhancer
  • segmented
  • radio
  • tabs
  • switch
  • spring
  • since 0.2

Background Studio: tune it below, then copy the code

Your system asks for reduced motion: the demo shows its final state and nothing moves.

Live demo

Segmented example

Range

Controls

1

Code

It follows the controls above: change an option and the code changes with it.

<link rel="stylesheet" href="/axi0/motion/motion.css?v=6">
<script src="/axi0/motion/motion.js?v=10" defer></script>

<fieldset data-motion="segmented">
  <legend>Range</legend>
  <label><input type="radio" name="range" value="day"> Day</label>
  <label><input type="radio" name="range" value="week" checked> Week</label>
  <label><input type="radio" name="range" value="month"> Month</label>
  <label><input type="radio" name="range" value="year"> Year</label>
</fieldset>

The wrappers: Segmented.tsx (React, TypeScript) and Segmented.vue (Vue). Both render the same attributes as the HTML; the loader does the rest.

Options

AttributeDefaultWhat it does
data-motion-stretch1how much the thumb stretches on its way (0: none)

Accessibility

- Real radio inputs stay in the page (visually hidden) inside their labels and the fieldset's legend: the group has a name, arrow keys move the choice, Tab reaches the chosen segment, forms submit it. - Focus draws a ring around the segment; the thumb is decoration. - Reduced motion moves the thumb at once, with no stretch. Reduced motion shows every state at once, with no movement, and stops anything that would move on its own. Frame loops and CSS animations pause off screen and in hidden tabs. Only transform, opacity and paint animate, so nothing around it moves.

Size

segmented.js is 1.2 KB gzip, with components-kit.js 3.9 KB it needs. A page loads the loader (2.7 KB) and core.js (1.4 KB) once, whatever it uses.