Skip to content

Select

<quiet-select> stable since 1.0

Selects let users choose an option from a predefined list of options.

This component works very similar to the <select> element. You can add <option>, <optgroup>, and <hr> elements to it to group and provide options, which are then copied into the component's shadow root.

<quiet-select 
  name="cat" 
  label="Wild cats" 
  description="Select your favorite type of cat from the wild"
>
  <optgroup label="Small cats">
    <option value="bobcat">Bobcat</option>
    <option value="sand-cat">Sand cat</option>
    <option value="serval">Serval</option>
  </optgroup>
  <optgroup label="Big cats">
    <option value="cheetah">Cheetah</option>
    <option value="lion">Lion</option>
    <option value="tiger">Tiger</option>
  </optgroup>
</quiet-select>

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 select. If you want to provide HTML, use the label and description slots instead.

For more information, visit our website.
<quiet-select name="zzz" label="Where to sleep">
  <span slot="description">
    For more information, <a href="https://example.com/" target="_blank">visit our website</a>.
  </span>
  <option value="box">Cardboard box</option>
  <option value="floor">Floor</option>
  <option value="laundry">Laundry</option>
  <option value="pillow">Pillow</option>
  <option value="sunbeam">Sunbeam</option>  
</quiet-select>

Providing an initial value Jump to heading

Use the value attribute to provide an initial value for the select.

<quiet-select name="size" label="Select a size" value="md">
  <option value="xs">Extra small</option>
  <option value="sm">Small</option>
  <option value="md">Medium</option>
  <option value="lg">Large</option>
  <option value="xl">Extra large</option>
</quiet-select>

This behavior is different from native selects that use the option's selected attribute to set the value. With <quiet-select>, always use the value attribute to set the value.

Start and end content Jump to heading

Use the start and end slots to add presentational icons or text. Avoid interactive elements such as buttons, links, etc. Works well with <quiet-icon> and <svg> elements.


<quiet-select name="account" label="Account type">
  <quiet-icon slot="start" name="user"></quiet-icon>
  <option value="owner">Owner</option>
  <option value="admin">Administrator</option>
  <option value="user">User</option>
  <option value="guest">Guest</option>
</quiet-select>

<br>

<quiet-select name="contact" label="Preferred method of contact">
  <quiet-icon slot="end" name="mail"></quiet-icon>
  <option value="email">Email</option>
  <option value="phone">Phone</option>
  <option value="mail">Regular Mail</option>
  <option value="text">Text Message</option>
  <option value="none">None</option>
</quiet-select>

Filled and unstyled selects Jump to heading

Set the appearance attribute to normal, filled, or unstyled to change the select's appearance.



<quiet-select appearance="normal" label="Normal select" value="normal">
  <option value="normal">Normal</option>
  <option value="filled">Filled</option>
  <option value="unstyled">Unstyled</option>
</quiet-select><br>

<quiet-select appearance="filled" label="Filled select" value="filled">
  <option value="normal">Normal</option>
  <option value="filled">Filled</option>
  <option value="unstyled">Unstyled</option>
</quiet-select><br>

<quiet-select appearance="unstyled" label="Unstyled select" value="unstyled">
  <option value="normal">Normal</option>
  <option value="filled">Filled</option>
  <option value="unstyled">Unstyled</option>
</quiet-select>

Pill-shaped selects Jump to heading

selects can be rendered with pill-shaped edges by adding the pill attribute.

<quiet-select pill label="Pill-shaped">
  <option value="1">One</option>
  <option value="2">Two</option>
  <option value="3">Three</option>
</quiet-select>

Changing the size Jump to heading

Use the size attribute to change the select's size.





<quiet-select size="xs" label="Extra small" value="xs">
  <option value="xs">Extra small</option>
  <option value="sm">Small</option>
  <option value="md">Medium</option>
  <option value="lg">Large</option>
  <option value="xl">Extra large</option>
</quiet-select><br>

<quiet-select size="sm" label="Small" value="sm">
  <option value="xs">Extra small</option>
  <option value="sm">Small</option>
  <option value="md">Medium</option>
  <option value="lg">Large</option>
  <option value="xl">Extra large</option>
</quiet-select><br>

