Skip to content
Docs

Menubar

A visually persistent menu common in desktop applications that provides quick access to a consistent set of commands.

A visually persistent menu common in desktop applications that provides quick access to a consistent set of commands.

<Menubar.root
  id="menubar-primitive"
  class="DemoMenubarRoot"
>
  <Menubar.menu value="file">
    <Menubar.trigger
      id="file-trigger"
      content_id="file-content"
      class="DemoMenubarTrigger"
    >
      File
    </Menubar.trigger>
    <Menubar.content
      id="file-content"
      class="DemoMenubarContent"
      align="start"
      side_offset={5}
    >
      <Menubar.item class="DemoMenubarItem">
        New Tab
        <div class="DemoRightSlot">⌘ T</div>
      </Menubar.item>
      <Menubar.item class="DemoMenubarItem">
        New Window
        <div class="DemoRightSlot">⌘ N</div>
      </Menubar.item>
      <Menubar.item
        class="DemoMenubarItem"
        disabled
      >
        New Incognito Window
      </Menubar.item>
      <Menubar.separator class="DemoMenubarSeparator" />
      <Menubar.sub>
        <Menubar.sub_trigger class="DemoMenubarSubTrigger">
          Share
          <div class="DemoRightSlot">
            <svg
              width="15"
              height="15"
              viewBox="0 0 15 15"
              fill="none"
              xmlns="http://www.w3.org/2000/svg"
              aria-hidden="true"
            >
              <path
                d="M6.1584 3.13508C6.35985 2.94621 6.67627 2.95642 6.86514 3.15788L10.61514 7.15788C10.7954 7.3502 10.7954 7.64949 10.61514 7.84182L6.86514 11.8418C6.67627 12.0433 6.35985 12.0535 6.1584 11.8646C5.95694 11.6757 5.94673 11.3593 6.1356 11.1579L9.565 7.49985L6.1356 3.84182C5.94673 3.64036 5.95694 3.32394 6.1584 3.13508Z"
                fill="currentColor"
                fill-rule="evenodd"
                clip-rule="evenodd"
              >
              </path>
            </svg>
          </div>
        </Menubar.sub_trigger>
        <Menubar.sub_content class="DemoMenubarSubContent">
          <Menubar.item class="DemoMenubarItem">Email Link</Menubar.item>
          <Menubar.item class="DemoMenubarItem">Messages</Menubar.item>
          <Menubar.item class="DemoMenubarItem">Notes</Menubar.item>
        </Menubar.sub_content>
      </Menubar.sub>
      <Menubar.separator class="DemoMenubarSeparator" />
      <Menubar.item class="DemoMenubarItem">
        Print…
        <div class="DemoRightSlot">⌘ P</div>
      </Menubar.item>
    </Menubar.content>
  </Menubar.menu>

  <Menubar.menu value="edit">
    <Menubar.trigger
      id="edit-trigger"
      content_id="edit-content"
      class="DemoMenubarTrigger"
    >
      Edit
    </Menubar.trigger>
    <Menubar.content
      id="edit-content"
      class="DemoMenubarContent"
      align="start"
      side_offset={5}
    >
      <Menubar.item class="DemoMenubarItem">
        Undo
        <div class="DemoRightSlot">⌘ Z</div>
      </Menubar.item>
      <Menubar.item class="DemoMenubarItem">
        Redo
        <div class="DemoRightSlot">⇧ ⌘ Z</div>
      </Menubar.item>
      <Menubar.separator class="DemoMenubarSeparator" />
      <Menubar.sub>
        <Menubar.sub_trigger class="DemoMenubarSubTrigger">
          Find
          <div class="DemoRightSlot">
            <svg
              width="15"
              height="15"
              viewBox="0 0 15 15"
              fill="none"
              xmlns="http://www.w3.org/2000/svg"
              aria-hidden="true"
            >
              <path
                d="M6.1584 3.13508C6.35985 2.94621 6.67627 2.95642 6.86514 3.15788L10.61514 7.15788C10.7954 7.3502 10.7954 7.64949 10.61514 7.84182L6.86514 11.8418C6.67627 12.0433 6.35985 12.0535 6.1584 11.8646C5.95694 11.6757 5.94673 11.3593 6.1356 11.1579L9.565 7.49985L6.1356 3.84182C5.94673 3.64036 5.95694 3.32394 6.1584 3.13508Z"
                fill="currentColor"
                fill-rule="evenodd"
                clip-rule="evenodd"
              >
              </path>
            </svg>
          </div>
        </Menubar.sub_trigger>
        <Menubar.sub_content class="DemoMenubarSubContent">
          <Menubar.item class="DemoMenubarItem">Search the web…</Menubar.item>
          <Menubar.separator class="DemoMenubarSeparator" />
          <Menubar.item class="DemoMenubarItem">Find…</Menubar.item>
          <Menubar.item class="DemoMenubarItem">Find Next</Menubar.item>
          <Menubar.item class="DemoMenubarItem">Find Previous</Menubar.item>
        </Menubar.sub_content>
      </Menubar.sub>
      <Menubar.separator class="DemoMenubarSeparator" />
      <Menubar.item class="DemoMenubarItem">Cut</Menubar.item>
      <Menubar.item class="DemoMenubarItem">Copy</Menubar.item>
      <Menubar.item class="DemoMenubarItem">Paste</Menubar.item>
    </Menubar.content>
  </Menubar.menu>

  <Menubar.menu value="view">
    <Menubar.trigger
      id="view-trigger"
      content_id="view-content"
      class="DemoMenubarTrigger"
    >
      View
    </Menubar.trigger>
    <Menubar.content
      id="view-content"
      class="DemoMenubarContent"
      align="start"
      side_offset={5}
    >
      <Menubar.checkbox_item
        class="DemoMenubarCheckboxItem inset"
        text_value="Always Show Bookmarks Bar"
      >
        <Menubar.item_indicator class="DemoMenubarItemIndicator">
          <svg
            width="15"
            height="15"
            viewBox="0 0 15 15"
            fill="none"
            xmlns="http://www.w3.org/2000/svg"
            aria-hidden="true"
          >
            <path
              d="M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z"
              fill="currentColor"
              fill-rule="evenodd"
              clip-rule="evenodd"
            >
            </path>
          </svg>
        </Menubar.item_indicator>
        Always Show Bookmarks Bar
      </Menubar.checkbox_item>
      <Menubar.checkbox_item
        class="DemoMenubarCheckboxItem inset"
        checked
        text_value="Always Show Full URLs"
      >
        <Menubar.item_indicator
          class="DemoMenubarItemIndicator"
          force_mount
        >
          <svg
            width="15"
            height="15"
            viewBox="0 0 15 15"
            fill="none"
            xmlns="http://www.w3.org/2000/svg"
            aria-hidden="true"
          >
            <path
              d="M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z"
              fill="currentColor"
              fill-rule="evenodd"
              clip-rule="evenodd"
            >
            </path>
          </svg>
        </Menubar.item_indicator>
        Always Show Full URLs
      </Menubar.checkbox_item>
      <Menubar.separator class="DemoMenubarSeparator" />
      <Menubar.item class="DemoMenubarItem inset">
        Reload
        <div class="DemoRightSlot">⌘ R</div>
      </Menubar.item>
      <Menubar.item
        class="DemoMenubarItem inset"
        disabled
      >
        Force Reload
        <div class="DemoRightSlot">⇧ ⌘ R</div>
      </Menubar.item>
      <Menubar.separator class="DemoMenubarSeparator" />
      <Menubar.item class="DemoMenubarItem inset">Toggle Fullscreen</Menubar.item>
      <Menubar.separator class="DemoMenubarSeparator" />
      <Menubar.item class="DemoMenubarItem inset">Hide Sidebar</Menubar.item>
    </Menubar.content>
  </Menubar.menu>

  <Menubar.menu value="profiles">
    <Menubar.trigger
      id="profiles-trigger"
      content_id="profiles-content"
      class="DemoMenubarTrigger"
    >
      Profiles
    </Menubar.trigger>
    <Menubar.content
      id="profiles-content"
      class="DemoMenubarContent"
      align="start"
      side_offset={5}
    >
      <Menubar.radio_group value="Luis">
        <Menubar.radio_item
          class="DemoMenubarRadioItem inset"
          value="Andy"
        >
          <Menubar.item_indicator class="DemoMenubarItemIndicator">
            <svg
              width="15"
              height="15"
              viewBox="0 0 15 15"
              fill="none"
              xmlns="http://www.w3.org/2000/svg"
              aria-hidden="true"
            >
              <path
                d="M9.875 7.5C9.875 8.81168 8.81168 9.875 7.5 9.875C6.18832 9.875 5.125 8.81168 5.125 7.5C5.125 6.18832 6.18832 5.125 7.5 5.125C8.81168 5.125 9.875 6.18832 9.875 7.5Z"
                fill="currentColor"
              >
              </path>
            </svg>
          </Menubar.item_indicator>
          Andy
        </Menubar.radio_item>
        <Menubar.radio_item
          class="DemoMenubarRadioItem inset"
          value="Benoît"
        >
          <Menubar.item_indicator class="DemoMenubarItemIndicator">
            <svg
              width="15"
              height="15"
              viewBox="0 0 15 15"
              fill="none"
              xmlns="http://www.w3.org/2000/svg"
              aria-hidden="true"
            >
              <path
                d="M9.875 7.5C9.875 8.81168 8.81168 9.875 7.5 9.875C6.18832 9.875 5.125 8.81168 5.125 7.5C5.125 6.18832 6.18832 5.125 7.5 5.125C8.81168 5.125 9.875 6.18832 9.875 7.5Z"
                fill="currentColor"
              >
              </path>
            </svg>
          </Menubar.item_indicator>
          Benoît
        </Menubar.radio_item>
        <Menubar.radio_item
          class="DemoMenubarRadioItem inset"
          value="Luis"
          checked
        >
          <Menubar.item_indicator
            class="DemoMenubarItemIndicator"
            force_mount
          >
            <svg
              width="15"
              height="15"
              viewBox="0 0 15 15"
              fill="none"
              xmlns="http://www.w3.org/2000/svg"
              aria-hidden="true"
            >
              <path
                d="M9.875 7.5C9.875 8.81168 8.81168 9.875 7.5 9.875C6.18832 9.875 5.125 8.81168 5.125 7.5C5.125 6.18832 6.18832 5.125 7.5 5.125C8.81168 5.125 9.875 6.18832 9.875 7.5Z"
                fill="currentColor"
              >
              </path>
            </svg>
          </Menubar.item_indicator>
          Luis
        </Menubar.radio_item>
        <Menubar.separator class="DemoMenubarSeparator" />
        <Menubar.item class="DemoMenubarItem inset">Edit…</Menubar.item>
        <Menubar.separator class="DemoMenubarSeparator" />
        <Menubar.item class="DemoMenubarItem inset">Add Profile…</Menubar.item>
      </Menubar.radio_group>
    </Menubar.content>
  </Menubar.menu>
