Quick answer: A Bootstrap 5 dropdown is a button with data-bs-toggle="dropdown" followed by a ul.dropdown-menu of li > a.dropdown-item. The bundle JavaScript handles opening, closing, keyboard navigation and outside-click detection automatically. The mistakes that leave a menu dead or misaligned are a missing bundle script, a wrong data-bs-toggle, and putting the menu beside the button instead of inside the dropdown wrapper.
This is a component guide in our Bootstrap series; if the framework is not on your page yet, start with getting started with Bootstrap 5.
The complete dropdown in 3 steps
One wrapper, one toggle button, one menu. Nothing else is required for a working menu.
<!-- Step 1: the wrapper -->
<div class="dropdown">
<!-- Step 2: the toggle button -->
<button class="btn btn-secondary dropdown-toggle" type="button"
id="menuBtn" data-bs-toggle="dropdown" aria-expanded="false">
Actions
</button>
<!-- Step 3: the menu -->
<ul class="dropdown-menu" aria-labelledby="menuBtn">
<li><a class="dropdown-item" href="/new">New file</a></li>
<li><a class="dropdown-item" href="/open">Open</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item text-danger" href="/delete">Delete</a></li>
</ul>
</div>
The dropdown wrapper is not optional: it is the positioning context the menu is anchored to. dropdown-toggle draws the caret and wires the click. dropdown-divider is a full-width line, and any dropdown-item can take color utilities such as text-danger.
Variations you will actually use
| Want | Recipe |
|---|---|
| Menu opens upward | Add dropup to the wrapper |
| Menu opens sideways | Add dropend or dropstart |
| Right-aligned menu | Add dropdown-menu-end to the ul (aligns to the right edge) |
| Dark menu | Add data-bs-theme="dark" to the dropdown-menu |
| Split button | btn-group: a normal button plus a dropdown-toggle-split button |
| Headers and text | dropdown-header for a label, dropdown-item-text for static lines |
Inside a navbar the wrapper is usually nav-item dropdown with the toggle carrying nav-link dropdown-toggle, but the menu markup stays identical. That is why the same classes also power the menus in our Bootstrap navbar guide.
Submenus and mobile behaviour
Bootstrap 5 has no built-in submenu, so a nested flyout has to be hand-built or replaced by two separate menus. A flat menu with clear labels almost always converts better anyway. On phones the menu is not a native select — it still renders as a list anchored to the button — so keep items short and to roughly seven; longer menus push past the viewport and become awkward to tap. If you truly need a picker of many options on mobile, a select in a modal is more usable than a long dropdown.
Opening a dropdown from JavaScript
const trigger = document.getElementById('menuBtn');
const menu = bootstrap.Dropdown.getOrCreateInstance(trigger);
menu.show(); // open
menu.hide(); // close
menu.toggle(); // flip
menu.update(); // recalculate position after the DOM changes
Bootstrap 5.3 added an autoClose option that controls what happens when the user clicks. The default true closes on any outside click; 'inside' closes only when a menu item is chosen; 'outside' closes only on clicks elsewhere; false never auto-closes. Pass it in the constructor: new bootstrap.Dropdown(trigger, { autoClose: 'inside', popperConfig: {} }). Use update() after you show, hide or resize content inside the menu, or the next open can appear offset.
When the dropdown does not open: check these four things
- No bundle script. The menu is toggled by JavaScript; the CSS alone only styles it.
- Wrong attribute. The toggle needs
data-bs-toggle="dropdown"—data-toggle(v4) or a missing value leaves it inert. - Menu outside the wrapper. The
dropdown-menumust be a sibling of the toggle inside thedropdowndiv; otherwise positioning collapses. - Parent with
overflow: hidden. A clipping ancestor cuts the menu off, a classic problem in custom navbars and card bodies.
Comparing frameworks? The Materialize dropdown guide shows the same menu built with explicit initialization. Buttons that host the toggle — sizes, outline styles and disabled states — are covered in our Bootstrap buttons guide.
Working on a real interface and want a reviewer for the tricky parts? Ampersand Academy teaches front-end development one-to-one, using your own project as the curriculum.
Frequently asked questions
Why is my Bootstrap dropdown not opening?
Check three things: bootstrap.bundle.min.js is loaded, the toggle button has data-bs-toggle set to dropdown, and the dropdown-menu element sits inside the same dropdown wrapper as the button. If all three are correct the menu opens on click.
How do I right-align a Bootstrap dropdown menu?
Add the dropdown-menu-end class to the menu. It anchors the menu’s right edge to the toggle’s right edge, which is what you want for a menu at the right of a toolbar or navbar.
How do I make a Bootstrap dropdown open on hover?
There is no built-in hover option; dropdowns are click-driven by design for accessibility. Many sites add a small CSS rule that shows .dropdown-menu when the parent is hovered, accepting that this breaks touch and keyboard behaviour.
What is the difference between dropup, dropend and dropstart?
They set the direction the menu opens. dropup opens above the button, dropend opens to the right (or left in RTL), and dropstart opens to the left (or right in RTL). Add the class to the dropdown wrapper.
How do I keep a Bootstrap dropdown open when clicking inside it?
Create it with the autoClose option set to inside: new bootstrap.Dropdown(trigger, { autoClose: ‘inside’ }). It then closes only when a menu item is selected, not on random clicks within the menu.

