Skip to content

Segmented Control

<quiet-segmented-control> stable since 6.1 form-associated This component is a form-associated custom element. It will submit its value when given a name and placed inside a <form>.

Presents a group of segments the user can pick an option from. Reach for it when a compact, always-visible choice is preferable over a select or radio group.

Selections take effect as soon as the user makes them, and the control holds a value that submits with forms like any other form control. For distinct panels of independent content, use a tab list instead, which provides dedicated semantics for tabs and panels.

Photos Videos Favorites
<quiet-segmented-control label="View" name="view" value="photos">
  <quiet-segment value="photos">Photos</quiet-segment>
  <quiet-segment value="videos">Videos</quiet-segment>
  <quiet-segment value="favorites">Favorites</quiet-segment>
</quiet-segmented-control>

Examples Jump to heading

Labeling Jump to heading

Unlike most form controls, segmented controls don't display a built-in label. Use the label attribute to name the control for assistive devices, and place the control where its purpose is clear from the surrounding context, such as next to a heading, in a toolbar, or beside the content it affects. In this example, selecting a filter dims the photos that don't match.

Smokey's photos

All Indoors Outdoors
A gray and white cat sleeps on a blanket with evening lights in the background A kitten sleeps peacefully on the floor An orange cat sleeps peacefully at the edge of a bed
<div id="segmented-control__labeling">
  <header>
    <h4>Smokey's photos</h4>
    <quiet-segmented-control label="Filter photos" name="filter" value="all" size="sm">
      <quiet-segment value="all">All</quiet-segment>
      <quiet-segment value="indoors">Indoors</quiet-segment>
      <quiet-segment value="outdoors">Outdoors</quiet-segment>
    </quiet-segmented-control>
  </header>

  <div>
    <img data-place="outdoors" src="https://images.unsplash.com/photo-1737912031624-e17ba0d7f673?q=80&w=1000&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="A gray and white cat sleeps on a blanket with evening lights in the background">
    <img data-place="indoors" src="https://images.unsplash.com/photo-1707520595303-d6b499aa84af?q=80&w=1000&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="A kitten sleeps peacefully on the floor">
    <img data-place="indoors" src="https://images.unsplash.com/photo-1626603084013-1bf8c6627707?q=80&w=1000&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="An orange cat sleeps peacefully at the edge of a bed">
  </div>
</div>

<style>
  #segmented-control__labeling {
    header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 1rem;
      margin-block-end: 1rem;

      h4 {
        margin-block: 0;
      }
    }

    div {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 0.5rem;
    }

    img {
      width: 100%;
      aspect-ratio: 1;
      border-radius: var(--quiet-border-radius-md);
      object-fit: cover;
      transition: 300ms opacity ease;
    }

    &:has([value='indoors']:state(checked)) img:not([data-place='indoors']),
    &:has([value='outdoors']:state(checked)) img:not([data-place='outdoors']) {
      opacity: 0.3;
    }
  }
</style>

If a heading or other visible text already describes the control, you can point aria-labelledby at it instead of setting label. This keeps the accessible name in sync with the text users see.

<h4 id="gallery-title">Kitten gallery</h4>

<quiet-segmented-control aria-labelledby="gallery-title" name="view" value="photos">
  <quiet-segment value="photos">Photos</quiet-segment>
  <quiet-segment value="videos">Videos</quiet-segment>
</quiet-segmented-control>

Providing an initial value Jump to heading

Use the value attribute to provide an initial value for the segmented control. The value should match an existing segment's value.

Small Medium Large
<quiet-segmented-control label="Food size" name="size" value="medium">
  <quiet-segment value="small">Small</quiet-segment>
  <quiet-segment value="medium">Medium</quiet-segment>
  <quiet-segment value="large">Large</quiet-segment>
</quiet-segmented-control>

Adding icons Jump to heading

Segments can contain icons alongside their labels. Slot a <quiet-icon> into the segment before its text.

Photos Videos Favorites
<quiet-segmented-control label="View" name="view" value="photos">
  <quiet-segment value="photos">
    <quiet-icon name="photo"></quiet-icon> Photos
  </quiet-segment>
  <quiet-segment value="videos">
    <quiet-icon name="video"></quiet-icon> Videos
  </quiet-segment>
  <quiet-segment value="favorites">
    <quiet-icon name="heart"></quiet-icon> Favorites
  </quiet-segment>
</quiet-segmented-control>

Icon-only segments Jump to heading

For a more compact control, you can show only icons. Give each icon a label that describes the segment.