</Menubar.root>
Can be controlled or uncontrolled.
Supports submenus with configurable reading direction.
Supports items, labels, groups of items.
Supports checkable items (single or multiple).
Customize side, alignment, offsets, collision handling.
Optionally render a pointing arrow.
Focus is fully managed.
Full keyboard navigation.
Typeahead support.

Anatomy

Import all parts and piece them together.

<Menubar.root id="…">
  <Menubar.menu value="…">
    <Menubar.trigger content_id="…" />
    <Menubar.portal>
      <Menubar.content id="…">
        <Menubar.label />
        <Menubar.item />
        <Menubar.group>
          <Menubar.item />
        </Menubar.group>
        <Menubar.checkbox_item>
          <Menubar.item_indicator />
        </Menubar.checkbox_item>
        <Menubar.radio_group>
          <Menubar.radio_item>
            <Menubar.item_indicator />
          </Menubar.radio_item>
        </Menubar.radio_group>
        <Menubar.sub>
          <Menubar.sub_trigger />
          <Menubar.sub_content />
        </Menubar.sub>
        <Menubar.separator />
      </Menubar.content>
    </Menubar.portal>
  </Menubar.menu>
</Menubar.root>

Anatomy

Root
Contains all the parts of a menubar.
Menu
A top-level menu item containing a trigger and content.
Trigger
The button that toggles the menu content.
Portal
Portals the content into the document (default `body`).
Content
The component that pops out when a menu is open.
Item
An actionable menu item.
Checkbox Item
An item that can be checked or unchecked.
Radio Group
Groups mutually exclusive `radio_item` parts.
Radio Item
An item that can be selected among a radio group.
Item Indicator
Renders when a checkbox or radio item is checked.
Label
A non-focusable section label.
Separator
Visually separates groups of items.
Group
Groups multiple items.
Sub
Contains all the parts of a submenu.
Sub Trigger
An item that opens a submenu.
Sub Content
The submenu panel.