<quiet-select size="md" label="Medium" value="md">
  <option value="xs">Extra small</option>
  <option value="sm">Small</option>
  <option value="md">Medium</option>
  <option value="lg">Large</option>
  <option value="xl">Extra large</option>
</quiet-select><br>

<quiet-select size="lg" label="Large" value="lg">
  <option value="xs">Extra small</option>
  <option value="sm">Small</option>
  <option value="md">Medium</option>
  <option value="lg">Large</option>
  <option value="xl">Extra large</option>
</quiet-select><br>

<quiet-select size="xl" label="Extra large" value="xl">
  <option value="xs">Extra small</option>
  <option value="sm">Small</option>
  <option value="md">Medium</option>
  <option value="lg">Large</option>
  <option value="xl">Extra large</option>
</quiet-select>

Adding option groups Jump to heading

Use <optgroup> elements to add option groups. Set the label attribute to an appropriate label.

<quiet-select name="cat" label="Wild cats">
  <optgroup label="Small cats">
    <option value="bobcat">Bobcat</option>
    <option value="sand-cat">Sand cat</option>
    <option value="serval">Serval</option>
  </optgroup>
  <optgroup label="Big cats">
    <option value="cheetah">Cheetah</option>
    <option value="lion">Lion</option>
    <option value="tiger">Tiger</option>
  </optgroup></quiet-select>

Adding dividers Jump to heading

Use <hr> to add dividers between options.


<quiet-select name="animal" label="Animal">
  <option value="bird">Bird</option>
  <option value="cat">Cat</option>
  <option value="dog">Dog</option>
  <option value="lizard">Lizard</option>
  <hr>
  <option value="other">Other</option>
</quiet-select>

Disabling options Jump to heading

Use the disabled attribute to disable individual options.

<quiet-select label="Disabled options">
  <option value="bird">Bird</option>
  <option value="cat">Cat</option>
  <option value="dog" disabled>Dog</option>
  <option value="lizard">Lizard</option>
</quiet-select>

Disabling option groups Jump to heading

Use the disabled attribute to disable an option group.

<quiet-select label="Disabled option groups">
  <optgroup label="Group one">
    <option value="morning-1">Morning</option>
    <option value="afternoon-1">Afternoon</option>
    <option value="evening-1">Evening</option>
  </optgroup>
  <optgroup label="Group two" disabled>
    <option value="morning-2">Morning</option>
    <option value="afternoon-2">Afternoon</option>
    <option value="evening-2">Evening</option>
  </optgroup>
</quiet-select>

Disabled option groups don't currently work in iOS Safari.

Disabling selects Jump to heading

Use the disabled attribute to disable the select.

<quiet-select label="Disabled" disabled>
  <option value="bird">Bird</option>
  <option value="cat">Cat</option>
  <option value="dog">Dog</option>
  <option value="lizard">Lizard</option>
</quiet-select>

Showing labels on the side Jump to heading

With a bit of custom CSS, you can show labels on the side instead of on top of the select.



<div class="select__side-labels">
  <quiet-select name="quantity" label="Quantity" description="How many do you need?">
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
  </quiet-select>
  <br>
  <quiet-select type="delivery" name="delivery" label="Delivery" description="How soon do you need it?">
    <option value="next">Next-day</option>
    <option value="priority">Priority</option>
    <option value="ground">Ground</option>
  </quiet-select>
</div>

<style>
  .select__side-labels {
    quiet-select {
      --label-width: 4.5rem; /* Change this to make more room for the label */

      display: grid;
      grid: auto / var(--label-width) 1fr;
      gap: .25em;
      align-items: center;    
    }

    quiet-select::part(label) {
      text-align: end;
    }

    quiet-select::part(description) {
      grid-column-start: 2;
      order: 3;
    }
  }
</style>

Validation Jump to heading

The required attribute can be applied to enable validation using the Constraint Validation API . This will prevent form submission until an option with a non-empty value is selected.


Submit Reset
<form action="about:blank" method="get" target="_blank">
  <quiet-select name="required" label="Required" required>
    <option value=""></option>
    <option value="bird">Bird</option>
    <option value="cat">Cat</option>
    <option value="dog">Dog</option>
    <option value="lizard">Lizard</option>
  </quiet-select>
  <br>
  <quiet-button type="submit">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 select 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.