<quiet-segmented-control label="Gallery layout" name="layout" value="grid">
  <quiet-segment value="list">
    <quiet-icon name="list" label="List view"></quiet-icon>
  </quiet-segment>
  <quiet-segment value="grid">
    <quiet-icon name="layout-grid" label="Grid view"></quiet-icon>
  </quiet-segment>
  <quiet-segment value="calendar">
    <quiet-icon name="calendar-month" label="Calendar view"></quiet-icon>
  </quiet-segment>
</quiet-segmented-control>

The icon's label won't be displayed, but it gives the segment an accessible name. You should always include one when a segment has no visible text.

Changing the size Jump to heading

Use the size attribute to change the segmented control's size. All segments inherit their size from the control.

Dry Wet Treats Dry Wet Treats Dry Wet Treats Dry Wet Treats Dry Wet Treats
<quiet-segmented-control size="xs" label="Food type" name="size-xs" value="dry">
  <quiet-segment value="dry">Dry</quiet-segment>
  <quiet-segment value="wet">Wet</quiet-segment>
  <quiet-segment value="treats">Treats</quiet-segment>
</quiet-segmented-control>

<quiet-segmented-control size="sm" label="Food type" name="size-sm" value="dry">
  <quiet-segment value="dry">Dry</quiet-segment>
  <quiet-segment value="wet">Wet</quiet-segment>
  <quiet-segment value="treats">Treats</quiet-segment>
</quiet-segmented-control>

<quiet-segmented-control size="md" label="Food type" name="size-md" value="dry">
  <quiet-segment value="dry">Dry</quiet-segment>
  <quiet-segment value="wet">Wet</quiet-segment>
  <quiet-segment value="treats">Treats</quiet-segment>
</quiet-segmented-control>

<quiet-segmented-control size="lg" label="Food type" name="size-lg" value="dry">
  <quiet-segment value="dry">Dry</quiet-segment>
  <quiet-segment value="wet">Wet</quiet-segment>
  <quiet-segment value="treats">Treats</quiet-segment>
</quiet-segmented-control>

<quiet-segmented-control size="xl" label="Food type" name="size-xl" value="dry">
  <quiet-segment value="dry">Dry</quiet-segment>
  <quiet-segment value="wet">Wet</quiet-segment>
  <quiet-segment value="treats">Treats</quiet-segment>
</quiet-segmented-control>

Pill segmented controls Jump to heading

Add the pill attribute to round the track, thumb, and segments together with a single attribute.

Sleepy Playful Chaotic
<quiet-segmented-control label="Cat mood" name="mood" value="sleepy" pill>
  <quiet-segment value="sleepy">Sleepy</quiet-segment>
  <quiet-segment value="playful">Playful</quiet-segment>
  <quiet-segment value="chaotic">Chaotic</quiet-segment>
</quiet-segmented-control>

Changing the orientation Jump to heading

Set the orientation attribute to vertical to change the segmented control's orientation. The thumb and arrow keys work the same way in both orientations.

Clean Scoop soon Biohazard
<quiet-segmented-control label="Litter box status" name="status" value="clean" orientation="vertical">
  <quiet-segment value="clean">Clean</quiet-segment>
  <quiet-segment value="scoop-soon">Scoop soon</quiet-segment>
  <quiet-segment value="biohazard">Biohazard</quiet-segment>
</quiet-segmented-control>

Switching views Jump to heading

Listen for the quiet-input event to swap content as the user selects segments. This example toggles the hidden attribute on the view that matches the segmented control's value.

Photos Videos Favorites
Sunbeam portraits, windowsill loafs, and mid-yawn close-ups of every cat in the colony.
<div id="segmented-control__switching-views">
  <quiet-segmented-control label="Cat gallery" name="gallery" value="photos">
    <quiet-segment value="photos">Photos</quiet-segment>
    <quiet-segment value="videos">Videos</quiet-segment>
    <quiet-segment value="favorites">Favorites</quiet-segment>
  </quiet-segmented-control>

  <div data-view="photos">Sunbeam portraits, windowsill loafs, and mid-yawn close-ups of every cat in the colony.</div>
  <div data-view="videos" hidden>Midnight zoomies, cardboard box heists, and slow-motion pounces captured on film.</div>
  <div data-view="favorites" hidden>The very best whiskers, hand-picked and heart-marked for repeat viewing.</div>
</div>