API Reference

Root

Contains all the parts of a menubar.

Prop Type Default Description
dir string "ltr"
id string
loop boolean true
orientation string "horizontal"
dir
Type string Default "ltr"
id
Type string Default
loop
Type boolean Default true
orientation
Type string Default "horizontal"

A top level menu item, contains a trigger with content combination.

Prop Type Default Description
id string nil
value string nil
id
Type string Default nil
value
Type string Default nil

Trigger

The button that toggles the content. By default, Menubar.content positions itself against the trigger.

Prop Type Default Description
content_id string nil
disabled boolean false
id string nil
content_id
Type string Default nil
disabled
Type boolean Default false
id
Type string Default nil

Data attributes

Attribute Values Description
[data-state] open | closed Reflects whether the menu is open.
[data-highlighted] Present when highlighted Present when the trigger is highlighted.
[data-disabled] Present when disabled Present when the trigger is disabled.

Portal

When used, portals the content part into the target (default body).

Prop Type Default Description
class any nil
container string "div"
id string
target string "body"
class
Type any Default nil
container
Type string Default "div"
id
Type string Default
target
Type string Default "body"

Content

The component that pops out when a menu is open.

Prop Type Default Description
align string "start"
id string nil
loop boolean true
side string "bottom"
side_offset integer 4
align
Type string Default "start"
id
Type string Default nil
loop
Type boolean Default true
side
Type string Default "bottom"
side_offset
Type integer Default 4

