Select
Overview
This component should only be used as a last resort.
Use the select component to help users select a single answer from a list.
Example Select contents
Nunjucks
{% from "components/select/_macro.njk" import onsSelect %}
{{
onsSelect({
"id": "select-example",
"name": "select",
"label": {
"text": "Question topic"
},
"options": [
{
"value": "",
"text": "Select an option",
"disabled": true,
"selected": true
},
{
"value": 1,
"text": "General"
},
{
"value": "people-who-live-here",
"text": "People who live here"
},
{
"value": "visitors",
"text": "Visitors"
},
{
"value": "household-accommodation",
"text": "Household and accommodation"
},
{
"value": "personal-details",
"text": "Personal details"
},
{
"value": "health",
"text": "Health"
},
{
"value": "qualifications",
"text": "Qualifications"
},
{
"value": "employment",
"text": "Employment"
}
]
})
}}
Nunjucks macro options
Name | Type | Required | Description |
---|---|---|---|
id | string | true | The HTML id of the select element. This used for the label’s for attribute. |
classes | string | false | Classes to add to the select element |
name | string | false | The HTML name attribute for the select element |
attributes | object | false | HTML attributes (for example, data attributes) to add to the select element |
label | Object<Label> | true | Settings for the label. The HTML for attribute will automatically be set to match the select id. |
options | Array<SelectOption> | true | An array of options for the component |
fieldId | string | false | The HTML id of the field |
fieldClasses | string | false | Classes for the field |
dontWrap | boolean | false | Prevents the select from being wrapped in a field component |
error | Error (ref) | false | Configuration for validation errors |
Name | Type | Required | Description |
---|---|---|---|
text | string | true | The text for the option |
value | string | false | The value for the option. If not specified the value will set by the text parameter |
selected | boolean | false | Set to “true” to make an option selected when the page loads. Only one option should have this set. |
disabled | boolean | false | Set to “true” to disable an option. Use to set a default placeholder option that can’t be selected, for example, “Select an option”. |
id | string | false | The HTML id of the option element. |
attributes | object | false | HTML attributes (for example, data attributes) to add to the option element |
Name | Type | Required | Description |
---|---|---|---|
text | string | true | The text content of the label |
description | string | false | Hint text to help users use the component |
classes | string | false | Classes to add to the label |
inline | boolean | false | Set to “true” to display the label on the same line and before the select element |
HTML
<div class="ons-field">
<label class="ons-label" for="select-example">Question topic</label>
<select id="select-example" name="select" class="ons-input ons-input--select">
<option value="" selected disabled>Select an option</option>
<option value="1">General</option>
<option value="people-who-live-here">People who live here</option>
<option value="visitors">Visitors</option>
<option value="household-accommodation">Household and accommodation</option>
<option value="personal-details">Personal details</option>
<option value="health">Health</option>
<option value="qualifications">Qualifications</option>
<option value="employment">Employment</option>
</select>
</div>
When not to use this component
For short lists, use radios.
If users will need to select multiple answers, use checkboxes.
Government Digital Service (GDS) research shows that long drop-down select boxes are not user friendly as:
- they are difficult to use on mobile devices
- they hide choices that could help users understand the question
- the scroll function in longer lists can be hard to use
- the expanded list cannot be styled so touch areas are small
You should especially avoid using selects:
- in forms
- to display a list that would require the user to scroll through the component
- where list items have long names
For more information, see Front-end London’s video on why users struggle with selects (opens in a new tab) .
Long lists
Users particularly struggle with selects when they are used for long lists.
However, long lists in general do not provide the best experience for users.
Content should be broken down into subcategories or qualifying questions should be asked to limit the number of options presented on a single page.
How to use this component
List items displayed in a select should be ordered alphabetically, unless a more logical order exists that is validated by user research.
The user should then be able to jump to the first option beginning with each letter. For example, if they press "s" when the component is in focus, they should be able to jump to the first option in the list beginning with "s".
Variants
Wide
Example Select Wide contents
Nunjucks
{% from "components/select/_macro.njk" import onsSelect %}
{{
onsSelect({
"id": "select-wide",
"name": "select",
"classes": "ons-input--block",
"label": {
"text": "Question topic"
},
"options": [
{
"value": "",
"text": "Select an option",
"disabled": true,
"selected": true
},
{
"value": "general",
"text": "General"
},
{
"value": "people-who-live-here",
"text": "People who live here"
},
{
"value": "visitors",
"text": "Visitors"
},
{
"value": "household-accommodation",
"text": "Household and accommodation"
},
{
"value": "personal-details",
"text": "Personal details"
},
{
"value": "health",
"text": "Health"
},
{
"value": "qualifications",
"text": "Qualifications"
},
{
"value": "employment",
"text": "Employment"
},
{
"value": "gdp",
"text": "Gross Domestic Product figures for year ending April 2018"
}
]
})
}}
Nunjucks macro options
Name | Type | Required | Description |
---|---|---|---|
id | string | true | The HTML id of the select element. This used for the label’s for attribute. |
classes | string | false | Classes to add to the select element |
name | string | false | The HTML name attribute for the select element |
attributes | object | false | HTML attributes (for example, data attributes) to add to the select element |
label | Object<Label> | true | Settings for the label. The HTML for attribute will automatically be set to match the select id. |
options | Array<SelectOption> | true | An array of options for the component |
fieldId | string | false | The HTML id of the field |
fieldClasses | string | false | Classes for the field |
dontWrap | boolean | false | Prevents the select from being wrapped in a field component |
error | Error (ref) | false | Configuration for validation errors |
Name | Type | Required | Description |
---|---|---|---|
text | string | true | The text for the option |
value | string | false | The value for the option. If not specified the value will set by the text parameter |
selected | boolean | false | Set to “true” to make an option selected when the page loads. Only one option should have this set. |
disabled | boolean | false | Set to “true” to disable an option. Use to set a default placeholder option that can’t be selected, for example, “Select an option”. |
id | string | false | The HTML id of the option element. |
attributes | object | false | HTML attributes (for example, data attributes) to add to the option element |
Name | Type | Required | Description |
---|---|---|---|
text | string | true | The text content of the label |
description | string | false | Hint text to help users use the component |
classes | string | false | Classes to add to the label |
inline | boolean | false | Set to “true” to display the label on the same line and before the select element |
HTML
<div class="ons-field">
<label class="ons-label" for="select-wide">Question topic</label>
<select id="select-wide" name="select" class="ons-input ons-input--select ons-input--block">
<option value="" selected disabled>Select an option</option>
<option value="general">General</option>
<option value="people-who-live-here">People who live here</option>
<option value="visitors">Visitors</option>
<option value="household-accommodation">Household and accommodation</option>
<option value="personal-details">Personal details</option>
<option value="health">Health</option>
<option value="qualifications">Qualifications</option>
<option value="employment">Employment</option>
<option value="gdp">Gross Domestic Product figures for year ending April 2018</option>
</select>
</div>
With inline label
Example Select With Inline Label contents
Nunjucks
{% from "components/select/_macro.njk" import onsSelect %}
{{
onsSelect({
"id": "select-example-with-inline-label",
"name": "select",
"classes": "ons-u-wa--@2xs",
"label": {
"text": "Sort by",
"inline": true
},
"options": [
{
"value": "best-match",
"text": "Best match",
"selected": true
},
{
"value": "latest",
"text": "Latest"
}
]
})
}}
Nunjucks macro options
Name | Type | Required | Description |
---|---|---|---|
id | string | true | The HTML id of the select element. This used for the label’s for attribute. |
classes | string | false | Classes to add to the select element |
name | string | false | The HTML name attribute for the select element |
attributes | object | false | HTML attributes (for example, data attributes) to add to the select element |
label | Object<Label> | true | Settings for the label. The HTML for attribute will automatically be set to match the select id. |
options | Array<SelectOption> | true | An array of options for the component |
fieldId | string | false | The HTML id of the field |
fieldClasses | string | false | Classes for the field |
dontWrap | boolean | false | Prevents the select from being wrapped in a field component |
error | Error (ref) | false | Configuration for validation errors |
Name | Type | Required | Description |
---|---|---|---|
text | string | true | The text for the option |
value | string | false | The value for the option. If not specified the value will set by the text parameter |
selected | boolean | false | Set to “true” to make an option selected when the page loads. Only one option should have this set. |
disabled | boolean | false | Set to “true” to disable an option. Use to set a default placeholder option that can’t be selected, for example, “Select an option”. |
id | string | false | The HTML id of the option element. |
attributes | object | false | HTML attributes (for example, data attributes) to add to the option element |
Name | Type | Required | Description |
---|---|---|---|
text | string | true | The text content of the label |
description | string | false | Hint text to help users use the component |
classes | string | false | Classes to add to the label |
inline | boolean | false | Set to “true” to display the label on the same line and before the select element |
HTML
<div class="ons-field ons-field--inline">
<label class="ons-label" for="select-example-with-inline-label">Sort by</label>
<select id="select-example-with-inline-label" name="select" class="ons-input ons-input--select ons-u-wa--@2xs">
<option value="best-match" selected>Best match</option>
<option value="latest">Latest</option>
</select>
</div>
Error messages
Use the correct errors pattern and show the error details above the drop-down.
Example Select With Error contents
Nunjucks
{% from "components/select/_macro.njk" import onsSelect %}
{{
onsSelect({
"id": "select-example-with-error",
"name": "select",
"label": {
"text": "Question topic"
},
"label": {
"text": "Question topic"
},
"options": [
{
"value": "",
"text": "Select an option",
"disabled": true,
"selected": true
},
{
"value": "general",
"text": "General"
},
{
"value": "people-who-live-here",
"text": "People who live here"
},
{
"value": "visitors",
"text": "Visitors"
},
{
"value": "household-accommodation",
"text": "Household and accommodation"
},
{
"value": "personal-details",
"text": "Personal details"
},
{
"value": "health",
"text": "Health"
},
{
"value": "qualifications",
"text": "Qualifications"
},
{
"value": "employment",
"text": "Employment"
}
],
"error": {
"id": "select-error",
"text": "Select a question topic"
}
})
}}
Nunjucks macro options
Name | Type | Required | Description |
---|---|---|---|
id | string | true | The HTML id of the select element. This used for the label’s for attribute. |
classes | string | false | Classes to add to the select element |
name | string | false | The HTML name attribute for the select element |
attributes | object | false | HTML attributes (for example, data attributes) to add to the select element |
label | Object<Label> | true | Settings for the label. The HTML for attribute will automatically be set to match the select id. |
options | Array<SelectOption> | true | An array of options for the component |
fieldId | string | false | The HTML id of the field |
fieldClasses | string | false | Classes for the field |
dontWrap | boolean | false | Prevents the select from being wrapped in a field component |
error | Error (ref) | false | Configuration for validation errors |
Name | Type | Required | Description |
---|---|---|---|
text | string | true | The text for the option |
value | string | false | The value for the option. If not specified the value will set by the text parameter |
selected | boolean | false | Set to “true” to make an option selected when the page loads. Only one option should have this set. |
disabled | boolean | false | Set to “true” to disable an option. Use to set a default placeholder option that can’t be selected, for example, “Select an option”. |
id | string | false | The HTML id of the option element. |
attributes | object | false | HTML attributes (for example, data attributes) to add to the option element |
Name | Type | Required | Description |
---|---|---|---|
text | string | true | The text content of the label |
description | string | false | Hint text to help users use the component |
classes | string | false | Classes to add to the label |
inline | boolean | false | Set to “true” to display the label on the same line and before the select element |
HTML
<div class="ons-panel ons-panel--error ons-panel--no-title" id="select-error">
<span class="ons-panel__assistive-text ons-u-vh">Error: </span>
<div class="ons-panel__body">
<p class="ons-panel__error">
<strong>Select a question topic</strong>
</p>
<div class="ons-field">
<label class="ons-label" for="select-example-with-error">Question topic</label>
<select id="select-example-with-error" name="select" class="ons-input ons-input--select ons-input--error">
<option value="" selected disabled>Select an option</option>
<option value="general">General</option>
<option value="people-who-live-here">People who live here</option>
<option value="visitors">Visitors</option>
<option value="household-accommodation">Household and accommodation</option>
<option value="personal-details">Personal details</option>
<option value="health">Health</option>
<option value="qualifications">Qualifications</option>
<option value="employment">Employment</option>
</select>
</div>
</div>
</div>
If a drop-down option has not been selected
Use “Select [whatever topic the drop-down is asking for]”.
For example, “Select a question topic”.
How to check a drop-down selection
You should check that users have selected one of the drop-down options and show an error message if they have not.
Help improve this page
Let us know how we could improve this page, or share your user research findings. Discuss the ‘Select’ component on GitHub (opens in a new tab)