Skip to content

Radio

<quiet-radio> stable since 1.0

Radios let the user select one option from a group of choices.

Radios follow the ARIA APG radio group pattern for accessibility. Unlike native radio buttons, Quiet radio items must be placed inside a radio controller as shown below.

Black White Orange Gray
<quiet-radio 
  label="Color" 
  description="Select a color for your new cat" 
  name="color" 
  value="black"
>
  <quiet-radio-item value="black">Black</quiet-radio-item>
  <quiet-radio-item value="white">White</quiet-radio-item>
  <quiet-radio-item value="orange">Orange</quiet-radio-item>
  <quiet-radio-item value="gray">Gray</quiet-radio-item>
</quiet-radio>

Examples Jump to heading

Labels and descriptions Jump to heading

You can use the label and description attributes to provide plain text labels and descriptions for the radio. If you want to provide HTML, use the label and description slots instead.

For more information, visit our website. Cat Dog Bird Lizard
<quiet-radio label="Favorite pet" name="animal">
  <span slot="description">
    For more information, <a href="https://example.com/" target="_blank">visit our website</a>.
  </span>
  <quiet-radio-item value="cat">Cat</quiet-radio-item>
  <quiet-radio-item value="dog">Dog</quiet-radio-item>
  <quiet-radio-item value="bird">Bird</quiet-radio-item>
  <quiet-radio-item value="lizard">Lizard</quiet-radio-item>
</quiet-radio-item>

Providing an initial value Jump to heading

Use the value attribute to provide an initial value for the radio. The value should match an existing radio item's value.

Short Medium Long Hairless
<quiet-radio label="Fur type" name="fur" value="short">
  <quiet-radio-item value="short">Short</quiet-radio-item>
  <quiet-radio-item value="medium">Medium</quiet-radio-item>
  <quiet-radio-item value="long">Long</quiet-radio-item>
  <quiet-radio-item value="hairless">Hairless</quiet-radio-item>
</quiet-radio-item>

This behavior is different from native radios that use the checked attribute to set the value. With <quiet-radio>, always use the value attribute to set the value.

Changing the orientation Jump to heading

To stack radio items on top of each other instead of side by side, set the orientation attribute to vertical.

Short Medium Long Hairless
<quiet-radio orientation="vertical" label="Fur type" name="fur">
  <quiet-radio-item value="short">Short</quiet-radio-item>
  <quiet-radio-item value="medium">Medium</quiet-radio-item>
  <quiet-radio-item value="long">Long</quiet-radio-item>
  <quiet-radio-item value="hairless">Hairless</quiet-radio-item>
</quiet-radio-item>

Filled radios Jump to heading

Set the appearance attribute to filled to change a radio item's appearance.

Cat Dog Bird Lizard
<quiet-radio label="Favorite pet" name="animal">
  <quiet-radio-item appearance="filled" value="cat">Cat</quiet-radio-item>
  <quiet-radio-item appearance="filled" value="dog">Dog</quiet-radio-item>
  <quiet-radio-item appearance="filled" value="bird">Bird</quiet-radio-item>
  <quiet-radio-item appearance="filled" value="lizard">Lizard</quiet-radio-item>
</quiet-radio>

Changing the size Jump to heading

Use the size attribute to change a radio item's size.

Extra small Small Medium Large Extra large
<quiet-radio label="Select a size" name="size" orientation="vertical">
  <quiet-radio-item size="xs" value="a">Extra small</quiet-radio-item>
  <quiet-radio-item size="sm" value="b">Small</quiet-radio-item>
  <quiet-radio-item size="md" value="c">Medium</quiet-radio-item>
  <quiet-radio-item size="lg" value="d">Large</quiet-radio-item>
  <quiet-radio-item size="xl" value="e">Extra large</quiet-radio-item>
</quiet-radio>

Disabling Jump to heading

You can disable one or more radio items by adding the disabled attribute.

Cat Dog Bird Lizard
<quiet-radio label="Favorite pet" name="animal">
  <quiet-radio-item value="cat">Cat</quiet-radio-item>
  <quiet-radio-item value="dog" disabled>Dog</quiet-radio-item>
  <quiet-radio-item value="bird">Bird</quiet-radio-item>
  <quiet-radio-item value="lizard">Lizard</quiet-radio-item></quiet-radio>

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 radio item is checked.