Data attributes

Attribute Values Description
[data-state] open | closed Reflects whether the menu is open.
[data-side] left | right | bottom | top The side the content rendered against.
[data-align] start | end | center The alignment against the trigger.

| CSS variable | Description | | --- | --- | | --radix-menubar-content-transform-origin | The transform-origin computed from content and arrow positions/offsets | | --radix-menubar-content-available-width | Remaining width between the trigger and the boundary edge | | --radix-menubar-content-available-height | Remaining height between the trigger and the boundary edge | | --radix-menubar-trigger-width | The width of the trigger | | --radix-menubar-trigger-height | The height of the trigger |

Item

The component that contains the menubar items.

Prop Type Default Description
disabled boolean false
id string nil
text_value string nil
disabled
Type boolean Default false
id
Type string Default nil
text_value
Type string Default nil

Data attributes

Attribute Values Description
[data-highlighted] Present when highlighted Present when the item is highlighted.
[data-disabled] Present when disabled Present when the item is disabled.

Checkbox Item

An item that can be controlled and rendered like a checkbox.

Prop Type Default Description
checked boolean false
disabled boolean false
id string nil
text_value string nil
checked
Type boolean Default false
disabled
Type boolean Default false
id
Type string Default nil
text_value
Type string Default nil

Data attributes

