Select menu (HTML)
Select menus allow users to make a single selection from a list of options.
Looking for the web component? See Select (web component)
Basic usage
Permalink to "Basic usage"The following configuration demonstrates a bare-minimum select pattern. All other variations are modifications of this configuration.
<bolt-select-control>
<div class="bolt-label-wrapper">
<label for="select-default">
Select menu name
<span class="bolt-annotation bolt-optional">(optional)</span>
</label>
</div>
<select id="select-default">
<option value="">Select</option>
<option value="item1">Item one</option>
<option value="item2">Item two</option>
<option value="item3">Item three</option>
</select>
<bolt-select-facade></bolt-select-facade>
</bolt-select-control>
<bolt-select-control>
<div class="bolt-label-wrapper">
<label for="select-disabled">
Select menu name
<span class="bolt-annotation bolt-optional">(optional)</span>
</label>
</div>
<select
id="select-disabled"
disabled
>
<option value="">Select</option>
<option value="item1">Item one</option>
<option value="item2">Item two</option>
<option value="item3">Item three</option>
</select>
<bolt-select-facade></bolt-select-facade>
</bolt-select-control>
<bolt-select-control class="bolt-invalid">
<div class="bolt-label-wrapper">
<label for="select-invalid">Select menu name</label>
</div>
<select
aria-describedby="select-error"
id="select-invalid"
required
>
<option value="">Select</option>
<option value="item1">Item one</option>
<option value="item2">Item two</option>
<option value="item3">Item three</option>
</select>
<bolt-select-facade></bolt-select-facade>
<footer>
<bolt-field-error id="select-error">
You must select an option.
</bolt-field-error>
</footer>
</bolt-select-control>
Help text body content.
<bolt-select-control>
<div class="bolt-label-wrapper">
<label for="select-with-help">
Select menu name
<span class="bolt-annotation bolt-optional">(optional)</span>
</label>
<bolt-contextual-help
heading="Help text heading"
type="push"
>
<p>Help text body content.</p>
</bolt-contextual-help>
</div>
<select id="select-with-help">
<option value="">Select</option>
<option value="item1">Item one</option>
<option value="item2">Item two</option>
<option value="item3">Item three</option>
</select>
<bolt-select-facade></bolt-select-facade>
</bolt-select-control>
Help text body content.
<bolt-select-control>
<div class="bolt-label-wrapper">
<label for="select-with-help-disabled">
Select menu name
<span class="bolt-annotation bolt-optional">(optional)</span>
</label>
<bolt-contextual-help
disabled
heading="Help text heading"
type="push"
>
<p>Help text body content.</p>
</bolt-contextual-help>
</div>
<select
disabled
id="select-with-help-disabled"
>
<option value="">Select</option>
<option value="item1">Item one</option>
<option value="item2">Item two</option>
<option value="item3">Item three</option>
</select>
<bolt-select-facade></bolt-select-facade>
</bolt-select-control>
Adjusting select box size
Permalink to "Adjusting select box size"By default, the select box fills the width of the bolt-select-control element.
To set an explicit width on the select box only, the select and bolt-select-facade elements must have the same width. The example below demonstrates how to set an explicit width for the select box. While the example uses the style attribute, it is recommended to use a CSS class to set the width of both elements.
<bolt-select-control>
<div class="bolt-label-wrapper">
<label for="select-explicit-width">
Select menu name
<span class="bolt-annotation bolt-optional">(optional)</span>
</label>
</div>
<select
id="select-explicit-width"
style="width: 320px;"
>
<option value="">Select</option>
<option value="item1">Item one</option>
<option value="item2">Item two</option>
<option value="item3">Item three</option>
</select>
<bolt-select-facade style="width: 320px;"></bolt-select-facade>
</bolt-select-control>
To display the selected option text below the select box, logic must be implemented by the consumer. The example below demonstrates how to implement the logic using JavaScript.
<bolt-select-control>
<div class="bolt-label-wrapper">
<label for="select-long-option">
Fund name
<span class="bolt-annotation bolt-optional">(optional)</span>
</label>
</div>
<select
id="select-long-option"
style="width: 320px;"
>
<option value="">Select</option>
<option value="item1">Nationwide AllianzGI International Growth Fund</option>
<option value="item2">Nationwide Bailard International Equities Fund Equity Funds</option>
<option value="item3">Nationwide Global Sustainable Equity Fund</option>
</select>
<bolt-select-facade style="width: 320px;"></bolt-select-facade>
<footer>
<div
aria-hidden="true"
class="bolt-select-long-option-text"
id="selectedValueText"
></div>
</footer>
</bolt-select-control>
<script>
let displayValue = document.querySelector('#selectedValueText');
let select = document.querySelector('#select-long-option');
select.addEventListener('change', function() {
if (select.value) {
displayValue.textContent = select.options[select.selectedIndex].text;
} else {
displayValue.textContent = '';
}
});
</script>
<bolt-select-control class="bolt-select-fit-content">
<div class="bolt-label-wrapper">
<label for="select-fit-content">
Select menu name
<span class="bolt-annotation bolt-optional">(optional)</span>
</label>
</div>
<select id="select-fit-content">
<option value="">Select</option>
<option value="item1">Item one</option>
<option value="item2">Item two</option>
<option value="item3">Item three</option>
</select>
<bolt-select-facade></bolt-select-facade>
</bolt-select-control>
Using ARIA attributes
Permalink to "Using ARIA attributes"Select menu name
<p id="select-label">Select menu name</p>
<bolt-select-control>
<select
aria-labelledby="select-label"
id="select-with-labelledby"
>
<option value="">Select</option>
<option value="item1">Item one</option>
<option value="item2">Item two</option>
<option value="item3">Item three</option>
</select>
<bolt-select-facade></bolt-select-facade>
</bolt-select-control>
<bolt-select-control>
<select
aria-label="Select menu name"
id="select-with-arialabel"
>
<option value="">Select</option>
<option value="item1">Item one</option>
<option value="item2">Item two</option>
<option value="item3">Item three</option>
</select>
<bolt-select-facade></bolt-select-facade>
</bolt-select-control>
The HTML implementation provides maximum control over the markup. However, it is up to the consumer to implement all advanced interaction logic.
If you want Bolt to handle the interaction logic, check out the web component implementation.
This implementation should be compatible with @angular/forms without the need for additional dependencies.
Select facade
Permalink to "Select facade"The <bolt-select-facade> custom element is designed exclusively for use within the select control pattern in order to encapsulate the complex CSS required to present a styled select control.
All APIs built for <bolt-select-facade> should be considered "private" and are subject to change at any time, without warning. Any use of the custom element outside of documented patterns shall be done so at consumer's own risk.
Select control
Permalink to "Select control"Syntax
Permalink to "Syntax"<!-- Root (REQUIRED) -->
<bolt-select-control
class="
[bolt-invalid]
[bolt-select-fit-content]
"
>
<!-- Label wrapper (REQUIRED, unless using aria-label or aria-labelledby) -->
<div class="bolt-label-wrapper">
<!-- Label (REQUIRED) -->
<label for="SELECT_ID">
Label text
<!-- Annotation (optional) -->
<span class="bolt-annotation bolt-optional">(optional)</span>
</label>
<!-- Contextual help (optional) -->
<bolt-contextual-help
[disabled]
heading="Heading"
type="push"
...
>
...
</bolt-contextual-help>
</div>
<!-- Select (REQUIRED) -->
<select
[aria-describedby="ERRORS_ID"]
[disabled]
[required]
id="SELECT_ID"
...
>
<option value="">Select</option>
<option value="1" [selected]>Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<!-- Facade (REQUIRED) -->
<bolt-select-facade></bolt-select-facade>
<!-- Footer (optional) -->
<footer>
<!-- Long option text display (optional) -->
<div
aria-hidden="true"
class="[bolt-select-long-option-text]"
></div>
<!-- Error (optional) -->
<bolt-field-error id="ERRORS_ID">...</bolt-field-error>
</footer>
</bolt-select-control>
Anatomy
Permalink to "Anatomy"A select control is comprised of the following items:
- Root (REQUIRED)
- MAY apply
.bolt-invalidclass to apply "invalid" appearance to theselectelement. - MAY apply
.bolt-select-fit-contentclass to set the width of theselectelement based on the longest option.
- MAY apply
- Label wrapper (REQUIRED, unless using
aria-labeloraria-labelledbyon<select>)- MUST apply
.bolt-label-wrapperclass to ensure proper layout oflabelelement with any optional items.
- MUST apply
- Label (REQUIRED)
- MUST have a
[for]attribute with value matching the[id]of theselect. - MUST be first item inside
<div class="bolt-label-wrapper">element.
- MUST have a
- Annotation (optional)
- When present, communicates that selecting an option is not critical for workflow progression.
- MUST match
.bolt-annotation.bolt-optionalCSS selector. - MUST be an inline element inside of
labelelement. - Should have
"(optional)"as inner text.
- Contextual help (optional)
- MUST have
[type="push"]. - MUST be last item inside
<div class="bolt-label-wrapper">element. - See contextual help component for more information.
- MUST have
- Select (REQUIRED)
- MUST have an
[id]attribute. - Refer to MDN for best practices on using the HTML
<select>element.
- MUST have an
- Facade (REQUIRED)
- MUST be present to display the select on screen.
- Footer (optional)
- Supports wrapping optional elements to be associated with the select.
- Long option text display (optional)
- Placeholder element to display the text of the selected option below the select box.
- MUST apply
.bolt-select-long-option-textclass to style the text. - MUST be wrapped in the footer.
- MUST implement logic to display the selected option text in this placeholder element.
- Error (optional)
- Defines a single error message.
- A
<bolt-field-error>element is recommended. - MUST have an
[id]attribute that matches the[aria-describedby]attribute of theselect. - MUST be wrapped in the footer.
- Error and disabled state should not be used at the same time.
General guidelines
Permalink to "General guidelines"- Select is used for selecting one item from a list of between 6 and 15 items. Avoid overwhelming users with too many options.
- Order the options in a Select logically.
- Only if a deliberate selection is required or if no option can be defaulted, should a Select display the placeholder text "Select" before a user interacts with it. Otherwise, any available option can be set as the Select's default.
- Combine a Select with a field label for context and the best accessibility. A field label is not needed when the component is used in a table. (e.g. where a column header provides accessible context.)
- When a screen does not provide enough space for a user to see the full text of an option, place the text, in full, below the Select to let the user know what they have chosen.
- Input validation and error messaging for a Select should only occur after a user submits a form.
- Select should never be in both error and disabled states at the same time.
When to use
Permalink to "When to use"- When a user needs to choose one option from a simple list of 6 or more options.
- Use Select if space constraints don't allow a large number of radio buttons to be used for selecting one option.
When not to use
Permalink to "When not to use"- Avoid using a Select when typing may be faster.
- Avoid if all options are required to be displayed concurrently.
When to use something else
Permalink to "When to use something else"- Avoid Select when displaying more than 15 options; consider using a Text field or Autocomplete, especially if filtering would be beneficial.
- Consider an alternative pattern when options are links navigating users to various places.
- Consider using Radio button for a list between 2 and 5 predefined options when space is available.
- Use Radio button instead of Select for a single boolean option.
- Use Switch for a binary decision where the input can be recorded or updated immediately.
- Use Checkbox for user confirmation (e.g., "I agree to…" or "I have read…") instead of Select.
Do
- Order options in Select logically.
- Display a user's selected option after a choice is made.
- Have clear, short field labels that provide users with an idea of the options they will see before opening a Select.
Don't
- Don't disable options; hide them instead.
- Don't add subtext or images into a Select.
- Don't add too many options; but at least 6 options are recommended.
- Don't allow choosing an item from a Select to act as navigation. Allow the user to make a choice and then press a button to proceed.
Content guidelines
Permalink to "Content guidelines"- Select field labels and items use sentence case.
- Error messages use sentence case and include a period.
In addition to code requirements, the following guidelines should be taken into account to ensure maximum accessibility.
- A select control MUST define an accessible label via one of the following strategies:
labelelement withforattribute that matches the[id]of theselect.aria-labelattribute on theselectelement.aria-labelledbyattribute on theselectelement.