Skip to content

Select Examples

The examples below assume that you have imported the component and set up the theme.

Basic

Put a trigger in the flyout's trigger slot and one button per option. The flyout ships starter styles for both, and your own rules override them.

<div class="select-basic">
<label class="field-label" for="basic-fruit-trigger">Fruit</label>
<sv-select close-on-select>
<sv-flyout>
<button id="basic-fruit-trigger" type="button" slot="trigger">
<span data-select-no-value>Pick a fruit</span>
<span data-select-has-value data-select-label></span>
</button>
<button value="apple">Apple</button>
<button value="banana">Banana</button>
<button value="cherry">Cherry</button>
</sv-flyout>
</sv-select>
</div>
<style>
.select-basic {
display: grid;
gap: 0.5em;
inline-size: min(100%, 16rem);
margin-inline: auto;
color: var(--sv-gray-2);
.field-label {
font-weight: 600;
}
}
</style>

Trigger

Style the trigger like any button. Use sv-flyout:state(--opened) to style it while the list is open.

<div class="select-trigger">
<label class="field-label" for="trigger-language-trigger">Language</label>
<sv-select close-on-select>
<sv-flyout>
<button id="trigger-language-trigger" type="button" class="trigger" slot="trigger">
<span data-select-no-value>Choose a language</span>
<span data-select-has-value data-select-label></span>
<svg class="chevron" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg">
<path d="M480-360 280-560h400L480-360Z"></path>
</svg>
</button>
<button value="en">English</button>
<button value="es">Español</button>
<button value="fr">Français</button>
<button value="de">Deutsch</button>
</sv-flyout>
</sv-select>
</div>
<style>
.select-trigger {
display: grid;
gap: 0.5em;
inline-size: min(100%, 16rem);
margin-inline: auto;
color: var(--sv-gray-2);
.field-label {
font-weight: 600;
}
.trigger {
display: flex;
gap: 0.5em;
align-items: center;
justify-content: space-between;
transition: border-color 200ms ease;
}
.chevron {
flex: none;
inline-size: 1.25em;
block-size: 1.25em;
fill: currentcolor;
rotate: -90deg;
transition: rotate 200ms ease;
}
sv-flyout:state(--opened) {
.trigger {
border-color: var(--sv-accent);
}
.chevron {
rotate: 0deg;
}
}
@media (prefers-reduced-motion: reduce) {
.trigger,
.chevron {
transition: none;
}
}
}
</style>

Content

Options can hold any markup, like an icon next to the text. data-select-clone shows a copy of the selected option in the trigger.


<div class="select-content">
<label class="field-label" for="content-status-trigger">Status</label>
<sv-select close-on-select value="online">
<sv-flyout>
<button id="content-status-trigger" type="button" class="trigger" slot="trigger">
<span data-select-clone></span>
<svg class="chevron" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg">
<path d="M480-360 280-560h400L480-360Z"></path>
</svg>
</button>
<button class="option" value="online">
<!-- Online -->
<svg class="icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg">
<circle cx="480" cy="-480" r="380"></circle>
</svg>
Online
</button>
<button class="option" value="away">
<!-- Away -->
<svg class="icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg">
<path
d="M480-860a380 380 0 1 0 0 760 380 380 0 0 0 0-760Zm0 100a280 280 0 1 1 0 560 280 280 0 0 1 0-560Z"
fill-rule="evenodd"
></path>
<path d="M480-660v180h140" fill="none" stroke="currentcolor" stroke-linecap="round" stroke-width="90"></path>
</svg>
Away
</button>
<button class="option" value="busy">
<!-- Busy -->
<svg class="icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg">
<path
d="M480-860a380 380 0 1 0 0 760 380 380 0 0 0 0-760Zm0 100a280 280 0 1 1 0 560 280 280 0 0 1 0-560Z"
fill-rule="evenodd"
></path>
<rect height="90" rx="45" width="360" x="300" y="-525"></rect>
</svg>
Busy
</button>
<hr class="separator" />
<button class="option" value="offline">
<!-- Offline -->
<svg class="icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg">
<path
d="M480-860a380 380 0 1 0 0 760 380 380 0 0 0 0-760Zm0 100a280 280 0 1 1 0 560 280 280 0 0 1 0-560Z"
fill-rule="evenodd"
></path>
</svg>
Appear offline
</button>
</sv-flyout>
</sv-select>
</div>
<style>
.select-content {
display: grid;
gap: 0.5em;
inline-size: min(100%, 16rem);
margin-inline: auto;
color: var(--sv-gray-2);
.field-label {
font-weight: 600;
}
.trigger {
display: flex;
gap: 0.5em;
align-items: center;
justify-content: space-between;
}
.chevron {
flex: none;
inline-size: 1.25em;
block-size: 1.25em;
fill: currentcolor;
rotate: -90deg;
transition: rotate 200ms ease;
}
.option {
display: flex;
gap: 0.6em;
align-items: center;
padding: 0.5em 0.75em;
border-radius: var(--sv-bdr-rad-md);
}
.trigger .option {
padding: 0;
font: inherit;
color: inherit;
cursor: inherit;
background: none;
border: none;
}
.icon {
flex: none;
inline-size: 1.25em;
block-size: 1.25em;
fill: currentcolor;
}
.separator {
flex: none;
block-size: var(--sv-bdr-sz-sm);
margin: 0.25em 0;
background-color: var(--sv-gray-5);
border: none;
}
sv-flyout:state(--opened) {
.trigger {
border-color: var(--sv-accent);
}
.chevron {
rotate: 0deg;
}
}
@media (prefers-reduced-motion: reduce) {
.chevron {
transition: none;
}
}
}
</style>

