Skip to content

Segmented Control

Tailwind CSS segmented control with a sliding thumb, built on native radio inputs for single-choice view, range and billing toggles.

Tailwind CSS Button Groups Responsive Dark #button-group #dark #radio #switch #toggle

Live preview

Open in new tab

Code

A segmented control built with Tailwind CSS: a compact button group where exactly one option is active, with a thumb that slides to the selected segment. The demo shows three versions on a dark zinc theme with an amber accent: a full-width time range switch that updates a statistic, a pill-shaped view switcher with icons, and a small billing toggle with a discount badge. Use it for dashboard filters, view modes, pricing toggles and settings.

How it works

Each control is a <fieldset class="tsc-control"> with a hidden <legend>, so it is a real radio group. Inside, .tsc-track holds the .tsc-indicator thumb and one <label class="tsc-option"> per segment. Every label wraps a visually hidden <input type="radio">, which means clicking, Tab and the arrow keys all work natively, and the form value can be submitted like any radio group. The checked label switches its text color with has-[:checked]:text-zinc-950, and keyboard focus is drawn around the label through has-[:focus-visible]:outline-2.

script.js initializes every .tsc-control on DOMContentLoaded. The place() function reads offsetLeft, offsetTop, offsetWidth and offsetHeight of the checked label and writes them to the --tsc-x, --tsc-y, --tsc-w and --tsc-h custom properties, which style.css uses to size and translate the indicator. The first placement happens without animation; afterwards the tsc-animate class enables the slide transition. A ResizeObserver on the track keeps the thumb aligned when the layout or fonts change. On every change event, if the fieldset has data-tsc-output, the data-tsc-detail text of the chosen radio is written into the element with that id.

Without JavaScript the indicator stays invisible and the fallback rule .tsc-control:not(.tsc-ready) .tsc-option:has(:checked) paints the checked segment amber, so the control still works.

Customization

  • bg-amber-400 on .tsc-indicator: changes the thumb color; the view switcher uses bg-zinc-100 for a neutral look.
  • grid grid-cols-4 on the first .tsc-track: equal-width segments that fill the card; use inline-flex (as in the other two) for segments sized to their content.
  • rounded-2xl / rounded-full / rounded-lg on .tsc-track and matching radius on .tsc-indicator and .tsc-option: set the overall shape.
  • data-tsc-output on .tsc-control and data-tsc-detail on each radio: connect the selection to a live text area; remove both for a plain switch.
  • transition: transform 0.3s in .tsc-animate .tsc-indicator: change the slide speed or easing.
  • px-3 py-1.5 text-xs on the billing options: the compact size; copy it for toolbars and table headers.

Accessibility

Native radio inputs inside a fieldset give screen readers the group name, the option count and the selected state for free, and arrow keys move the selection as users expect. The labels show a visible amber focus ring whenever the hidden radio has keyboard focus. Icons are aria-hidden, and outputs use aria-live="polite" so the updated statistic is announced. Text colors keep WCAG AA contrast on both the dark track and the bright thumb. The sliding transition is removed under prefers-reduced-motion.

Usage notes

Give each control on the page its own radio name so the groups stay independent.

Requirements

Add these to your page (already included in the download):

  • <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>

The Tailwind browser build is for prototyping. In production, compile Tailwind with its CLI or your bundler.

Segmented Control – Tailwind CSS button groups component screenshot
Segmented Control · Tailwind CSS Button Groups

More Button Groups

Editor Button Toolbar – Bootstrap 5 button groups preview

Editor Button Toolbar

Dark Bootstrap 5 text editor toolbar with grouped icon buttons, toggle states, a block style dropdown, arrow key navigation and a working editable area.