<script>
  const gallery = document.getElementById('segmented-control__switching-views');
  const gallerySegments = gallery.querySelector('quiet-segmented-control');

  gallerySegments.addEventListener('quiet-input', () => {
    gallery.querySelectorAll('[data-view]').forEach(view => {
      view.hidden = view.getAttribute('data-view') !== gallerySegments.value;
    });
  });
</script>

<style>
  #segmented-control__switching-views {
    [data-view] {
      margin-block-start: 1rem;
      color: var(--quiet-text-muted);
    }
  }
</style>

This recipe only toggles visibility. If you're presenting full panels of content, use a tab list instead, which provides the correct semantics for tabs and panels.

You can also switch regions without any JavaScript. Each segment exposes a checked custom state, so a containing element can watch it with :has() and show the matching region.

About Diet Quirks
Sir Pounce is a distinguished tuxedo cat with a passion for supervising household chores.
Strictly salmon pâté, served at room temperature, with the occasional stolen green bean.
Sleeps in the bathroom sink and answers exclusively to the sound of a cheese wrapper.
<div id="segmented-control__switching-views-css">
  <quiet-segmented-control label="Cat profile" name="profile" value="about">
    <quiet-segment value="about">About</quiet-segment>
    <quiet-segment value="diet">Diet</quiet-segment>
    <quiet-segment value="quirks">Quirks</quiet-segment>
  </quiet-segmented-control>

  <div data-view="about">Sir Pounce is a distinguished tuxedo cat with a passion for supervising household chores.</div>
  <div data-view="diet">Strictly salmon pâté, served at room temperature, with the occasional stolen green bean.</div>
  <div data-view="quirks">Sleeps in the bathroom sink and answers exclusively to the sound of a cheese wrapper.</div>
</div>

<style>
  #segmented-control__switching-views-css {
    [data-view] {
      display: none;
      margin-block-start: 1rem;
      color: var(--quiet-text-muted);
    }

    &:has([value='about']:state(checked)) [data-view='about'],
    &:has([value='diet']:state(checked)) [data-view='diet'],
    &:has([value='quirks']:state(checked)) [data-view='quirks'] {
      display: block;
    }
  }
</style>

Each value needs its own rule, since CSS can't match one element's attribute against another's. For more than a handful of views, the JavaScript recipe above scales better.

Transitioning between views Jump to heading

A little CSS makes view changes feel smooth. This example uses the same checked custom state and :has() technique to crossfade between images as the selection changes, without any JavaScript.

Pancake Waffles Crumpet Biscuit
A tabby kitten sleeps next to a toy mouse. A fluffy kitten sprawls out on a red pillow with its eyes closed and paws in the air. A kitten sits upright looking at the camera. A gray kitten peeks out from behind a tree.
<div id="segmented-control__transitioning-views">
  <quiet-segmented-control label="Cat of the day" name="cat" value="pancake">
    <quiet-segment value="pancake">Pancake</quiet-segment>
    <quiet-segment value="waffles">Waffles</quiet-segment>
    <quiet-segment value="crumpet">Crumpet</quiet-segment>
    <quiet-segment value="biscuit">Biscuit</quiet-segment>
  </quiet-segmented-control>

  <div>
    <img data-cat="pancake" src="https://images.unsplash.com/photo-1515073883629-5e2924e3e106?q=80&w=1000&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="A tabby kitten sleeps next to a toy mouse.">
    <img data-cat="waffles" src="https://images.unsplash.com/photo-1498336179775-9836baef8fdf?q=80&w=1000&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="A fluffy kitten sprawls out on a red pillow with its eyes closed and paws in the air.">
    <img data-cat="crumpet" src="https://plus.unsplash.com/premium_photo-1661676191997-0c0cece2a683?q=80&w=500&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="A kitten sits upright looking at the camera.">
    <img data-cat="biscuit" src="https://images.unsplash.com/photo-1503844281047-cf42eade5ca5?q=80&w=1000&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="A gray kitten peeks out from behind a tree.">
  </div>
</div>

<style>
  #segmented-control__transitioning-views {
    div {
      display: grid;
      margin-block-start: 1rem;
    }

    img {
      grid-area: 1 / 1;
      width: 100%;
      aspect-ratio: 16 / 9;
      border-radius: var(--quiet-border-radius-md);
      object-fit: cover;
      opacity: 0;
      transition: 600ms opacity ease;
    }

    &:has([value='pancake']:state(checked)) [data-cat='pancake'],
    &:has([value='waffles']:state(checked)) [data-cat='waffles'],
    &:has([value='crumpet']:state(checked)) [data-cat='crumpet'],
    &:has([value='biscuit']:state(checked)) [data-cat='biscuit'] {
      opacity: 1;
    }
  }
