Navigation/Navigation Menu

Navigation Menu

A collection of links for navigating websites.

Themed

When to Use

Use Navigation Menu when you need to:

  • Provide top-level site navigation with categorised dropdown panels
  • Show rich content in dropdowns such as featured pages, icons, or descriptions
  • Offer a horizontal menu bar that collapses to a single viewport on desktop
  • Mix dropdown triggers with direct navigation links in the same bar
  • Build accessible mega-menus that support keyboard and screen reader users

When Not to Use

  • Application-style menu bar with submenus — use Menubar
  • Switching between content panels in the same view — use Tabs
  • Showing the user’s current location in a hierarchy — use Breadcrumb
  • Right-click or action menus — use Context Menu or Dropdown Menu

Default

Full navigation menu with a featured content panel and grid layouts inside dropdowns.

Simple

A compact menu combining a single dropdown with direct navigation links.

With Icons

Menu items decorated with leading icons for quick visual scanning.

{/* Use navigationMenuTriggerStyle() for links that look like triggers */}
<NavigationMenuItem>
  <NavigationMenuLink
    className={navigationMenuTriggerStyle()}
    href="/docs"
  >
    Documentation
  </NavigationMenuLink>
</NavigationMenuItem>

UX & Design Guidelines

Visual Hierarchy

Limit top-level triggers to 5–7 items. Use bg-accent and text-accent-foreground for hover/active states to maintain visual consistency. For featured content inside a dropdown, a gradient from bg-muted/50 to bg-muted creates a tasteful highlight card.

Spacing & Layout

Dropdown panels use p-4 padding by default. Grid layouts (grid-cols-2 or grid-cols-[.75fr_1fr]) work well for content-rich menus. Keep gap-1 between NavigationMenuList items for consistent trigger spacing.

Responsive Behaviour

The viewport width is driven by --radix-navigation-menu-viewport-width so it adapts to content automatically. On narrow screens, consider collapsing the navigation into a Sheet or Drawer triggered by a hamburger icon, rather than shrinking the menu bar.

Color & Contrast

Trigger text uses text-foreground on bg-background, flipping to text-accent-foreground on bg-accent for hover and open states. The dropdown panel sits on bg-popover with text-popover-foreground, ensuring AA-compliant contrast in both light and dark modes.

Accessibility

Keyboard Navigation

  • Tab — Move focus into and out of the navigation menu
  • Enter or Space — Open/close a trigger’s dropdown, or activate a link
  • — Move focus between top-level triggers
  • — Move focus into the open dropdown content
  • Esc — Close the currently open dropdown and return focus to its trigger

Screen Reader Support

  • The root element renders a nav landmark — add aria-label when the page contains multiple nav regions
  • Triggers announce expanded/collapsed state via aria-expanded automatically
  • Use aria-current="page" on the link that represents the current page
  • Active links receive data-active="true" for styling and assistive technology hooks

Focus Management

Focus is trapped within the open dropdown. Closing the dropdown returns focus to the trigger. A visible focus ring (focus-visible:ring-[3px]) is shown on both triggers and links, using ring-ring/50 to meet WCAG 2.1 AA focus indicator requirements.

Touch Targets

Triggers render at h-9 (36 px) with px-4 horizontal padding, meeting minimum 44 px tap-target recommendations when combined with gap-1 between items. Dropdown links include p-2 padding for comfortable touch interaction.

ARIA Attributes

{/* Root menu with accessible label */}
<NavigationMenu aria-label="Main navigation">
  <NavigationMenuList>
    <NavigationMenuItem>
      {/* Trigger auto-manages aria-expanded and aria-controls */}
      <NavigationMenuTrigger>Products</NavigationMenuTrigger>
      <NavigationMenuContent>
        {/* Links announce their text to screen readers */}
        <NavigationMenuLink href="/analytics">
          Analytics
        </NavigationMenuLink>
      </NavigationMenuContent>
    </NavigationMenuItem>

    {/* Direct link — no aria-expanded needed */}
    <NavigationMenuItem>
      <NavigationMenuLink
        className={navigationMenuTriggerStyle()}
        href="/pricing"
        aria-current="page" {/* mark current page */}
      >
        Pricing
      </NavigationMenuLink>
    </NavigationMenuItem>
  </NavigationMenuList>
</NavigationMenu>

API Reference

The Navigation Menu is a compound component. Each sub-component accepts the props listed below in addition to standard HTML attributes.

NavigationMenu

PropTypeDefaultDescription
valuestringControlled value of the currently active menu item.
onValueChange(value: string) => voidCallback invoked when the active menu item changes.
defaultValuestringThe value of the active item on initial render (uncontrolled).
orientation"horizontal" | "vertical""horizontal"The layout direction of the menu items.
viewportbooleantrueWhen true, renders a shared viewport container for dropdown content. Set to false for inline content.
classNamestringAdditional CSS classes applied to the root element.

NavigationMenuTrigger

PropTypeDefaultDescription
childrenrequiredReact.ReactNodeThe trigger label. A chevron icon is appended automatically.
classNamestringAdditional CSS classes applied to the trigger button.

NavigationMenuContent

PropTypeDefaultDescription
forceMountbooleanForce the content to stay mounted in the DOM. Useful when controlling entry/exit animations externally.
classNamestringAdditional CSS classes applied to the content container.

NavigationMenuLink

PropTypeDefaultDescription
activebooleanfalseMarks the link as the currently active page (adds data-active attribute).
asChildbooleanfalseWhen true, renders the child element directly, merging props. Use with Next.js Link or custom anchor tags.
classNamestringAdditional CSS classes applied to the link element.