The dropdown displays multiple options in a compact way. Tapping inside a dropdown shows the options in a native list, from which one is selectable.
Configurator
LiveDropdown: label, selection, hint, error message and state
HTML
<oc-dropdown-v1 label="Land" empty-option hint="Wähle das Land aus, in dem du lebst."><option>Deutschland</option><option>Österreich</option><option>Schweiz</option><option>Frankreich</option><option>Niederlande</option></oc-dropdown-v1>
Error: The error variant is not only visualized by the error color but also by an error icon, which is due to accessibility. Additionally, the error should be explained.
Default
Error
Livedefault and errorHTML
<p class="demo-label">Default</p>
<oc-dropdown-v1 label="Anrede" empty-option hint="Für eine persönliche Ansprache."><option>Frau</option><option>Herr</option><option>Divers</option></oc-dropdown-v1>
<p class="demo-label">Error</p>
<oc-dropdown-v1 label="Anrede" empty-option validation-message="Bitte wähle eine Anrede aus." hint="Für eine persönliche Ansprache."><option>Frau</option><option>Herr</option><option>Divers</option></oc-dropdown-v1>
Hint and error
The dropdown comes with an optional hint. The hint helps the user choosing the correct answer and provides further context. The error is shown additionally above the hint if the user made a wrong input. It helps the user understanding the mistake and fixing the input.
Hint
Error and hint
Livehint and errorHTML
<p class="demo-label">Hint</p>
<oc-dropdown-v1 label="Land" empty-option hint="Wähle das Land aus, in dem du lebst."><option>Deutschland</option><option>Österreich</option><option>Schweiz</option></oc-dropdown-v1>
<p class="demo-label">Error and hint</p>
<oc-dropdown-v1 label="Land" empty-option validation-message="Bitte wähle ein Land aus, um fortzufahren." hint="Wähle das Land aus, in dem du lebst."><option>Deutschland</option><option>Österreich</option><option>Schweiz</option></oc-dropdown-v1>
When the user chooses an option the label will move to the top left and the selection will be displayed inside the container. Depending on the position of the dropdown, the dropdown can open upward or downward. The dropdown uses the native dropdown list of the operating system.
Tap inside the dropdown, then choose a selection
↓ after the selection
LiveinteractionHTML
<oc-dropdown-v1 label="Versandart" empty-option hint="Hinweis"><option>Standardversand</option><option>Expressversand</option><option>Wunschtermin</option><option>Abholung im Paketshop</option><option>Abholung in der Filiale</option></oc-dropdown-v1>
<oc-dropdown-v1 label="Versandart" value="Expressversand" hint="Hinweis"><option>Standardversand</option><option>Expressversand</option><option>Wunschtermin</option><option>Abholung im Paketshop</option><option>Abholung in der Filiale</option></oc-dropdown-v1>
Fitting
The width of the dropdown is set to fill-parent by default. The dropdown's height uses fit-content and adapts when a hint or error is visible.
Fills the parent width, height fits the content
LivefittingHTML
<p class="demo-label">Fills the parent width, height fits the content</p>
<oc-dropdown-v1 label="Anrede" empty-option hint="Hinweis"><option>Frau</option><option>Herr</option><option>Divers</option></oc-dropdown-v1>
Placement
You can place multiple dropdowns side by side. When placing them horizontally, make sure there is an 8px gap between them. Use a form group to set only one hint and error for horizontally placed dropdowns. Vertically, there should be a 24px gap.
Side by side in a form group, 8px gap
Livehint and errorHTML
<p class="demo-label">Side by side in a form group, 8px gap</p>
<oc-form-group-v1 orientation="horizontal" flex-behavior="grow" gap="var(--oc-base-dimension-8)" hint="Hinweis" oc-aria-label="Lieferung">
<oc-dropdown-v1 label="Land" empty-option><option>Deutschland</option><option>Österreich</option></oc-dropdown-v1>
<oc-dropdown-v1 label="Versandart" empty-option><option>Standard</option><option>Express</option></oc-dropdown-v1>
</oc-form-group-v1>
Stacked, 24px gap
Livevertical placementHTML
<p class="demo-label">Stacked, 24px gap</p>
<oc-form-group-v1 orientation="vertical" gap="var(--oc-base-dimension-24)" oc-aria-label="Lieferung">
<oc-dropdown-v1 label="Land" empty-option hint="Hinweis"><option>Deutschland</option><option>Österreich</option></oc-dropdown-v1>
<oc-dropdown-v1 label="Versandart" empty-option hint="Hinweis"><option>Standard</option><option>Express</option></oc-dropdown-v1>
<oc-dropdown-v1 label="Zustellung" empty-option hint="Hinweis"><option>Bis zur Haustür</option><option>Bis in die Wohnung</option></oc-dropdown-v1>
</oc-form-group-v1>
You can group multiple related dropdowns horizontally, e.g. for choosing the date - though a text field with type date may be appropriate for this task too. Form group can be used to set a hint for all combined form elements.
The dropdown component is used to provide a list of selectable options to the user.
It can be configured with a label, a hint, an error state, to be required and to be disabled.
The dropdown component offers a variety of styling variants such as default and error.
This component is configurable, allowing you to tailor its features and appearance to your specific needs.
To explore all the available options and adjust the component, use the component configurator and see the changes affect the component in real-time.
Usage guidelines
Before integrating the dropdown component into your project, make sure you have correctly installed the OTTO components package.
Look through the variations page for examples of possible component variations. Here, you can discover both common and specific variations that address different use cases.
This component has visual overflow.
It extends beyond its bounding box and is clipped by parent containers with overflow: hidden.
Ensure the parent container has sufficient padding to accommodate the component's full visual area.
Set options
There are two ways of setting options of the dropdown component:
Via the options attribute
Via the default slot
Set options via the options attribute
The following code shows the recommended way of setting options via the options attribute:
In case you are working with a template engine, the recommended way of setting options is via slots.
Note that the options are not reactive when set via the default slot.
This means that it is impossible to add, remove, or change the options once the dropdown is rendered.
The following code shows the recommended way of setting options via slots:
To make the dropdown recognizable for screen readers, use the label attribute to provide a clear and descriptive label.
Use the aria-label attribute on the label to provide additional context if the visible label is not sufficient.
See the general accessibility documentation for guidance on using oc-aria-label, including how it works with link and masked link behavior.
Keyboard navigation
The dropdown component supports keyboard navigation for accessibility purposes.
The following table lists the keyboard shortcuts available for this component:
Shortcut
Description
Tab
Focuses the dropdown element
Space
Open the dropdown if it is closed
Key Up / Down
Navigate through the available options
Space / Enter
Select option
Esc
Close the dropdown if it is open
Configuration (v1)
Dropdown configuration
Configure the dropdown component with the controls below and see the changes live in the preview canvas.
Click the Show code button within the preview canvas to see the source code for the current component configuration.
Interactive configurator (Storybook controls); every option is listed in the API section of this file.
API v1
Dropdown v1 API
API: <oc-dropdown-v1> (DropdownV1)
The Dropdown component is used to provide a list of selectable options to the user.
It can be configured with a label, a hint, an error state, to be required and to be disabled.
Attributes / properties
Attribute
Type
Default
Required
Description
variant
"default" | "error"
"default"
no
Sets the main styling and behavior of the dropdown.
label
string
undefined
no
Sets the text content for the dropdown label to provide a brief description of the input field.
value
string
undefined
no
Sets the initial value of the dropdown to the provided value for form processing.
Sets the selectable options by providing an array or JSON string. This is an alternative to the default slot. Read more in the section setting options.
hint
string
undefined
no
Provides additional information related to the dropdown below the input element.
validation-message
string
undefined
no
Provides a validation message related to the dropdown below the input element.
Implicitly sets the dropdown to the error state.
disabled
boolean
false
no
Disables the dropdown, preventing user interaction and input.
required
boolean
false
no
Marks the input as required for screen readers. Doesn't prevent form submission on its own.
Fired when the component is mounted to the DOM. The event is fired when the onMount hook of the component is called by the runtime.
oc-unmount
{ component: string; }
Fired when the component is unmounted from the DOM. The event is fired when the function returned by the onMount hook of the component is called by the runtime.
Variations (v1)
Variations
Listed below are the most common variations of the dropdown component as well as specific component variations for different use cases.
You can explore all available options using the component configurator, adjust the component to your needs, and see the changes live in a preview canvas.
A demonstration of how to use the dropdown in a form.
<h1>Complex Demo Form</h1>
<p>
This form contains two dropdowns. The first dropdown has options and optgroups defined via
attributes and the slot, while the second dropdown uses only options defined via the slot.
</p>
<form>
<oc-dropdown-v1
name="food"
hint="What do you like to eat?"
label="Something to eat"
options='[{"label":"Cake","value":"food4"},{"label":"Ice Cream","value":"food5"}]'
>
<option value="food1">Bread</option>
<option value="food2">Fries</option>
<option value="food3">Salad</option>
<optgroup label="Italian">
<option value="it-food4">Pasta</option>
<option value="it-food5">Pizza</option>
</optgroup>
<optgroup label="Japanese">
<option value="jp-food6">Sushi</option>
<option value="jp-food7">Ramen</option>
</optgroup>
<optgroup label="American">
<option value="am-food8">Steak</option>
<option value="am-food9">Burger</option>
</optgroup>
</oc-dropdown-v1>
<br />
<oc-dropdown-v1
name="beverages"
hint="What do you like to drink?"
label="Something to drink (required)"
required
>
<option value="drink1">Coffee</option>
<option value="drink2">Tea</option>
<option value="drink3">Beer</option>
</oc-dropdown-v1>
<br />
<div style="display: flex; gap: 8px;">
<oc-button-v1 type="reset" variant="secondary" id="clear" fit-content>Reset</oc-button-v1>
<oc-button-v1 type="submit" id="submit" fit-content>Submit</oc-button-v1>
</div>
</form>
<script>
(() => {
const form = document.querySelector("form");
let formData = {};
form.addEventListener("submit", (e) => {
e.preventDefault();
formData = Object.fromEntries(new FormData(form).entries());
alert("Submitted form data: " + JSON.stringify(formData));
});
})();
</script>
Story source (TypeScript, verbatim from Storybook)
{
name: "Complex Demo Form",
parameters: {
controls: {
disabled: true
}
},
argTypes: hideControlsBadge(Metadata),
render() {
return html` <h1>Complex Demo Form</h1>
<p>
This form contains two dropdowns. The first dropdown has options and optgroups defined via
attributes and the slot, while the second dropdown uses only options defined via the slot.
</p>
<form>
<oc-dropdown-v1
name="food"
hint="What do you like to eat?"
label="Something to eat"
options='[{"label":"Cake","value":"food4"},{"label":"Ice Cream","value":"food5"}]'
>
<option value="food1">Bread</option>
<option value="food2">Fries</option>
<option value="food3">Salad</option>
<optgroup label="Italian">
<option value="it-food4">Pasta</option>
<option value="it-food5">Pizza</option>
</optgroup>
<optgroup label="Japanese">
<option value="jp-food6">Sushi</option>
<option value="jp-food7">Ramen</option>
</optgroup>
<optgroup label="American">
<option value="am-food8">Steak</option>
<option value="am-food9">Burger</option>
</optgroup>
</oc-dropdown-v1>
<br />
<oc-dropdown-v1
name="beverages"
hint="What do you like to drink?"
label="Something to drink (required)"
required
>
<option value="drink1">Coffee</option>
<option value="drink2">Tea</option>
<option value="drink3">Beer</option>
</oc-dropdown-v1>
<br />
<div style="display: flex; gap: 8px;">
<oc-button-v1 type="reset" variant="secondary" id="clear" fit-content>Reset</oc-button-v1>
<oc-button-v1 type="submit" id="submit" fit-content>Submit</oc-button-v1>
</div>
</form>
<script>
(() => {
const form = document.querySelector("form");
let formData = {};
form.addEventListener("submit", (e) => {
e.preventDefault();
formData = Object.fromEntries(new FormData(form).entries());
alert("Submitted form data: " + JSON.stringify(formData));
});
})();
</script>`;
}
}