Menu
Toggle contextual menus and custom overlays for lists of buttons, links, forms, and other custom content.
The Idea React Menu wrapper uses the same .menu, .menu-item, and .submenu class names as
Bootstrap 6, with React-controlled open state, keyboard navigation, focus restoration, and
configurable auto-close behavior. These examples adapt the upstream Menu documentation.
Overview
Toggle menus with buttons whenever possible. Here's an example using a Bootstrap button:
Menus are toggleable, contextual overlays for displaying lists of links and more. They're toggled by clicking, not by hovering; this is an intentional design decision.
Bootstrap's JavaScript plugin uses Floating UI for dynamic positioning and viewport detection. The React wrapper instead positions its panel with Bootstrap's CSS placement utilities and closes on outside pointer interaction.
Examples
While <button> is the recommended control for a menu toggle, there might be situations where you
have to use an <a> element. If you do, we recommend adding a role="button" attribute to
appropriately convey control's purpose to assistive technologies such as screen readers.
Use button groups to create split button menus where the menu is displayed when a secondary button is clicked.
Dark menus
Opt into darker menus to match a dark navbar or custom style by adding data-bs-theme="dark" onto
the toggle element or a parent. The Navbar wrapper exposes this through its theme prop, and any
wrapper element can use the attribute directly.
And putting it to use in a navbar:
Translucent menus
Blur and saturate the background of menus to create a translucent effect with .menu-translucent.
Pass it through menuClassName.
Placement
Bootstrap's menu plugin supports physical placements (top, bottom, left, right) and logical
placements (start, end) with -start and -end alignment modifiers. The React wrapper exposes
the logical axis through the align prop: start aligns the panel to the start edge and end (the
default) aligns it to the end edge.
Flip direction and responsive breakpoint placement are handled by the JavaScript plugin through
Floating UI; use the align prop for the two logical alignments in React.
Menu items
You can use <a> or <button> elements as menu items. The MenuItem wrapper renders a button
by default and an anchor when href is set.
We use utility classes to display menus in our docs examples, but they're not required for your own use.
You can also create non-interactive menu items with .menu-text. Feel free to style further with
custom CSS or text utilities.
Active
Add .active to items in the menu to style them as the active selection. To convey the active state
to assistive technologies, use the aria-current attribute—using the page value for the current
page, or true for the current item in a set.
Disabled
Add .disabled to items in the menu to style them as disabled. The disabled prop on MenuItem
also removes anchors from the tab order and marks them with aria-disabled.
Variants
You can use the theme prop to apply a theme color to a menu item; it renders the theme- prefix
classes used by Bootstrap.
Icons
Add .menu-item-icon to an icon element to add an icon slot to menu items. Icons are rendered
through the Icon component.
Descriptions
Use .menu-item-content for a flex column layout and .menu-item-description for secondary text
below the main label.
Selected
Add .selected to a .menu-item to indicate the current selection. Pair it with a
.menu-item-check icon; Bootstrap only reveals the check on selected items.
Menu content
Headers
Add a header to label sections of actions in any menu.
Dividers
Separate groups of related menu items with a divider.
Text
Place any freeform text within a menu with text and use margin and padding utilities. Note that you'll likely need additional sizing styles to constrain the menu width.
Forms
Put a form within a menu, or make it into a menu, and use margin and padding utilities to give it the negative space you require.
Scrollable menus
Assign --bs-menu-max-height and --bs-menu-overflow-y custom properties to constrain the menu
height and enable scrolling.
You can also use the .menu-scrollable class to make the menu scrollable. This assumes a generally
safe maximum height of 80dvh and sets the overflow for you.
Submenus
Create nested menus with the .submenu wrapper class. Submenus support hover and click activation,
keyboard navigation, and viewport-aware positioning. On small screens (below 576px), submenus
stack over the parent menu with a back button instead of flying out to the side.
Wrap a .menu-item trigger and a nested .menu inside a .submenu element. The
MenuSubmenu wrapper renders both, keeps aria-haspopup and aria-expanded in sync, and
places the nested panel to the side.
Nested
Submenus can be nested to multiple levels. Each level opens to the side and flips direction when there's not enough viewport space.
Menu options
The Bootstrap plugin accepts offset, reference, and boundary options for positioning. The React
wrapper keeps menus inside their relative trigger wrapper, so use align for logical alignment and
CSS properties on menuClassName for sizing.
Auto close behavior
By default, the menu is closed when clicking inside or outside the menu. You can use the autoClose
prop to change this behavior of the menu.
Regardless of the autoClose setting, pressing Esc while focus is within the menu (its
toggle or items) closes the menu and returns focus to the toggle.
Accessibility
The WAI-ARIA standard defines an actual role="menu" widget, but this is specific to
application-like menus which trigger actions or functions. ARIA menus can only contain menu items,
checkbox menu items, radio button menu items, radio button groups, and sub-menus.
Bootstrap's menus, on the other hand, are designed to be generic and applicable to a variety of
situations and markup structures. For instance, it is possible to create menus that contain
additional inputs and form controls, such as search fields or login forms. For this reason, Bootstrap
does not expect (nor automatically add) any of the role and aria- attributes required for true
ARIA menus. Authors will have to include these more specific attributes themselves.
Submenu triggers are an exception. MenuSubmenu adds aria-haspopup="true" to its trigger and keeps
aria-expanded in sync as the submenu opens and closes. Set aria-expanded yourself only if a
submenu must start open.
Keyboard navigation
Menus include built-in keyboard support for navigating menu items.
| Key | Action |
|---|---|
↓ / ↑ | Navigate to next/previous menu item |
→ | Enter submenu (or ← in RTL) |
← | Exit submenu and return to parent (or →) |
Enter / Space | Activate focused item or open submenu |
Esc | Close the menu |
Home / End | Jump to first/last menu item |
Tab | Move focus and close the menu |
CSS
Menus use CSS variables for real-time customization. Menu items include at least one variable that is
not set on .menu. This allows you to provide a new value while Bootstrap defaults to a fallback
value: --bs-menu-item-border-radius.
See the upstream menu CSS for the complete variable, Sass map, and selector reference.
React behavior
Bootstrap toggles menus through the data-bs-toggle="menu" plugin. The React wrapper manages open
state itself and exposes the same behaviors as props:
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | — | Content of the toggle button. |
autoClose | boolean | 'inside' | 'outside' | true | Close on inside and outside clicks, only inside, only outside, or only manually. |
align | 'start' | 'end' | 'end' | Align the panel to the start or end edge of the trigger. |
menuClassName | string | — | Additional classes for the menu panel, such as menu-scrollable or menu-translucent. |
toggleProps | ButtonProps | — | Variant, theme, icon, and other button props for the toggle. |
onOpenChange | (open: boolean) => void | — | Called whenever the menu opens or closes. |
There is no plugin instance to dispose or retrieve: mount the Menu component and let React manage
its lifecycle. Use onOpenChange instead of the show.bs.menu and hide.bs.menu events.