Select
- Usage
- Styling
Select allows users to choose a single value from a list of options presented in an overlay.
new tab
<vaadin-select
label="Sort by"
.items="${this.items}"
.value="${this.items[0].value}"
></vaadin-select>
The drop-down menu can be opened with a click, up and down arrow keys, or by typing the initial character of one of the options.
Dividers
Dividers can be used to group related options. Use dividers sparingly to avoid creating unnecessary visual clutter.
new tab
private accessor items = [
{
label: 'Most recent first',
value: 'recent',
},
{
component: 'hr',
},
{
label: 'Rating: high to low',
value: 'rating-desc',
},
{
label: 'Rating: low to high',
value: 'rating-asc',
},
{
component: 'hr',
},
{
label: 'Price: high to low',
value: 'price-desc',
},
{
label: 'Price: low to high',
value: 'price-asc',
},
];
For large data sets, it’s preferable to use Combo Box instead of Select. This allows users to filter the list of options.
Disabled Items
Items can be disabled. This prevents users from selecting them, while still showing that the items would be available for selection under different circumstances.
new tab
private accessor items = [
{
label: 'XS (out of stock)',
value: 'xs',
disabled: true,
},
{
label: 'S',
value: 's',
},
{
label: 'M',
value: 'm',
},
{
label: 'L',
value: 'l',
},
{
label: 'XL',
value: 'xl',
},
];
Caution
|
Accessibility
Some assistive technologies might not announce disabled options.
|
Basic Features
The following features, common to most input field components, are supported:
Label
The label is used to identify the input field. It supports plain-text content, and its length is limited to the width of the field. Helpers and Tooltips can be used to provide additional information that doesn’t fit into the label.
Visible labels are strongly recommended for all input fields. In cases where the built-in label cannot be used, an external element can be associated as the field’s label through the aria-labelledby
attribute. Fields without any visible label should include an invisible label for assistive technologies with the aria-label
attribute.
Helper
Helpers are used to provide additional information that the user may need to enter in the field, such as format requirements or explanations of the field’s purpose below the field.
A style variant is available for rendering the helper above the field.
In addition to plain text, helpers can contain components and HTML elements. However, complex and interactive content is likely to have accessibility issues.
Tooltip
Tooltips are small text pop-ups displayed on hover, and on keyboard-focus. They can be used to provide additional information about a field. This can be useful in situations where an always visible Helper is not appropriate. Helpers are generally recommended in favor of tooltips, though, as they provide much better discoverability and mobile support. See the Tooltip documentation for more information.
Prefix
A prefix element — rendered at the start of the field — can be used to display units, icons, and similar visual cues to the field’s purpose or format.
External & Invisible Labels (ARIA)
Visible labels are strongly recommended for all input fields. In situations where the built-in label cannot be used, an external element can be associated as the field’s label through its element id
. Fields without any visible label should be provided an invisible label for assistive technologies like screen readers.
<!-- Associates external element as label: -->
<label id="external-label">This is the label</label>
<vaadin-select accessible-name-ref="external-label">...
<!-- Invisible label for screen readers: -->
<vaadin-select accessible-name="This is the label">...
new tab
<vaadin-select
label="Label"
helper-text="Helper text"
placeholder="Placeholder"
.items="${this.items}"
>
<vaadin-tooltip slot="tooltip" text="Tooltip text"></vaadin-tooltip>
<vaadin-icon slot="prefix" icon="vaadin:vaadin-h"></vaadin-icon>
</vaadin-select>
Read-Only & Disabled
Fields used to display values should be set to read-only
mode to prevent editing. Read-only fields are focusable and visible to screen readers. They can display tooltips. Their values can be selected and copied.
Fields that are currently unavailable should be disabled
. The reduced contrast of disabled fields makes them inappropriate for displaying information. They can’t be focused or display tooltips. They’re invisible to screen readers, and their values cannot be selected and copied.
Disabled fields can be useful in situations where they can become enabled based on some user action. Consider hiding fields entirely if there’s nothing the user can do to make them editable.
new tab
<vaadin-select
readonly
label="Read-only"
value="${this.items[0].value}"
.items="${this.items}"
></vaadin-select>
<vaadin-select disabled label="Disabled"></vaadin-select>
Style Variants
The following style variants can be applied:
Text Alignment
Three different text alignments are supported: left
, which is the default; center
; and right
.
Right-alignment is recommended for numerical values when presented in vertical groups. This tends to aid interpretation and comparison of values.
Small Variant
The small variant can be used to make individual fields more compact. The default size of fields can be customized with style properties.
Helper Above Field
The helper can be rendered above the field, and below the label.
Borders
Borders can be applied to the field surface by providing a value (e.g., 1px
) to the --vaadin-input-field-border-width
CSS property. This can be applied globally to all input fields using the html
selector, or to individual component instances. Borders are required to achieve WCAG 2.1 level AA conformant color contrast with the default Lumo styling of fields.
You can override the default border color with the --vaadin-input-field-border-color
property.
new tab
<vaadin-select
theme="align-right small helper-above-field"
label="Label"
helper-text="Helper text"
style="--vaadin-input-field-border-width: 1px;"
.items="${this.items}"
value="${this.items[0].value}"
></vaadin-select>
Placeholder
Use the placeholder feature to provide an inline text prompt for the field. Don’t create or use a separate item for this purpose.
new tab
<vaadin-select label="Size" placeholder="Select size" .items="${this.items}"></vaadin-select>
Empty Selection Item (Flow Only)
An empty item can be set as the first option. Use it in cases where you want to allow users to clear their selection. The value of the empty item is represented as null
.
Customizing Empty Selection Caption
The label for the empty item is customizable. The caption that you set replaces the placeholder for the empty selection item.
new tab
select.setEmptySelectionAllowed(true);
select.setEmptySelectionCaption("Unknown size");
Custom Item Label
When using complex values, a label can be set to represent the item value as plain text.
new tab
this.items = people.map((person) => ({
label: `${person.firstName} ${person.lastName}`,
value: `${person.id}`,
}));
When using custom item renderers with rich content, a label can be set to represent the item value when it’s selected.
new tab
<!-- Use the label attribute to display full name of the person as selected value label -->
<vaadin-item value="${person.id}" label="${formatPersonFullName(person)}">
<div style="display: flex; align-items: center;">
<img
src="${person.pictureUrl}"
alt="Portrait of ${formatPersonFullName(person)}"
style="width: var(--lumo-size-m); margin-right: var(--lumo-space-s);"
/>
<div>
${formatPersonFullName(person)}
<div
style="font-size: var(--lumo-font-size-s); color: var(--lumo-secondary-text-color);"
>
${person.profession}
</div>
</div>
</div>
</vaadin-item>
Note
|
Flow-Specific
When using
The same applies when using a data source that may contain null values. |
Custom Item Presentation
Items can be rendered with rich content instead of plain text. This can be useful to provide information in a more legible fashion than appending it to the item text.
new tab
<vaadin-select
label="Choose doctor"
${selectRenderer(this.renderer, this.people)}
></vaadin-select>
...
private renderer = () => html`
<vaadin-list-box>
${this.people.map(
(person) => html`
<vaadin-item value="${person.id}">
<!--
NOTE
We are using inline styles here to keep the example simple.
We recommend placing CSS in a separate style sheet and
encapsulating the styling in a new component.
-->
<div style="display: flex; align-items: center;">
<img
src="${person.pictureUrl}"
alt="Portrait of ${person.firstName} ${person.lastName}"
style="width: var(--lumo-size-m); margin-right: var(--lumo-space-s);"
/>
<div>
${person.firstName} ${person.lastName}
<div
style="font-size: var(--lumo-font-size-s); color: var(--lumo-secondary-text-color);"
>
${person.profession}
</div>
</div>
</div>
</vaadin-item>
`
)}
</vaadin-list-box>
`;
Best Practices
Don’t Use as a Menu
Select is an input field component, not a generic menu component. Use Menu Bar to create overlays for actions.
Related Components
Component | Usage Recommendation |
---|---|
Better accessibility than Select, as all options are visible without user interaction. | |
Filterable list of options. Appropriate for large sets of options. Supports lazy-loading entry of custom values. | |
Scrollable inline list of options. Supports single and multi-select. | |
Overlay menus for items that trigger actions. |
F53C23C7-4798-402A-A7C9-47416795D4C5