Select

Fully customizable native select with CSS appearance base-select

Overview

A fully styleable native <select> element using CSS appearance: base-select. Get complete control over the dropdown picker, arrow icon, and options—while maintaining native accessibility.

Browser Support: Chrome 135+, Edge 135+. Falls back gracefully to standard select styling in unsupported browsers.

Import

/* Full framework (includes all components) */
@import "@shift-css/core";

/* Or import just the select component */
@import "@shift-css/core/components/select";

Note: When importing individual components, you also need @shift-css/core/reset and @shift-css/core/tokens for the base styles and design tokens.

Basic Usage

Customizable select

<div class="demo-grid">
<div s-field>
  <label s-field-label for="demo-select">Choose an option</label>
  <select s-select id="demo-select">
    <option>Option 1</option>
    <option>Option 2</option>
    <option>Option 3</option>
  </select>
</div>
<div s-field>
  <label s-field-label for="demo-select-2">With more options</label>
  <select s-select id="demo-select-2">
    <option>React</option>
    <option>Vue</option>
    <option>Angular</option>
    <option>Svelte</option>
    <option>Solid</option>
  </select>
</div>
</div>

Size Variants

Use the s-size attribute for different sizes:

Select sizes

<div class="demo-grid">
<div s-field>
  <label s-field-label for="select-sm">Small</label>
  <select s-select s-size="sm" id="select-sm">
    <option>Small select</option>
    <option>Option 2</option>
  </select>
</div>
<div s-field>
  <label s-field-label for="select-md">Default</label>
  <select s-select id="select-md">
    <option>Default select</option>
    <option>Option 2</option>
  </select>
</div>
<div s-field>
  <label s-field-label for="select-lg">Large</label>
  <select s-select s-size="lg" id="select-lg">
    <option>Large select</option>
    <option>Option 2</option>
  </select>
</div>
</div>

States

Select states

<div class="demo-grid">
<div s-field>
  <label s-field-label for="select-normal">Normal</label>
  <select s-select id="select-normal">
    <option>Click to open</option>
    <option>Option 2</option>
  </select>
</div>
<div s-field>
  <label s-field-label for="select-disabled">Disabled</label>
  <select s-select id="select-disabled" disabled>
    <option>Disabled</option>
    <option>Option 2</option>
  </select>
</div>
</div>

Comparison: s-select vs s-input

Features-selectselect[s-input]
Dropdown stylingFull control via ::picker(select)Browser default
Arrow iconStyleable via ::picker-iconSVG background image
Options stylingFull CSS controlLimited
CheckmarkCustomizable ::checkmarkNone
AnimationOpen/close transitionsNone
Browser supportChrome 135+All browsers

Use s-select for modern browsers with full customization, or s-input on <select> for maximum compatibility.

How It Works

The appearance: base-select CSS property opts in to the new customizable select rendering:

/* Opt-in to customizable select */
[s-select],
[s-select]::picker(select) {
  appearance: base-select;
}

/* Style the dropdown picker */
[s-select]::picker(select) {
  background: var(--s-surface-base);
  border: 2px solid var(--s-border-default);
  border-radius: var(--s-radius-md);
  box-shadow: var(--s-shadow-lg);
}

/* Rotate arrow when open */
[s-select]::picker-icon {
  transition: rotate 0.2s;
}

[s-select]:open::picker-icon {
  rotate: 180deg;
}

/* Style individual options */
[s-select] option {
  padding: var(--s-space-2) var(--s-space-3);
}

[s-select] option:checked {
  background-color: var(--s-interactive-primary);
  color: var(--s-text-on-primary);
}

New CSS Features Used

FeaturePurpose
appearance: base-selectEnables customizable select rendering
::picker(select)Targets the dropdown picker container
::picker-iconTargets the arrow icon
::checkmarkTargets the selected option indicator
:openMatches when the select is open
:checkedMatches the currently selected option

Fallback Behavior

In browsers that don’t support appearance: base-select, the component falls back to standard select styling with:

  • Custom arrow icon via SVG background
  • Consistent border and padding
  • Focus and hover states
@supports not (appearance: base-select) {
  [s-select] {
    appearance: none;
    background-image: url("data:image/svg+xml,...");
    /* Standard select styling */
  }
}

Accessibility

The s-select component maintains full native accessibility:

  • Keyboard navigation (arrow keys, Enter, Escape)
  • Screen reader support
  • Focus management
  • Form integration

No JavaScript required—it’s pure CSS enhancement of the native <select> element.

Attributes

AttributePurposeExample
s-selectEnable customizable select<select s-select>
s-size="sm"Small size variant<select s-select s-size="sm">
s-size="lg"Large size variant<select s-select s-size="lg">

Resources

Search