Select
The select allows users to select a single option from a list.
Modifiers list
Here is a list of available modifiers for an element:
flix-select--active
- triggers visual active state
flix-select--valid
- triggers visual valid state
flix-select--error
- triggers visual error state
flix-select--disabled
- triggers visual disabled state
flix-select--no-label
- use if select without label is needed (this makes sure all the icons and other elements still placed properly)
flix-select--multiple
- applies correct styles for select with `multiple` attribute
Normal and active states
Select boxes have same style options as normal inputs with a similar approach.
<div class="flix-form-row">
<div class="flix-select">
<label class="flix-select__label flix-label" for="select-simple">Countries</label>
<div class="flix-select__container">
<select id="select-simple" class="flix-select__field">
<option value="1">Germany</option>
<option value="2">France</option>
<option value="3">Austria</option>
<option value="4">The Netherlands</option>
</select>
</div>
</div>
</div>
<div class="flix-form-row">
<div class="flix-select flix-select--active">
<label class="flix-select__label flix-label" for="select-active">Countries</label>
<div class="flix-select__container">
<select id="select-active" class="flix-select__field" aria-describedby="select-active-info">
<option value="1">Germany</option>
<option value="2">France</option>
<option value="3">Austria</option>
<option value="4">The Netherlands</option>
</select>
</div>
<span class="flix-select__info" id="select-active-info">Additional info text for this field, if needed</span>
</div>
</div>
Validation and errors
To display an error state with meaningful error messages you must:
- If the field is required remember to add the
required
attribute to the select element; - Add
flix-select--error
modifier to component to enable the error appearance; - Add
aria-invalid="true"
to inform assistive technologies of the invalid input; - Add an
id
andaria-live="assertive"
to the info element that contains the error message; - Connect the error message with the select element using
aria-errormessage
attribute.
When the validation passes and the select is no longer invalid:
- Switch
--error
modifier to--valid
to update the visual appearance; - Switch
aria-invalid
to "false" to update the element valid status.
<div class="flix-form-row">
<div class="flix-select flix-select--error">
<label class="flix-select__label flix-label" for="select-error">Countries</label>
<div class="flix-select__container">
<select id="select-error" class="flix-select__field" required="" aria-invalid="true" aria-errormessage="select-error-message" aria-describedby="select-error-info">
<option disabled="" selected="">Please select something</option>
<option value="1">Germany</option>
<option value="2">France</option>
<option value="3">Austria</option>
<option value="4">The Netherlands</option>
</select>
</div>
<span class="flix-select__info" id="select-error-message" aria-live="assertive">An error occurred</span>
<span class="flix-select__info" id="select-error-info">Additional info text for this field, if needed</span>
</div>
</div>
For displaying a visual valid state add flix-select--valid
modifier and ensure aria-invalid="false"
attribute is correctly set.
<div class="flix-form-row">
<div class="flix-select flix-select--valid">
<label class="flix-select__label flix-label" for="select-valid">Countries</label>
<div class="flix-select__container">
<select id="select-valid" class="flix-select__field" aria-invalid="false">
<option disabled="" selected="">Please select something</option>
<option value="1">Germany</option>
<option value="2">France</option>
<option value="3">Austria</option>
<option value="4">The Netherlands</option>
</select>
</div>
</div>
</div>
Disabled
Add the flix-select--disabled
modifier to trigger the visual disabled state and add the disabled
attribute to the field to effectively disable any interaction.
<div class="flix-form-row">
<div class="flix-select flix-select--disabled">
<label class="flix-select__label flix-label" for="select-disabled">Countries</label>
<div class="flix-select__container">
<select id="select-disabled" class="flix-select__field" disabled="">
<option value="1">Germany</option>
<option value="2">France</option>
<option value="3">Austria</option>
<option value="4">The Netherlands</option>
</select>
</div>
</div>
</div>
Select with multiple choices
To add the correct styles for a select with multiple choices add the flix-select--multiple
modifier to the wrapper.
<div class="flix-select flix-select--multiple">
<label class="flix-select__label flix-label" for="select-multiple">Countries</label>
<div class="flix-select__container">
<select id="select-multiple" class="flix-select__field" multiple="" size="8">
<option value="1">Antarctica</option>
<option value="2">Brazil</option>
<option value="3">Chile</option>
<option value="4">Peru</option>
<option value="5">Venezuela</option>
<option value="6">Austria</option>
<option value="7">France</option>
<option value="8">Germany</option>
<option value="9">Ukraine</option>
<optgroup label="Out of Reach" disabled="">
<option value="10">Indonesia</option>
<option value="11">Japan</option>
<option value="12">South Korea</option>
<option value="13">Taiwan</option>
</optgroup>
</select>
</div>
</div>
Select without visible label
Certain cases and design decisions require you to use form fields without visible label. If the case there are 2 things you need to make sure doing:
- Add an
aria-label
attribute to the input to preserve basic accessibility guidelines; - Add a
flix-select--no-label
modifier class to component.
<div class="flix-form-row">
<div class="flix-select flix-select--no-label">
<div class="flix-select__container">
<select aria-label="Country" id="select-no-label" class="flix-select__field">
<option disabled="" selected="">Please select something</option>
<optgroup label="America">
<option value="1">Brazil</option>
<option value="2">Chile</option>
<option value="3">Peru</option>
<option value="4">Venezuela</option>
</optgroup>
<optgroup label="Europe" disabled="">
<option value="5">Germany</option>
<option value="6">France</option>
<option value="7">Austria</option>
<option value="8">The Netherlands</option>
</optgroup>
</select>
</div>
</div>
</div>
Placeholder options
Placeholder options should have disabled
and selected
attributes on them in order to remove them from the available selection list, and yet still show them as the initial placeholder option.
With icons
You can add an icon to be displayed on the left side of the select.
Just add an icon component inside of flix-select__container
and give it the flix-select__icon
class name in addition to the icon class.
<div class="flix-form-row">
<div class="flix-select">
<label class="flix-select__label flix-label" for="select-with-icon">Countries</label>
<div class="flix-select__container">
<i class="flix-select__icon flix-icon flix-icon--primary flix-icon-pin" aria-hidden="true"></i>
<select id="select-with-icon" class="flix-select__field">
<option value="0">Germany</option>
<option value="1">France</option>
<option value="2">Austria</option>
<option value="3">The Netherlands</option>
</select>
</div>
</div>
</div>
Make sure the icon comes before the select
element in the markup, icons on the right are not supported.
Inline labels
Inline labels work similar to icons, you should add them inside of the select container.
Unlike the icons, the inline labels deliver important information related to the select field format, for this reason you must connect them to the field for screen reader support.
- Add the inline label text inside a
flix-select__inline-label
element - Add an
id
to the inline label element - Connect it to the field by using
aria-describedby="{ID}"
on the field
This way, when screen reader users focus the input field the screen reader will be able to read out the inline label together with the input label and any error messages it contains.
<div class="flix-select">
<label class="flix-select__label flix-label" for="select-inline-label">Countries</label>
<div class="flix-select__container">
<span class="flix-select__inline-label" id="select-inline-label">Destination</span>
<select id="select-simple" class="flix-select__field">
<option value="0">Germany</option>
<option value="1">France</option>
<option value="2">Austria</option>
<option value="3">The Netherlands</option>
</select>
</div>
</div>