</style>

Stretching to full width Jump to heading

Segmented controls are sized to fit their content by default. To stretch one across its container, set its width and let each segment flex to fill the available space.

All Kittens Seniors
<quiet-segmented-control id="segmented-control__full-width" label="Adoption filter" name="filter" value="all">
  <quiet-segment value="all">All</quiet-segment>
  <quiet-segment value="kittens">Kittens</quiet-segment>
  <quiet-segment value="seniors">Seniors</quiet-segment>
</quiet-segmented-control>

<style>
  #segmented-control__full-width {
    width: 100%;

    quiet-segment {
      flex: 1;
    }
  }
</style>

Handling overflow Jump to heading

Segmented controls don't wrap or scroll on their own. If there are more segments than the available space can show, place the control inside a scroller so users can reach the rest. A little padding on the scroller's content part keeps focus rings from being clipped at the edges.

All Tabby Siamese Persian Bengal Sphynx Ragdoll Calico
<quiet-scroller id="segmented-control__overflow" style="max-width: 340px;">
  <quiet-segmented-control label="Filter by breed" name="breed" value="all">
    <quiet-segment value="all">All</quiet-segment>
    <quiet-segment value="tabby">Tabby</quiet-segment>
    <quiet-segment value="siamese">Siamese</quiet-segment>
    <quiet-segment value="persian">Persian</quiet-segment>
    <quiet-segment value="bengal">Bengal</quiet-segment>
    <quiet-segment value="sphynx">Sphynx</quiet-segment>
    <quiet-segment value="ragdoll">Ragdoll</quiet-segment>
    <quiet-segment value="calico">Calico</quiet-segment>
  </quiet-segmented-control>
</quiet-scroller>

<style>
  #segmented-control__overflow {
    /* Make room for focus rings */
    &::part(content) {
      padding: var(--quiet-focus-width);
    }
  }
</style>

If there are enough options to scroll, consider whether a select or radio group would serve users better.

Read-only Jump to heading

Add the readonly attribute to prevent the user from changing the selection. Unlike disabled controls, read-only controls remain focusable and their value is submitted with containing forms.

Once daily Twice daily Free feeding
<quiet-segmented-control label="Feeding schedule" name="schedule" value="twice-daily" readonly>
  <quiet-segment value="once-daily">Once daily</quiet-segment>
  <quiet-segment value="twice-daily">Twice daily</quiet-segment>
  <quiet-segment value="free-feeding">Free feeding</quiet-segment>
</quiet-segmented-control>

Disabling Jump to heading

Use the disabled attribute to disable the segmented control and prevent form submission.

Photos Videos Favorites
<quiet-segmented-control label="View" name="view" value="photos" disabled>
  <quiet-segment value="photos">Photos</quiet-segment>
  <quiet-segment value="videos">Videos</quiet-segment>
  <quiet-segment value="favorites">Favorites</quiet-segment>
</quiet-segmented-control>

To disable individual options, add the disabled attribute to one or more segments.

Photos Videos Favorites
<quiet-segmented-control label="View" name="view" value="photos">
  <quiet-segment value="photos">Photos</quiet-segment>
  <quiet-segment value="videos" disabled>Videos</quiet-segment>
  <quiet-segment value="favorites">Favorites</quiet-segment>
</quiet-segmented-control>

Validation Jump to heading

The required attribute can be applied to enable validation using the Constraint Validation API . This will prevent form submission until a segment is selected.

Who are you shopping for?

Kittens Adults Seniors
Submit Reset
<form action="about:blank" method="get" target="_blank">
  <p>Who are you shopping for?</p>
  <quiet-segmented-control label="Who are you shopping for?" name="audience" required>
    <quiet-segment value="kittens">Kittens</quiet-segment>
    <quiet-segment value="adults">Adults</quiet-segment>
    <quiet-segment value="seniors">Seniors</quiet-segment>
  </quiet-segmented-control>
  <br>
  <quiet-button type="submit" variant="primary">Submit</quiet-button>
  <quiet-button type="reset">Reset</quiet-button>
</form>

Using custom validation Jump to heading

Use the setCustomValidity() method to make the segmented control invalid and show a custom error message on submit. This will override all other validation parameters. To clear the error, remove the attribute or set it to an empty string.

Which toy should we restock?

