Skip to main content

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.

KeyAction
↓ / ↑Navigate to next/previous menu item
→Enter submenu (or ← in RTL)
←Exit submenu and return to parent (or →)
Enter / SpaceActivate focused item or open submenu
EscClose the menu
Home / EndJump to first/last menu item
TabMove 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:

PropTypeDefaultDescription
labelReactNode—Content of the toggle button.
autoCloseboolean | 'inside' | 'outside'trueClose 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.
menuClassNamestring—Additional classes for the menu panel, such as menu-scrollable or menu-translucent.
togglePropsButtonProps—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.