Skip to content

Accessibility

vue-superselect implements the WAI-ARIA Combobox pattern out of the box. Every component automatically applies the correct ARIA attributes, keyboard interactions, and screen reader announcements without any configuration.

Fully Accessible Select

Keyboard Navigation

All keyboard interactions follow the WAI-ARIA combobox specification:

KeyAction
Arrow DownOpen dropdown (if closed), move highlight to next option
Arrow UpOpen dropdown (if closed), move highlight to previous option
EnterSelect the highlighted option, close dropdown (single select)
EscapeClose dropdown. If already closed, clear the input text.
TabClose dropdown and move focus to the next focusable element
BackspaceWhen input is empty in multi-select, remove the last selected tag
HomeMove highlight to the first option
EndMove highlight to the last option

By default, keyboard navigation loops. Pressing Arrow Down on the last option wraps to the first. Disable with :loop="false" on SelectRoot.

The select-on-tab prop changes Tab behavior: instead of just closing, it selects the highlighted option first, then closes and moves focus.

ARIA Attributes

The component tree automatically applies the correct roles and attributes:

Input (Combobox)

AttributeValuePurpose
rolecomboboxIdentifies the input as a combobox
aria-expandedtrue / falseWhether the dropdown is open
aria-controlslistbox idPoints to the dropdown element
aria-activedescendantoption idPoints to the currently highlighted option
aria-autocompletelistIndicates filtering behavior
AttributeValuePurpose
rolelistboxIdentifies the dropdown as a list of options
aria-multiselectabletrue (when multiple)Indicates multi-select capability

Options

AttributeValuePurpose
roleoptionIdentifies each item as a selectable option
aria-selectedtrue / falseWhether this option is currently selected
aria-disabledtrue / falseWhether this option is disabled

You do not need to set any of these attributes manually. They are applied by the components automatically.

Screen Reader Announcements

Add SelectLiveRegion to enable screen reader announcements:

template
<SelectRoot v-model="selected">
  <SelectControl>
    <SelectInput placeholder="Pick a fruit..." />
  </SelectControl>
  <SelectContent>
    <SelectOption v-for="fruit in fruits" :key="fruit" :value="fruit" :label="fruit">
      {{ fruit }}
    </SelectOption>
  </SelectContent>
  <SelectLiveRegion />
</SelectRoot>

SelectLiveRegion uses an aria-live="polite" region to announce state changes to screen readers:

  • When an option is selected: "Apple selected"
  • When an option is removed (multi-select): "Apple removed"
  • When the selection is cleared: "Selection cleared"
  • Result count updates as the user types to filter

Custom Messages (i18n)

Override the default English messages by providing a messages object:

ts
import { defaultSelectMessages } from 'vue-superselect'

const frenchMessages = {
  ...defaultSelectMessages,
  selected: (label: string) => `${label} selectionne`,
  removed: (label: string) => `${label} supprime`,
  cleared: () => 'Selection effacee',
}

Pass custom messages through the composable API or context when building custom wrappers.

Data Attributes for Styling

Every option element receives data attributes that reflect its current state. Use these for CSS styling instead of relying on class names:

AttributeValuesWhen
data-selected"true" / "false"Whether the option is selected
data-highlighted"true" / "false"Whether the option is keyboard-highlighted
data-disabled"true" / "false"Whether the option is disabled
data-state"open" / "closed"On the root element, whether dropdown is open

Example CSS using data attributes:

css
[data-highlighted="true"] {
  background-color: #e0f2fe;
}

[data-selected="true"] {
  font-weight: 600;
  color: #0369a1;
}

[data-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
}

The SelectContent element also receives positioning attributes when using Floating UI:

AttributeExample ValuesPurpose
data-side"top", "bottom", "left", "right"Which side the dropdown opened on
data-align"start", "center", "end"Alignment relative to the trigger

Focus Management

  • Clicking the control area focuses the input
  • Selecting an option (single select) returns focus to the input and closes the dropdown
  • Selecting an option (multi-select) keeps focus in the input and the dropdown open
  • Pressing Escape returns focus to the input
  • Tab moves focus out of the component naturally

Focus is trapped within the component while the dropdown is open. Arrow keys navigate options, not the page.

Testing Accessibility

To verify accessibility in your application:

  1. Keyboard-only test: navigate the entire select without a mouse
  2. Screen reader test: listen for announcements with VoiceOver (macOS), NVDA (Windows), or Orca (Linux)
  3. Inspect ARIA: use browser DevTools to verify role, aria-expanded, and aria-activedescendant update correctly
  4. axe/Lighthouse: run automated accessibility audits

Next Steps