Multiple

multiple lets the user pick several options. Mark the initial picks with aria-selected="true" on the options.

<div class="select-multiple">
<label class="field-label" for="multiple-toppings-trigger">Toppings</label>
<sv-select multiple>
<sv-flyout>
<button id="multiple-toppings-trigger" type="button" class="trigger" slot="trigger">
<span data-select-no-value>No toppings</span>
<span class="label" data-select-has-value data-select-label></span>
<svg class="chevron" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg">
<path d="M480-360 280-560h400L480-360Z"></path>
</svg>
</button>
<button aria-selected="true" value="cheese">Extra cheese</button>
<button value="mushrooms">Mushrooms</button>
<button aria-selected="true" value="olives">Olives</button>
<button value="peppers">Peppers</button>
<button value="anchovies">Anchovies</button>
</sv-flyout>
</sv-select>
</div>
<style>
.select-multiple {
display: grid;
gap: 0.5em;
inline-size: min(100%, 18rem);
margin-inline: auto;
color: var(--sv-gray-2);
.field-label {
font-weight: 600;
}
.trigger {
display: flex;
gap: 0.5em;
align-items: center;
justify-content: space-between;
min-inline-size: 0;
.label {
min-inline-size: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.chevron {
flex: none;
inline-size: 1.25em;
block-size: 1.25em;
fill: currentcolor;
rotate: -90deg;
transition: rotate 200ms ease;
}
sv-flyout:state(--opened) {
.trigger {
border-color: var(--sv-accent);
}
.chevron {
rotate: 0deg;
}
}
@media (prefers-reduced-motion: reduce) {
.chevron {
transition: none;
}
}
}
</style>

Positions

Set position-order on the flyout. It takes a preset or a list of position areas, tried in order until one fits.

top center center, bottom center center
bottom start start, top start start
bottom end end, top end end
horizontal
<div class="select-positions">
<div class="variant">
<sv-select close-on-select>
<sv-flyout position-order="top center center, bottom center center">
<button type="button" aria-label="Fruit" slot="trigger">
<span data-select-no-value>Pick a fruit</span>
<span data-select-has-value data-select-label></span>
</button>
<button value="apple">Apple</button>
<button value="banana">Banana</button>
<button value="cherry">Cherry</button>
</sv-flyout>
</sv-select>
<span>top center center, bottom center center</span>
</div>
<div class="variant">
<sv-select close-on-select>
<sv-flyout class="narrow" position-order="bottom start start, top start start">
<button type="button" aria-label="Fruit" slot="trigger">
<span data-select-no-value>Pick a fruit</span>
<span data-select-has-value data-select-label></span>
</button>
<button value="apple">Apple</button>
<button value="banana">Banana</button>
<button value="cherry">Cherry</button>
</sv-flyout>
</sv-select>
<span>bottom start start, top start start</span>
</div>
<div class="variant">
<sv-select close-on-select>
<sv-flyout class="narrow" position-order="bottom end end, top end end">
<button type="button" aria-label="Fruit" slot="trigger">
<span data-select-no-value>Pick a fruit</span>
<span data-select-has-value data-select-label></span>
</button>
<button value="apple">Apple</button>
<button value="banana">Banana</button>
<button value="cherry">Cherry</button>
</sv-flyout>
</sv-select>
<span>bottom end end, top end end</span>
</div>
<div class="variant">
<sv-select close-on-select>
<sv-flyout class="sideways" position-order="horizontal">
<button type="button" aria-label="Fruit" slot="trigger">
<span data-select-no-value>Pick a fruit</span>
<span data-select-has-value data-select-label></span>
</button>
<button value="apple">Apple</button>
<button value="banana">Banana</button>
<button value="cherry">Cherry</button>
</sv-flyout>
</sv-select>
<span>horizontal</span>
</div>
</div>
<style>
.select-positions {
display: grid;
gap: 1.5em;
inline-size: min(100%, 16rem);
padding-block: 2em;
margin-inline: auto;
color: var(--sv-gray-2);
.variant {
display: grid;
gap: 0.4em;
> span {
font-size: 0.8em;
color: var(--sv-gray-3);
text-align: center;
}
}
.narrow::part(content) {
inline-size: 10rem;
}
.sideways::part(content) {
inline-size: max-content;
}
}
</style>