Feather wand Laser pointer Catnip mouse
Submit
<form action="about:blank" method="get" target="_blank" id="segmented-control__custom-validation">
  <p>Which toy should we restock?</p>
  <quiet-segmented-control label="Which toy should we restock?" name="toy" value="feather-wand">
    <quiet-segment value="feather-wand">Feather wand</quiet-segment>
    <quiet-segment value="laser-pointer">Laser pointer</quiet-segment>
    <quiet-segment value="catnip-mouse">Catnip mouse</quiet-segment>
  </quiet-segmented-control>
  <br>
  <quiet-button type="submit" variant="primary">Submit</quiet-button>
</form>

<script type="module">
  import { allDefined } from '/dist/quiet.js';

  await allDefined();

  const form = document.getElementById('segmented-control__custom-validation');
  const segmentedControl = form.querySelector('quiet-segmented-control');

  segmentedControl.setCustomValidity('Not so fast, bubba!');
</script>

Styling validation Jump to heading

You can style valid and invalid segmented controls using the user-valid and user-invalid custom states. These styles are only shown after the user interacts with the form control or when the form is submitted. The :valid and :invalid pseudo classes are also available, but they match even before the user has had a chance to fill out the form.

Who are you shopping for?

Kittens Adults Seniors
Submit Reset
<form action="about:blank" method="get" target="_blank" class="segmented-control__validation-custom">
  <p>Who are you shopping for?</p>
  <quiet-segmented-control label="Who are you shopping for?" name="audience" required>
    <quiet-segment value="kittens">Kittens</quiet-segment>
    <quiet-segment value="adults">Adults</quiet-segment>
    <quiet-segment value="seniors">Seniors</quiet-segment>
  </quiet-segmented-control>
  <br>
  <quiet-button type="submit" variant="primary">Submit</quiet-button>
  <quiet-button type="reset">Reset</quiet-button>
</form>

<style>
  .segmented-control__validation-custom {
    quiet-segmented-control:state(user-valid) {
      outline: solid 2px var(--quiet-constructive-stroke-mid);
      outline-offset: .5rem;
    }

    quiet-segmented-control:state(user-invalid) {
      outline: solid 2px var(--quiet-destructive-stroke-mid);
      outline-offset: .5rem;
    }
  }
</style>

If you're using the CSS utilities, add the quiet-user-valid and quiet-user-invalid classes to any form control for automatic validation styling.

Color scheme pickers Jump to heading

A segmented control is a natural fit for letting users choose between light, dark, and system color schemes.

<quiet-segmented-control label="Color scheme" name="scheme" value="light" pill id="segmented-control__color-scheme">
  <quiet-segment value="light">
    <quiet-icon name="sun" label="Light"></quiet-icon>
  </quiet-segment>
  <quiet-segment value="dark">
    <quiet-icon name="moon" label="Dark"></quiet-icon>
  </quiet-segment>
  <quiet-segment value="system">
    <quiet-icon name="device-desktop" label="System"></quiet-icon>
  </quiet-segment>
</quiet-segmented-control>

Styling segmented controls Jump to heading

Segmented controls come with a simple, minimal appearance. Feel free to customize them with your own styles. The sliding selection indicator is exposed through the thumb part, and its animation speed is controlled by the --thumb-speed custom property. This example slows the animation down and combines the pill attribute with custom colors.

Sunrise Midday Sunset
<quiet-segmented-control id="segmented-control__custom-thumb" label="Nap time" name="nap-time" value="sunset" pill>
  <quiet-segment value="sunrise">Sunrise</quiet-segment>
  <quiet-segment value="midday">Midday</quiet-segment>
  <quiet-segment value="sunset">Sunset</quiet-segment>
</quiet-segmented-control>