Attribute Values Description
[data-state] checked | unchecked Reflects the checked state.
[data-highlighted] Present when highlighted Present when the item is highlighted.
[data-disabled] Present when disabled Present when the item is disabled.

Radio Group

Used to group multiple Menubar.radio_item parts.

Prop Type Default Description
id string nil
value string nil
id
Type string Default nil
value
Type string Default nil

Radio Item

An item that can be controlled and rendered like a radio.

Prop Type Default Description
checked boolean false
disabled boolean false
id string nil
text_value string nil
value string
checked
Type boolean Default false
disabled
Type boolean Default false
id
Type string Default nil
text_value
Type string Default nil
value
Type string Default

Data attributes

Attribute Values Description
[data-state] checked | unchecked Reflects the selected state.
[data-highlighted] Present when highlighted Present when the item is highlighted.
[data-disabled] Present when disabled Present when the item is disabled.

Item Indicator

Renders when the parent checkbox_item or radio_item is checked.

Prop Type Default Description
force_mount boolean false
id string nil
force_mount
Type boolean Default false
id
Type string Default nil

Data attributes

Attribute Values Description
[data-state] checked | unchecked Reflects the checked state of the parent item.

Label

Used to render a label. It won't be focusable using arrow keys.

Prop Type Default Description
id string nil
id
Type string Default nil

Separator

Used to visually separate items in a menubar menu.

Prop Type Default Description
decorative boolean true
id string nil
decorative
Type boolean Default true
id
Type string Default nil

Group

Used to group multiple Menubar.item parts.

Prop Type Default Description
id string nil
id
Type string Default nil

Sub

Contains all the parts of a submenu.

Prop Type Default Description
id string nil
open boolean false
id
Type string Default nil
open
Type boolean Default false

Sub Trigger

An item that opens a submenu. Must be rendered inside Menubar.sub.

Prop Type Default Description
disabled boolean false
id string nil
text_value string nil
disabled
Type boolean Default false
id
Type string Default nil
text_value
Type string Default nil

Data attributes

Attribute Values Description
[data-state] open | closed Reflects whether the submenu is open.
[data-highlighted] Present when highlighted Present when the item is highlighted.
[data-disabled] Present when disabled Present when the item is disabled.

Sub Content

The component that pops out when a submenu is open. Must be rendered inside Menubar.sub.

Prop Type Default Description
align string "start"
id string nil
side string "right"
side_offset integer 0
align
Type string Default "start"
id
Type string Default nil
side
Type string Default "right"
side_offset
Type integer Default 0

Data attributes

Attribute Values Description
[data-state] open | closed Reflects whether the submenu is open.
[data-side] left | right | bottom | top The side the submenu rendered against.
[data-align] start | end | center The alignment of the submenu.
[data-orientation] vertical | horizontal The orientation of the submenu.

Examples

With submenus

You can create submenus by using Menubar.sub in combination with its parts.

<Menubar.root id="menubar-sub">
  <Menubar.menu value="file">
    <Menubar.trigger id="menubar-sub-trigger" content_id="menubar-sub-content">…</Menubar.trigger>
    <Menubar.content id="menubar-sub-content">
      <Menubar.item class="DemoMenubarItem">…</Menubar.item>
      <Menubar.item class="DemoMenubarItem">…</Menubar.item>
      <Menubar.separator class="DemoMenubarSeparator" />
      <Menubar.sub>
        <Menubar.sub_trigger class="DemoMenubarSubTrigger">Sub menu →</Menubar.sub_trigger>
        <Menubar.sub_content class="DemoMenubarSubContent">
          <Menubar.item class="DemoMenubarItem">Sub menu item</Menubar.item>
          <Menubar.item class="DemoMenubarItem">Sub menu item</Menubar.item>
        </Menubar.sub_content>
      </Menubar.sub>
      <Menubar.separator class="DemoMenubarSeparator" />
      <Menubar.item class="DemoMenubarItem">…</Menubar.item>
    </Menubar.content>
  </Menubar.menu>
</Menubar.root>

With disabled items

