Dropdown
The dropdown displays a menu of actions anchored to its trigger, like the commands behind a "more" button or a user menu. For rich free-form content, reach for the popover; for picking a value in a form, use the select or combobox.
<button id="dd-demo-trigger" class="btn btn-outline">Open</button>
<div class="dropdown w-40" data-sp-toggle="#dd-demo-trigger">
<div class="dropdown-label">My Account</div>
<button class="dropdown-item">
Profile
<span class="dropdown-shortcut">⇧⌘P</span>
</button>
<button class="dropdown-item">
Billing
<span class="dropdown-shortcut">⌘B</span>
</button>
<button class="dropdown-item">
Settings
<span class="dropdown-shortcut">⌘S</span>
</button>
<div class="dropdown-separator"></div>
<button class="dropdown-item">Support</button>
<button class="dropdown-item" aria-disabled="true">API</button>
<div class="dropdown-separator"></div>
<button class="dropdown-item">
Log out
<span class="dropdown-shortcut">⇧⌘Q</span>
</button>
</div>Usage
Add the dropdown class to the menu panel and point it at its trigger with data-sp-toggle. It opens on click, positions itself against the trigger, supports arrow-key navigation, and closes when an action is chosen, on an outside click, or with Escape. Checkable items are the exception: toggling one keeps the menu open.
<!-- This is the trigger -->
<button id="my-trigger" class="btn btn-outline">Open</button>
<!-- This is the dropdown -->
<div class="dropdown" data-sp-toggle="#my-trigger">
<button class="dropdown-item">Profile</button>
<button class="dropdown-item">Settings</button>
</div>Examples
Basic
A plain menu of actions.
Groups
Group related items under a dropdown-label and divide groups with a dropdown-separator.
<button id="dd-groups-trigger" class="btn btn-outline">Open</button>
<div class="dropdown" data-sp-toggle="#dd-groups-trigger">
<div class="dropdown-label">My Account</div>
<button class="dropdown-item">Profile</button>
<button class="dropdown-item">Billing</button>
<button class="dropdown-item">Settings</button>
<div class="dropdown-separator"></div>
<button class="dropdown-item">GitHub</button>
<button class="dropdown-item">Support</button>
</div>Submenu
Nest menus by pointing a second dropdown at an item; dropdown-sub sizes it, and hover mode opens it when the pointer reaches the item. With the keyboard, ArrowRight, Enter, or Space opens it and ArrowLeft or Escape closes it back to its item.
<button id="dd-sub-trigger" class="btn btn-outline">Open</button>
<div class="dropdown" data-sp-toggle="#dd-sub-trigger">
<button class="dropdown-item">Team</button>
<button id="dd-sub-invite" class="dropdown-item">
Invite users
<svg class="ml-auto" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg>
</button>
<button class="dropdown-item">
New Team
<span class="dropdown-shortcut">⌘+T</span>
</button>
</div>
<div
class="dropdown dropdown-sub"
data-sp-toggle="#dd-sub-invite"
data-sp-mode="hover"
data-sp-placement="right-start"
>
<button class="dropdown-item">Email</button>
<button class="dropdown-item">Message</button>
<button id="dd-sub-more" class="dropdown-item">
More options
<svg class="ml-auto" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg>
</button>
<div class="dropdown-separator"></div>
<button class="dropdown-item">Advanced...</button>
</div>
<div
class="dropdown dropdown-sub"
data-sp-toggle="#dd-sub-more"
data-sp-mode="hover"
data-sp-placement="right-start"
>
<button class="dropdown-item">Calendly</button>
<button class="dropdown-item">Slack</button>
<div class="dropdown-separator"></div>
<button class="dropdown-item">Webhook</button>
</div>Shortcuts
Hint an item's keyboard shortcut with dropdown-shortcut; it right-aligns inside the item.
<button id="dd-shortcuts-trigger" class="btn btn-outline">Open</button>
<div class="dropdown" data-sp-toggle="#dd-shortcuts-trigger">
<div class="dropdown-label">My Account</div>
<button class="dropdown-item">
Profile
<span class="dropdown-shortcut">⇧⌘P</span>
</button>
<button class="dropdown-item">
Billing
<span class="dropdown-shortcut">⌘B</span>
</button>
<button class="dropdown-item">
Settings
<span class="dropdown-shortcut">⌘S</span>
</button>
<div class="dropdown-separator"></div>
<button class="dropdown-item">
Log out
<span class="dropdown-shortcut">⇧⌘Q</span>
</button>
</div>Icons
Lead items with an icon; svgs inside items are sized automatically.
<button id="dd-icons-trigger" class="btn btn-outline">Open</button>
<div class="dropdown" data-sp-toggle="#dd-icons-trigger">
<button class="dropdown-item">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
Profile
</button>
<button class="dropdown-item">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="14" x="2" y="5" rx="2"/><line x1="2" x2="22" y1="10" y2="10"/></svg>
Billing
</button>
<button class="dropdown-item">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915"/><circle cx="12" cy="12" r="3"/></svg>
Settings
</button>
<div class="dropdown-separator"></div>
<button class="dropdown-item dropdown-item-destructive">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m16 17 5-5-5-5"/><path d="M21 12H9"/><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/></svg>
Log out
</button>
</div>Checkboxes
Make items checkable with dropdown-item-checkbox: a hidden checkbox input holds the state, so checked, change events, and form submission work like any input. Toggling doesn't close the menu, so several can be flipped in one visit.
<button id="dd-check-trigger" class="btn btn-outline">Open</button>
<div class="dropdown w-40" data-sp-toggle="#dd-check-trigger">
<div class="dropdown-label">Appearance</div>
<div class="dropdown-item dropdown-item-checkbox">
<input type="checkbox" name="statusbar" checked />
Status Bar
</div>
<div class="dropdown-item dropdown-item-checkbox" aria-disabled="true">
<input type="checkbox" name="activitybar" />
Activity Bar
</div>
<div class="dropdown-item dropdown-item-checkbox">
<input type="checkbox" name="panel" />
Panel
</div>
</div>Radio group
Give dropdown-item-radio inputs a shared name and the browser keeps the set exclusive; read the choice with input[name=position]:checked.
<button id="dd-radio-trigger" class="btn btn-outline">Open</button>
<div class="dropdown w-32" data-sp-toggle="#dd-radio-trigger">
<div class="dropdown-label">Panel Position</div>
<div class="dropdown-item dropdown-item-radio">
<input type="radio" name="position" value="top" />
Top
</div>
<div class="dropdown-item dropdown-item-radio">
<input type="radio" name="position" value="bottom" checked />
Bottom
</div>
<div class="dropdown-item dropdown-item-radio">
<input type="radio" name="position" value="right" />
Right
</div>
</div>Destructive
Mark a dangerous action with dropdown-item-destructive.
<button id="dd-destructive-trigger" class="btn btn-outline">Actions</button>
<div class="dropdown" data-sp-toggle="#dd-destructive-trigger">
<button class="dropdown-item">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/><path d="m15 5 4 4"/></svg>
Edit
</button>
<button class="dropdown-item">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2v13"/><path d="m16 6-4-4-4 4"/><path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"/></svg>
Share
</button>
<div class="dropdown-separator"></div>
<button class="dropdown-item dropdown-item-destructive">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/><path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
Delete
</button>
</div>Disabled
Add aria-disabled to disable an item.
Avatar
Any element can be the trigger, like an avatar button for a user menu.
<button id="dd-avatar-trigger" class="btn btn-ghost btn-icon rounded-full">
<span class="avatar">
<img
class="avatar-image"
src="https://images.unsplash.com/photo-1750390200282-bf7f669a9946?w=640&h=640&fit=facearea&facepad=3.2&auto=format&q=100"
alt="Leila Navarro"
/>
<span class="avatar-fallback">LN</span>
</span>
</button>
<div class="dropdown" data-sp-toggle="#dd-avatar-trigger">
<button class="dropdown-item">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z"/><path d="m9 12 2 2 4-4"/></svg>
Account
</button>
<button class="dropdown-item">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="14" x="2" y="5" rx="2"/><line x1="2" x2="22" y1="10" y2="10"/></svg>
Billing
</button>
<button class="dropdown-item">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.268 21a2 2 0 0 0 3.464 0"/><path d="M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326"/></svg>
Notifications
</button>
<div class="dropdown-separator"></div>
<button class="dropdown-item">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m16 17 5-5-5-5"/><path d="M21 12H9"/><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/></svg>
Sign Out
</button>
</div>Complex
Groups, submenus, checkboxes, and radio items compose into a full application menu.
<button id="dd-complex-trigger" class="btn btn-outline">Open</button>
<div class="dropdown w-44" data-sp-toggle="#dd-complex-trigger">
<div class="dropdown-label">File</div>
<button class="dropdown-item">
New File
<span class="dropdown-shortcut">⌘N</span>
</button>
<button class="dropdown-item">
Save
<span class="dropdown-shortcut">⌘S</span>
</button>
<div class="dropdown-separator"></div>
<div class="dropdown-label">View</div>
<div class="dropdown-item dropdown-item-checkbox">
<input type="checkbox" name="sidebar" checked />
Show Sidebar
</div>
<div class="dropdown-item dropdown-item-checkbox">
<input type="checkbox" name="statusbar" />
Show Status Bar
</div>
<div class="dropdown-separator"></div>
<button id="dd-complex-theme" class="dropdown-item">
Theme
<svg class="ml-auto" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg>
</button>
</div>
<div
class="dropdown dropdown-sub"
data-sp-toggle="#dd-complex-theme"
data-sp-mode="hover"
data-sp-placement="right-start"
>
<div class="dropdown-label">Appearance</div>
<div class="dropdown-item dropdown-item-radio">
<input type="radio" name="theme" value="light" checked />
Light
</div>
<div class="dropdown-item dropdown-item-radio">
<input type="radio" name="theme" value="dark" />
Dark
</div>
<div class="dropdown-item dropdown-item-radio">
<input type="radio" name="theme" value="system" />
System
</div>
</div>Placement
Set where the menu opens relative to its trigger with data-sp-placement. It accepts any Floating UI placement, like top, right-start, or bottom-end, and the menu flips to the opposite side on its own when there isn't room.
<div class="flex gap-6">
<button id="dd-placement-start" class="btn btn-outline btn-sm">Start</button>
<button id="dd-placement-center" class="btn btn-outline btn-sm">
Center
</button>
<button id="dd-placement-end" class="btn btn-outline btn-sm">End</button>
</div>
<div
class="dropdown w-40"
data-sp-toggle="#dd-placement-start"
data-sp-placement="bottom-start"
>
<button class="dropdown-item">Profile</button>
<button class="dropdown-item">Settings</button>
</div>
<div
class="dropdown w-40"
data-sp-toggle="#dd-placement-center"
data-sp-placement="bottom"
>
<button class="dropdown-item">Profile</button>
<button class="dropdown-item">Settings</button>
</div>
<div
class="dropdown w-40"
data-sp-toggle="#dd-placement-end"
data-sp-placement="bottom-end"
>
<button class="dropdown-item">Profile</button>
<button class="dropdown-item">Settings</button>
</div>Hover
Add data-sp-mode="hover" to open the menu on hover instead of click; it closes when the pointer leaves both the trigger and the menu.
Options
Dropdown
Set each option with its own data-sp-* attribute on the dropdown element.
<div
class="dropdown"
data-sp-toggle="#my-trigger"
data-sp-placement="bottom-start"
></div>JavaScript
Events
Lifecycle events fire on the dropdown element; before* events are cancelable.
el.addEventListener("sp-beforehide", (e) => {
if (unsavedChanges) e.preventDefault(); // veto the close
});Methods
Get the instance with sp.dropdown(el), then call its methods:
const dropdown = sp.dropdown(document.querySelector("#my-dropdown"));
dropdown.show();