Skip to content

Select

A native select with the same label, hint and error wiring as every other field.

Preview

Code

The three render the same class names, the same ARIA and the same data attributes. That is checked when this site builds: a class in any of these samples that neither the markup contract nor the shipped stylesheet defines fails the build.

<div class="wsu-field">
  <label class="wsu-field__label" for="term">Term</label>
  <select class="wsu-select" id="term" name="term">
    <option value="" disabled selected>Choose a term</option>
    <option>Winter 2027</option>
    <option>Fall 2027</option>
  </select>
</div>

Why it works this way

  • Native, not a custom listbox. The platform control gets keyboard behavior, type-ahead, mobile pickers and forced-colors support for free, and none of them survive a rebuild in divs.
  • The placeholder option is disabled and has an empty value, so it cannot be submitted as an answer.

Accessibility

  • A label element with for (1.3.1).
  • aria-invalid and aria-describedby on error (3.3.1).

Success criteria in brackets refer to WCAG 2.2. Every one of them is checked by axe-core in both themes at three viewport widths before this page can be published. See Accessibility for what the gates are.

Props

Blade

AttributeDefaultWhat it does
namerequiredAlso the default id and error-bag key.
labelnullRendered as a real label.
options[]Values, or value and label pairs.
valueold inputFalls back to old() on a failed submit.
placeholdernullDisabled first option.
hintnullAbove the control, wired with aria-describedby.
errorthe error bagPass a string to override.
requiredfalseAdds the required attribute and the "(required)" text.
multiplefalseNative multiple select.
ida slug of nameSet it to change the id without changing name.
bag'default'Named error bag.

Vue

PropType and defaultWhat it does
modelValueString or Number, ''v-model.
optionsArray, [][{ value, label }] or plain strings.
placeholderString, ''Disabled first option.