You can add special styles to disabled items via the data-disabled attribute.

<Menubar.root id="menubar-disabled">
  <Menubar.menu value="file">
    <Menubar.trigger id="menubar-disabled-trigger" content_id="menubar-disabled-content">…</Menubar.trigger>
    <Menubar.content id="menubar-disabled-content">
      <Menubar.item class="DemoMenubarItem" disabled>…</Menubar.item>
      <Menubar.item class="DemoMenubarItem">…</Menubar.item>
    </Menubar.content>
  </Menubar.menu>
</Menubar.root>
.DemoMenubarItem[data-disabled] {
  color: gainsboro;
}

With separators

Use the separator part to add a separator between items.

<Menubar.root id="menubar-separators">
  <Menubar.menu value="file">
    <Menubar.trigger id="menubar-separators-trigger" content_id="menubar-separators-content">…</Menubar.trigger>
    <Menubar.content id="menubar-separators-content">
      <Menubar.item class="DemoMenubarItem">…</Menubar.item>
      <Menubar.separator class="DemoMenubarSeparator" />
      <Menubar.item class="DemoMenubarItem">…</Menubar.item>
      <Menubar.separator class="DemoMenubarSeparator" />
      <Menubar.item class="DemoMenubarItem">…</Menubar.item>
    </Menubar.content>
  </Menubar.menu>
</Menubar.root>

With labels

Use the label part to help label a section.

<Menubar.root id="menubar-labels">
  <Menubar.menu value="file">
    <Menubar.trigger id="menubar-labels-trigger" content_id="menubar-labels-content">…</Menubar.trigger>
    <Menubar.content id="menubar-labels-content">
      <Menubar.label class="DemoMenubarLabel">Label</Menubar.label>
      <Menubar.item class="DemoMenubarItem">…</Menubar.item>
      <Menubar.item class="DemoMenubarItem">…</Menubar.item>
      <Menubar.item class="DemoMenubarItem">…</Menubar.item>
    </Menubar.content>
  </Menubar.menu>
</Menubar.root>

With checkbox items

Use the checkbox_item part to add an item that can be checked. Pass checked from LiveView assigns to control state.

<Menubar.root id="menubar-checkbox">
  <Menubar.menu value="view">
    <Menubar.trigger id="menubar-checkbox-trigger" content_id="menubar-checkbox-content">…</Menubar.trigger>
    <Menubar.content id="menubar-checkbox-content">
      <Menubar.item class="DemoMenubarItem">…</Menubar.item>
      <Menubar.item class="DemoMenubarItem">…</Menubar.item>
      <Menubar.separator class="DemoMenubarSeparator" />
      <Menubar.checkbox_item checked={@checked} class="DemoMenubarCheckboxItem" text_value="Checkbox item">
        <Menubar.item_indicator class="DemoMenubarItemIndicator">✓</Menubar.item_indicator>
        Checkbox item
      </Menubar.checkbox_item>
    </Menubar.content>
  </Menubar.menu>
</Menubar.root>

With radio items

Use the radio_group and radio_item parts to add an item that can be checked amongst others.

<Menubar.root id="menubar-radio">
  <Menubar.menu value="profiles">
    <Menubar.trigger id="menubar-radio-trigger" content_id="menubar-radio-content">…</Menubar.trigger>
    <Menubar.content id="menubar-radio-content">
      <Menubar.radio_group value={@color}>
        <Menubar.radio_item value="red" checked={@color == "red"} class="DemoMenubarRadioItem">
          <Menubar.item_indicator class="DemoMenubarItemIndicator">●</Menubar.item_indicator>
          Red
        </Menubar.radio_item>
        <Menubar.radio_item value="blue" checked={@color == "blue"} class="DemoMenubarRadioItem">
          <Menubar.item_indicator class="DemoMenubarItemIndicator">●</Menubar.item_indicator>
          Blue
        </Menubar.radio_item>
      </Menubar.radio_group>
    </Menubar.content>
  </Menubar.menu>
</Menubar.root>