Cats Dogs
Submit Reset
<form action="about:blank" method="get" target="_blank">
  <quiet-radio label="Select one" name="animal" required>
    <quiet-radio-item value="cats">Cats</quiet-radio-item>
    <quiet-radio-item value="dogs">Dogs</quiet-radio-item>
  </quiet-radio>
  <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 custom-validity attribute to make the radio 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.

Cats Dogs
Submit Reset
<form action="about:blank" method="get" target="_blank">
  <quiet-radio label="Select one" name="animal" custom-validity="Not so fast, bubba!">
    <quiet-radio-item value="cats">Cats</quiet-radio-item>
    <quiet-radio-item value="dogs">Dogs</quiet-radio-item>
  </quiet-radio>
  <br>
  <quiet-button type="submit" variant="primary">Submit</quiet-button>
  <quiet-button type="reset">Reset</quiet-button>
</form>

Most validation attributes work exactly like their native counterparts. However, the custom-validity attribute is offered in lieu of the setCustomValidity() method. This allows you to declaratively set custom errors instead of having to call a method with JavaScript.

Styling validation Jump to heading

You can style valid and invalid radios using the :valid and :invalid pseudo classes.

Cats Dogs
Submit Reset
<form action="about:blank" method="get" target="_blank" class="radio__validation-pseudo">
  <quiet-radio label="Select one" name="animal" required>
    <quiet-radio-item value="cats">Cats</quiet-radio-item>
    <quiet-radio-item value="dogs">Dogs</quiet-radio-item>
  </quiet-radio>
  <br>
  <quiet-button type="submit" variant="primary">Submit</quiet-button>
  <quiet-button type="reset">Reset</quiet-button>
</form>