<style>
  #segmented-control__custom-thumb {
    --thumb-speed: 400ms;
    background-color: #1d1f3a;

    &::part(thumb) {
      background: linear-gradient(45deg, #f97644, #ec4899);
    }

    quiet-segment {
      color: #a3a8cc;
    }

    /* Suppress the hover tint while the thumb is sliding beneath the segments */
    &:not(:state(sliding)) quiet-segment:hover:not(:state(checked)) {
      background-color: color-mix(in oklab, #1d1f3a, white 10%);
      color: white;
    }

    quiet-segment:state(checked) {
      color: white;
    }
  }
</style>

Keyboard support Jump to heading

Tab to the segmented control to focus the selected segment, then use the keys below.

Key Action
Selects the previous or next segment, wrapping around (reversed in RTL)
Selects the previous segment, wrapping to the last
Selects the next segment, wrapping to the first
Home Selects the first segment
End Selects the last segment
Space Selects the focused segment

API Jump to heading

Importing Jump to heading

The autoloader is the recommended way to import components but, if you prefer to do it manually, the following code snippets will be helpful.

CDN Self-hosted

To manually import <quiet-segmented-control> from the CDN, use the following code.

import 'https://cdn.quietui.org/v6.0.0/components/segmented-control/segmented-control.js';

To manually import <quiet-segmented-control> from a self-hosted distribution, use the following code. Remember to replace /path/to/quiet with the appropriate local path.

import '/path/to/quiet/components/segmented-control/segmented-control.js';

Slots Jump to heading

Segmented Control supports the following slots. Learn more about using slots

Name Description
(default) The segments to place in the group.

Properties Jump to heading

Segmented Control has the following properties that can be set with corresponding attributes. In many cases, the attribute's name is the same as the property's name. If an attribute is different, it will be displayed after the property. Learn more about attributes and properties

Property Description Reflects Type Default
label The segmented control's label. The label isn't displayed, but it gives the control an accessible name for assistive technology and should always be provided. string
name The name of the segmented control. This will be submitted with the form as a name/value pair. string
value The segmented control's current value. Set this to change the selected segment. string ''
form The form to associate this control with. If omitted, the closest containing <form> will be used. The value of this attribute must be an ID of a form in the same document or shadow root. string
required Indicates at least one option in the segmented control is required. boolean false
readonly Makes the segmented control read-only. The user can focus the control and move through segments, but the selection can't be changed. Unlike disabled controls, the value is still submitted with the form. boolean false
disabled Disables the segmented control. boolean false
size The segmented control's size. 'xs' | 'sm' | 'md' | 'lg' | 'xl' 'md'
orientation The segmented control's orientation. 'horizontal' | 'vertical' 'horizontal'
pill Draws the segmented control, its thumb, and its segments in a pill shape. boolean false
ignoreReducedMotion
ignore-reduced-motion
By default, the thumb won't animate when the user indicates a preference for reduced motion. Use this attribute to override this behavior when necessary. boolean false

Methods Jump to heading

Segmented Control supports the following methods. You can obtain a reference to the element and call them like functions in JavaScript. Learn more about methods

Name Description Arguments
focus() Sets focus to the selected segment or the first segment if none are selected. options: FocusOptions
checkValidity() Checks if the form control has any restraints and whether it satisfies them. If invalid, false will be returned and the invalid event will be dispatched. If valid, true will be returned.
reportValidity() Checks if the form control has any restraints and whether it satisfies them. If invalid, false will be returned and the invalid event will be dispatched. In addition, the problem will be reported to the user. If valid, true will be returned.
setCustomValidity() Sets a custom validation message for the form control. If this message is not an empty string, then the form control is considered invalid and the specified message will be displayed to the user when reporting validity. Setting an empty string clears the custom validity state. message: string

Events Jump to heading

Segmented Control dispatches the following custom events. You can listen to them the same way was native events. Learn more about custom events

Name Description
quiet-change Emitted when the user commits changes to the segmented control's value.
quiet-input Emitted when the segmented control receives input.

CSS custom properties Jump to heading

Segmented Control supports the following CSS custom properties. You can style them like any other CSS property. Learn more about CSS custom properties

Name Description Default
--spacing The spacing around the thumb and between segments. The track's border radius adjusts with it to keep the corners concentric. 0.125em
--thumb-speed The duration of the thumb's slide animation. 200ms

CSS parts Jump to heading

Segmented Control exposes internal elements that can be styled with CSS using the selectors shown below. Learn more about CSS parts

Name Description CSS selector
thumb The animated indicator that slides behind the checked segment. ::part(thumb)

Custom States Jump to heading

Segmented Control has the following custom states. You can target them with CSS using the selectors shown below. Learn more about custom states

Name Description CSS selector
disabled Applied when the segmented control is disabled. :state(disabled)
readonly Applied when the segmented control is read-only. :state(readonly)
sliding Applied while the thumb is animating to a newly selected segment. :state(sliding)
user-valid Applied when the segmented control is valid and the user has sufficiently interacted with it. :state(user-valid)
user-invalid Applied when the segmented control is invalid and the user has sufficiently interacted with it. :state(user-invalid)

Dependencies Jump to heading

Segmented Control automatically imports the following elements. Sub-dependencies are also included in this list.

Search this website Toggle dark mode View the code on GitHub Follow @quietui.org on Bluesky Follow @quiet_ui on X

    No results found