Dropdown
A fully accessible dropdown component with smooth animations, backdrop blur, keyboard navigation, grouped options, disabled items, and comprehensive dark mode support. Built with modern CSS effects and vanilla JavaScript.
Basic Usage
Add data-name to the wrapper to name the hidden input for form use.
<div class="dropdown" data-name="framework" style="width:220px">
<button class="dropdown-btn">Select framework…</button>
<div class="dropdown-content">
<div class="dropdown-label">Frontend</div>
<div class="dropdown-item" data-value="react">React</div>
<div class="dropdown-item" data-value="vue">Vue</div>
<div class="dropdown-item active" data-value="svelte">Svelte</div>
<div class="dropdown-divider"></div>
<div class="dropdown-label">Backend</div>
<div class="dropdown-item" data-value="express">Express</div>
<div class="dropdown-item" data-value="fastify">Fastify</div>
</div>
</div>
Dropdown Structure
Every dropdown consists of four main parts:
.dropdown— Root container withdata-namefor form integration.dropdown-btn— Toggle button showing the current selection.dropdown-content— Animated menu panel with backdrop blur effect.dropdown-item— Individual selectable options inside the content
Backdrop Blur Effect
The .dropdown-content uses backdrop-filter: blur(12px) for a modern
frosted-glass effect. This creates visual depth and elegance while maintaining readability.
backdrop-filter.
The blur is a visual enhancement, not a requirement for functionality.
Animations
The dropdown content animates in smoothly using a combination of opacity, scale, and transform properties. The toggle button's arrow rotates 180° when the content is open.
/* Animation on enter */
.dropdown.open .dropdown-content {
opacity: 1;
transform: translateY(0) scale(1);
pointer-events: auto;
transition: all 0.25s cubic-bezier(0.25, 0.8, 0.25, 1);
}
/* Animation on exit */
.dropdown-content {
opacity: 0;
transform: translateY(-10px) scale(0.95);
pointer-events: none;
}
Grouped Items with Labels and Dividers
Organize dropdown items into logical groups using .dropdown-label for headers
and .dropdown-divider for visual separation.
<div class="dropdown-label">🎨 Design</div> <div class="dropdown-item" data-value="figma">Figma</div> <div class="dropdown-item" data-value="sketch">Sketch</div> <div class="dropdown-divider"></div> <div class="dropdown-label">⚙️ Development</div> <div class="dropdown-item" data-value="vscode">VS Code</div>
Disabled Items
Use aria-disabled="true" on items that should not be selectable. This is useful
for placeholder text, "Coming soon" messages, or unavailable options.
<div class="dropdown-item" data-value="" aria-disabled="true"> Coming soon… </div>
Active State
Add the class active to a .dropdown-item to indicate the currently
selected option. This item will have a bold font weight and light background highlight.
Scrollable Content
Large dropdowns automatically scroll when content exceeds max-height: 15rem.
The scrollbar styling is consistent with the theme and adapts to dark mode.
scrollbar-width: thin and webkit pseudo-elements
for consistent appearance across browsers. The scrollbar adapts its color in dark mode.
Initialisation
// Dropdowns are automatically initialized with initAll()
// No manual initialization needed!
import('@kerkhoff-ict/solora/dist/index.js')
.then(sol => sol.initAll());
Keyboard Support
| Key | Action |
|---|---|
Enter / Space | Open dropdown |
↑ / ↓ | Navigate between items |
Enter | Select focused item |
Escape | Close dropdown |
Tab | Move focus out (closes dropdown) |
Form Integration
Each dropdown automatically creates a hidden <input type="hidden"> with the
name specified in data-name. This input holds the selected item's data-value.
<!-- Rendered output after selection --> <input type="hidden" name="framework" value="react">
Dark Mode
All dropdown styles automatically adapt when dark class is added to
<html>. The backdrop blur effect remains consistent, while text,
background, and hover states invert appropriately.
Toggle your theme to see dark mode in action. The dropdown will instantly adapt.
/* Light mode (default) */
.dropdown-btn {
background: var(--color-bg, #fefefe);
color: var(--color-text-dark, #000);
border: 1px solid rgba(0, 0, 0, 0.1);
}
/* Dark mode */
:root.dark .dropdown-btn {
background: #1c1c1e;
color: #f0f0f0;
border: 1px solid rgba(255, 255, 255, 0.2);
}
CSS Classes Reference
| Class / Attribute | Type | Description |
|---|---|---|
.dropdown | Container | Root wrapper; apply dimensions here |
data-name | Attribute | Names the hidden input field for forms |
.dropdown-btn | Interactive | Toggle button; displays current selection |
.dropdown-btn:after | Pseudo | Rotates arrow icon when open via transform |
.dropdown-content | Panel | Menu container with backdrop blur and scroll |
.dropdown.open | State | Applied when menu is visible |
.dropdown-item | Option | Individual selectable item |
.dropdown-item.active | State | Highlights the selected item (bold + background) |
aria-disabled="true" | Attribute | Marks items as non-selectable (grayed out) |
.dropdown-label | Label | Group header; not selectable |
.dropdown-divider | Divider | Thin horizontal line between groups |
data-value | Attribute | Value stored in hidden input when selected |
CSS Customization
Override these CSS variables to customize dropdown appearance across your entire site:
:root {
/* Button */
--dropdown-btn-bg: var(--color-bg, #fefefe);
--dropdown-btn-text: var(--color-text-dark, #000);
--dropdown-btn-border: rgba(0, 0, 0, 0.1);
--dropdown-btn-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
/* Content panel */
--dropdown-content-blur: 12px;
--dropdown-content-max-height: 15rem;
--dropdown-content-shadow: 0 12px 32px rgba(0, 0, 0, 0.12);
/* Items */
--dropdown-item-hover-bg: rgba(0, 0, 0, 0.05);
--dropdown-item-active-bg: rgba(0, 0, 0, 0.1);
}
Accessibility
- Dropdowns are fully keyboard navigable. Use
↑/↓to navigate,Enterto select. - ARIA attributes are handled automatically by the JavaScript initialization.
- Disabled items use
aria-disabled="true"so screen readers announce them as unavailable. - The hidden input respects the
data-nameattribute for proper form submission. - Always pair dropdowns with visible labels or use
aria-labelon the toggle button.
Performance Tips
- For dropdowns with many items (50+), ensure
max-heightis set to keep rendering efficient. - Backdrop blur is GPU-accelerated, but avoid excessive blur values on low-end devices.
- Re-initialize dropdown if content changes dynamically via
initAll().