<style>
  .radio__validation-pseudo {
    quiet-radio:valid {
      outline: solid 2px var(--quiet-constructive-stroke-mid);
      outline-offset: .5rem;
    }

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

However, these selectors will match even before the user has had a chance to fill out the form. More often than not, you'll want to use the user-valid and user-invalid custom states instead. This way, validation styles are only shown after the user interacts with the form control or when the form is submitted.

Cats Dogs
Submit Reset
<form action="about:blank" method="get" target="_blank" class="radio__validation-custom">
  <quiet-radio label="Select one" name="animal" required>
    <quiet-radio-item value="cats">Cats</quiet-radio-item>
    <quiet-radio-item value="dogs">Dogs</quiet-radio-item>
  </quiet-radio>
  <br>
  <quiet-button type="submit" variant="primary">Submit</quiet-button>
  <quiet-button type="reset">Reset</quiet-button>
</form>

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

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

Styling radios Jump to heading

Radios come with a simple, minimal appearance. Feel free to customize them with your own styles. Here are some examples, for inspiration.

Magic link Password
<quiet-radio label="How would you like to login?" name="auth" class="radio__auth">
  <quiet-radio-item value="magic">
    <quiet-icon name="wand"></quiet-icon> Magic link
  </quiet-radio-item>
  <quiet-radio-item value="password">
    <quiet-icon name="password"></quiet-icon> Password
  </quiet-radio-item>
</quiet-radio>

<style>
  .radio__auth {
    quiet-radio-item {
      background: var(--quiet-paper);
      border: solid 1px var(--quiet-neutral-stroke-soft);
      border-radius: .5rem;
      box-shadow: var(--quiet-shadow-softer);
      padding: 1rem;
      cursor: pointer;
    }

    quiet-radio-item:state(checked) {
      background-color: var(--quiet-primary-fill-softer);
      border-color: var(--quiet-primary-stroke-soft);
    }

    quiet-radio-item:focus-visible {
      outline: var(--quiet-focus-ring);
      outline-offset: var(--quiet-focus-offset);
    }    
  }
</style>
Startup
12GB · 6 CPUs · 256GB SSD
Business
16GB · 8 CPUs · 512GB SSD
Enterprise
32GB · 12 CPUs · 1TB SSD
<quiet-radio 
  label="Select a plan" 
  description="All plans come with a free cat"
  name="plan" 
  class="radio__hosting"
>
  <quiet-radio-item value="startup">
    Startup<br>
    <small>12GB &middot; 6 CPUs &middot; 256GB SSD</small> 
  </quiet-radio-item>

  <quiet-radio-item value="business">
    Business<br>
    <small>16GB &middot; 8 CPUs &middot; 512GB SSD</small> 
  </quiet-radio-item>
  
  <quiet-radio-item value="enterprise">
    Enterprise<br>
    <small>32GB &middot; 12 CPUs &middot; 1TB SSD</small>
  </quiet-radio-item>
</quiet-radio>

<style>
  .radio__hosting {
    quiet-radio-item {
      position: relative;
      width: 100%;
      background: var(--quiet-paper);
      border: solid 1px var(--quiet-neutral-stroke-soft);
      box-shadow: var(--quiet-shadow-softer);
      border-radius: .5rem;
      padding: 1rem;
    }

    quiet-radio-item::part(label) {
      width: 100%;
      display: block;
    }

    quiet-radio-item::part(visual-box) {
      position: absolute;
      top: calc(50% - .625rem);
      right: 1rem;
    }

    quiet-radio-item:state(checked) {
      background-color: var(--quiet-primary-fill-softer);
      border-color: var(--quiet-primary-stroke-soft);
    }

    quiet-radio-item:focus-visible {
      outline: var(--quiet-focus-ring);
      outline-offset: 2px;
    }    

    small {
      color: var(--quiet-text-muted);
    }
  }  
</style>
Silver Blue Rose Gold
<quiet-radio 
  label="Color" 
  description="Choose a color for your new device" 
  name="color" 
  class="radio__colors"
>
  <quiet-radio-item value="silver" style="color: #b6b9c9;">Silver</quiet-radio-item>
  <quiet-radio-item value="blue" style="color: #83c0f5;">Blue</quiet-radio-item>
  <quiet-radio-item value="rose" style="color: #eea3bb;">Rose</quiet-radio-item>
  <quiet-radio-item value="gold" style="color: #d1b86c;">Gold</quiet-radio-item>
</quiet-radio>

<style>
  .radio__colors {
    &::part(group) {
      gap: .5rem;
    }

    quiet-radio-item {
      width: 3rem;
      height: 3rem;
      background-color: currentColor;
      background-image: linear-gradient(#fff8, transparent);
      box-shadow: inset 0 1px 2px color-mix(in oklab, currentColor, black 12.5%);
      border-radius: 50%;
      cursor: pointer;
    }

    quiet-radio-item:state(checked) {
      outline: var(--quiet-border-style) var(--quiet-focus-width) currentColor;
      outline-offset: 2px;
    }

    quiet-radio-item:focus-visible {
      outline: var(--quiet-focus-ring);
      outline-offset: 2px;
    }    

    quiet-radio-item::part(label) {
      position: absolute;
      width: 1px;
      height: 1px;
      overflow: hidden;
      white-space: nowrap;
      clip-path: inset(50%);
    }
  }
</style>

It's not recommended to hide the radio button unless your styles make it very clear to users that the control is selectable.

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 npm

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

import 'https://cdn.jsdelivr.net/npm/@quietui/quiet@1.0.0/dist/components/radio/radio.js';

To manually import <quiet-radio> from npm, use the following code.

import '@quietui/quiet/dist/components/radio/radio.js';

Slots Jump to heading

Radio supports the following slots. Learn more about using slots

Name Description
(default) The radio items to place in the group.
label The radio's label. For plain-text labels, you can use the label attribute instead.
description The radios's description. For plain-text descriptions, you can use the description attribute instead.

Properties Jump to heading

Radio 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 / Attribute Description Reflects Type Default
associatedForm A reference to the <form> associated with the form control, or null if no form is associated. HTMLFormElement
null
null
label The radio's label. If you need to provide HTML in the label, use the label slot instead. string
description The radio's description. If you need to provide HTML in the description, use the description slot instead. string
name The name of the radio. This will be submitted with the form as a name/value pair. string
value The radio's current value. Set this to change the selected item. string ''
orientation The orientation of grouped items. 'horizontal'
'vertical'
'horizontal'
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 radio is required. boolean false
customValidity
custom-validity
You can provide a custom error message to force the radio to be invalid. To clear the error, set this to an empty string. string ''

Methods Jump to heading

Radio 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 item or the first item if none are selected. options: FocusOptions

Events Jump to heading

Radio 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 radio's value.
quiet-input Emitted when the radio receives input.

CSS parts Jump to heading

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

Name Description CSS selector
label The element that contains the radio's label. ::part(label)
description The element that contains the radio's description. ::part(description)
group The element that wraps the grouped radios. ::part(group)

Custom States Jump to heading

Radio 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
user-valid Applied when the radio is valid and the user has sufficiently interacted with it. :state(user-valid)
user-invalid Applied when the radio is invalid and the user has sufficiently interacted with it. :state(user-invalid)

Dependencies Jump to heading

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

Search this website Toggle dark mode Get the code on GitHub Follow @quietui.org on Bluesky Follow @quiet_ui on X
    No results found