With complex items

You can add extra decorative elements in the item parts, such as images.

<Menubar.root id="menubar-complex">
  <Menubar.menu value="people">
    <Menubar.trigger id="menubar-complex-trigger" content_id="menubar-complex-content">…</Menubar.trigger>
    <Menubar.content id="menubar-complex-content">
      <Menubar.item class="DemoMenubarItem">
        <img src="…" alt="" />
        Adolfo Hess
      </Menubar.item>
      <Menubar.item class="DemoMenubarItem">
        <img src="…" alt="" />
        Miyah Myles
      </Menubar.item>
    </Menubar.content>
  </Menubar.menu>
</Menubar.root>

Constrain the content/sub-content size

You may want to constrain the width of the content (or sub-content) so that it matches the trigger width, or constrain its height to not exceed the viewport.

We expose several CSS custom properties such as --radix-menubar-trigger-width and --radix-menubar-content-available-height to support this. Use them to constrain the content dimensions.

<Menubar.root id="menubar-constrain">
  <Menubar.menu value="file">
    <Menubar.trigger id="menubar-constrain-trigger" content_id="menubar-constrain-content">…</Menubar.trigger>
    <Menubar.content id="menubar-constrain-content" class="DemoMenubarContent" side_offset={5}>
      …
    </Menubar.content>
  </Menubar.menu>
</Menubar.root>
.DemoMenubarContent {
  width: var(--radix-menubar-trigger-width);
  max-height: var(--radix-menubar-content-available-height);
}

Origin-aware animations

We expose a CSS custom property --radix-menubar-content-transform-origin. Use it to animate the content from its computed origin based on side, side_offset, align, and any collisions.

<Menubar.root id="menubar-origin">
  <Menubar.menu value="file">
    <Menubar.trigger id="menubar-origin-trigger" content_id="menubar-origin-content">…</Menubar.trigger>
    <Menubar.content id="menubar-origin-content" class="DemoMenubarContent">…</Menubar.content>
  </Menubar.menu>
</Menubar.root>
.DemoMenubarContent {
  transform-origin: var(--radix-menubar-content-transform-origin);
  animation: scaleIn 0.5s ease-out;
}

@keyframes scaleIn {
  from {
    opacity: 0;
    transform: scale(0);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

Collision-aware animations

We expose data-side and data-align attributes. Their values change at runtime to reflect collisions. Use them to create collision and direction-aware animations.

<Menubar.root id="menubar-collision">
  <Menubar.menu value="file">
    <Menubar.trigger id="menubar-collision-trigger" content_id="menubar-collision-content">…</Menubar.trigger>
    <Menubar.content id="menubar-collision-content" class="DemoMenubarContent">…</Menubar.content>
  </Menubar.menu>
</Menubar.root>
.DemoMenubarContent {
  animation-duration: 0.6s;
  animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}
.DemoMenubarContent[data-side="top"] {
  animation-name: slideUp;
}
.DemoMenubarContent[data-side="bottom"] {
  animation-name: slideDown;
}

@keyframes slideUp {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

Accessibility

Adheres to the Menu Button WAI-ARIA design pattern and uses roving tabindex to manage focus movement among menu items.

Keyboard Interactions

Keyboard Interactions

Key Description
Space When focus is on `Menubar.trigger`, opens the menubar and focuses the first item. When focus is on an item, activates the focused item.
Enter When focus is on `Menubar.trigger`, opens the associated menu. When focus is on an item, activates the focused item.
ArrowDown When focus is on `Menubar.trigger`, opens the associated menu. When focus is on an item, moves focus to the next item.
ArrowUp When focus is on an item, moves focus to the previous item.
ArrowRight, ArrowLeft When focus is on a `Menubar.trigger`, moves focus to the next or previous item. When focus is on a `Menubar.sub_trigger`, opens or closes the submenu depending on reading direction. When focus is within a `Menubar.content`, opens the next menu in the menubar.
Esc Closes the currently open menu and moves focus to its `Menubar.trigger`.