Submit
<form action="about:blank" method="get" target="_blank">
  <quiet-select 
    name="animal"
    label="Animal"
    description="This field will be invalid until the custom-validity attribute is removed"
    custom-validity="Not so fast, bubba!"
  >
    <option value="bird">Bird</option>
    <option value="cat">Cat</option>
    <option value="dog">Dog</option>
    <option value="lizard">Lizard</option>
  </quiet-select>
  <br>
  <quiet-button type="submit" variant="primary">Submit</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 selects using the :valid and :invalid pseudo classes.


Submit Reset
<form action="about:blank" method="get" target="_blank" class="select__validation-pseudo">
  <quiet-select 
    name="animal"
    label="Animal"
    description="This field is required"
    required
  >
    <option value=""></option>
    <option value="bird">Bird</option>
    <option value="cat">Cat</option>
    <option value="dog">Dog</option>
    <option value="lizard">Lizard</option>
  </quiet-select>
  <br>
  <quiet-button type="submit" variant="primary">Submit</quiet-button>
  <quiet-button type="reset">Reset</quiet-button>
</form>

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

    quiet-select: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.


Submit Reset
<form action="about:blank" method="get" target="_blank" class="select__validation-custom">
  <quiet-select 
    name="animal"
    label="Animal"
    description="This field is required"
    required
  >
    <option value=""></option>
    <option value="bird">Bird</option>
    <option value="cat">Cat</option>
    <option value="dog">Dog</option>
    <option value="lizard">Lizard</option>
  </quiet-select>
  <br>
  <quiet-button type="submit" variant="primary">Submit</quiet-button>
  <quiet-button type="reset">Reset</quiet-button>
</form>

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

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

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-select> from the CDN, use the following code.

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

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

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

Slots Jump to heading

Select supports the following slots. Learn more about using slots

Name Description
label The select's label. For plain-text labels, you can use the label attribute instead.
description The select's description. For plain-text descriptions, you can use the description attribute instead.
start An icon or similar element to place before the label. Works great with <quiet-icon>.
end An icon or similar element to place after the label. Works great with <quiet-icon>.

Properties Jump to heading

Select 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 select's label. If you need to provide HTML in the label, use the label slot instead. string
description The select's description. If you need to provide HTML in the description, use the description slot instead. string
name The name of the select. This will be submitted with the form as a name/value pair. string
value The select's value. string ''
disabled Disables the select. boolean false
readonly Makes the select a read-only field. boolean false
appearance The type of select to render. 'normal'
'filled'
'unstyled'
'normal'
size The select's size. 'xs'
'sm'
'md'
'lg'
'xl'
'md'
pill Draws the select in a pill shape. boolean false
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 Makes the select required. Form submission will not be allowed when this is set and the select is blank. boolean false
customValidity
custom-validity
You can provide a custom error message to force the select to be invalid. To clear the error, set this to an empty string. string ''
autocomplete Tells the browser how to autocomplete the select. See this page for available values. string
enterkeyhint Sets the enter key label on virtual keyboards. 'enter'
'done'
'go'
'next'
'previous'
'search'
'send'

Methods Jump to heading

Select 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 select.
blur() Removes focus from the select.
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.

Events Jump to heading

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

Name Description
quiet-blur Emitted when the select loses focus. This event does not bubble.
quiet-change Emitted when the user commits changes to the select's value.
quiet-focus Emitted when the select receives focus. This event does not bubble.
quiet-input Emitted when the select receives input.

CSS parts Jump to heading

Select 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 select's label. ::part(label)
description The element that contains the select's description. ::part(description)
visual-box The element that wraps the internal text box. ::part(visual-box)
text-box The internal text box, a <select> element. ::part(text-box)
chevron The chevron icon, a <quiet-icon> element. ::part(chevron)
chevron__svg The chevron icon's <svg> part. ::part(chevron__svg)

Custom States Jump to heading

Select 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 select is disabled. :state(disabled)
blank Applied when the select has no selected option. :state(blank)
focused Applied when the select has focus. :state(focused)
user-valid Applied when the select is valid and the user has sufficiently interacted with it. :state(user-valid)
user-invalid Applied when the select is invalid and the user has sufficiently interacted with it. :state(user-invalid)

Dependencies Jump to heading

Select 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