Skip to content

Sidebar Menu

Sidebar Menu renders local section navigation with native links and separate caret buttons for expanding or collapsing child branches.

Component

Use fd-sidebar-menu when a content-heavy page needs the same local navigation treatment as Sidebar Nav, but users also need to open and close child branches in place.

When to use

  • Expandable section navigation — use Sidebar Menu beside long-form news, policy, guidance, or resource pages when sibling branches should be available on demand.
  • Tree-like local context — use it when a section has meaningful child pages, but showing every branch all the time would make the sidebar too long.
  • CMS-backed navigation trees — use it when a route, content model, or navigation service can pass a structured tree.

When not to use

  • Do not use it for global navigation — use Global Header for primary site navigation.
  • Do not use it for in-page headings — use the Prose table-of-contents pattern for links within one page.
  • Do not use it as an application command menu — Sidebar Menu is still page navigation, not a toolbar, menu bar, or command list.
  • Do not use it to hide weak IA — if the tree is too deep or hard to name clearly, fix the information architecture first.

Choose Nav or Menu

Use Sidebar Menu when people need to explore sibling branches without leaving the page. It keeps links native and adds separate caret buttons for expanding and collapsing child branches.

Use Sidebar Nav when the current page should determine which branch is visible. Sidebar Nav renders a predictable route-driven view of the section and omits unrelated descendants from the DOM instead of giving users disclosure controls.

Examples

Sidebar Menu renders a web-area root, native links, and separate caret buttons for expandable branches. View in Storybook →

Basic usage

html
<fd-sidebar-menu
  label="News section"
  current-href="/news-events/news/press-releases"
></fd-sidebar-menu>

<script type="module">
  const menu = document.querySelector("fd-sidebar-menu");

  menu.root = {
    label: "News & Events",
    href: "/news-events",
  };

  menu.items = [
    { id: "overview", label: "Overview", href: "/news-events" },
    {
      id: "news",
      label: "News",
      href: "/news-events/news",
      items: [
        {
          id: "global-messages",
          label: "Global Messages",
          href: "/news-events/news/global-messages",
        },
        {
          id: "press-releases",
          label: "Press Releases",
          href: "/news-events/news/press-releases",
        },
      ],
    },
  ];
</script>

Expansion behavior

  • Top-level items always render.
  • Items with children render a separate caret button at the right edge.
  • Current-path branches and item-level expanded: true branches open by default.
  • Users can expand or collapse a branch with the caret button.
  • Branch content stays in the DOM while collapsed, but it is hidden from keyboard and screen reader navigation with the native hidden attribute.

Current state

  • Pass currentHref or currentId at the component level.
  • Prefer currentId when URLs can vary by environment, locale, or query string.
  • Only the matched current page link receives aria-current="page".
  • Ancestor links in the current path remain normal links. They may receive internal path styling, but they do not receive aria-current.

Properties

NameTypeDefaultDescription
labelstring``Accessible label for the internal navigation landmark when labelledby is not provided.
labelledbystring | undefinedundefinedID of an external visible heading that labels the navigation landmark.
rootFdSidebarMenuRoot | undefinedundefinedOptional level-0 web-area link rendered before the item tree.
itemsFdSidebarMenuItem[][]Structured navigation tree. Invalid items without labels or hrefs are omitted.
currentHrefstring | undefinedundefinedCurrent-page href matcher. Used when currentId is not provided.
currentIdstring | undefinedundefinedCurrent-page item id matcher. Takes precedence over currentHref.
maxDepth1 | 2 | 3 | 44Maximum rendered item depth, capped to the Sidebar Nav four-level indentation model.
ts
type FdSidebarMenuRoot = {
  label: string;
  href: string;
};

type FdSidebarMenuItem = {
  id?: string;
  label: string;
  href: string;
  items?: FdSidebarMenuItem[];
  expanded?: boolean;
};

CSS custom properties

NameDefaultDescription
--fd-sidebar-menu-widthvar(--fd-sidebar-nav-width, var(--fdic-layout-sidebar-width, 20rem))Inline size of the sidebar menu.
--fd-sidebar-menu-item-min-heightvar(--fd-sidebar-nav-item-min-height, 40px)Minimum block size for each link and toggle row.
--fd-sidebar-menu-indent-stepvar(--fd-sidebar-nav-indent-step, var(--fdic-spacing-md, 16px))Indentation step applied per item level.
--fd-sidebar-menu-toggle-sizevar(--fd-sidebar-nav-item-min-height, 40px)Inline and minimum block size for each caret button.
--fd-sidebar-menu-caret-size1emRendered size of the caret icon.
--fd-sidebar-menu-transition-duration160msDuration for branch reveal/collapse and caret rotation.
--fd-sidebar-menu-current-indicator-widthvar(--fd-sidebar-nav-current-indicator-width, 4px)Width of the current-page indicator stripe.
--fd-sidebar-menu-divider-colorvar(--fd-sidebar-nav-divider-color, var(--fdic-color-border-divider))Divider color between the root link and item tree.

Shadow parts

NameDescription
navInternal navigation landmark.
listRoot and nested unordered lists.
sublistNested unordered lists.
itemList item wrapper for each link row.
rowGrid row that holds the link and optional caret button.
linkNative anchor element for a navigation destination.
root-linkOptional level-0 web-area anchor.
toggleCaret button used to expand or collapse a child branch.
dividerDivider rendered after the root link when child items are present.

Best practices

Do

  • Keep labels short and close to the destination page titles.
  • Use the caret only for showing or hiding child links.
  • Default-open the branch that contains the current page.

Don’t

  • Use the caret button as the page link.
  • Use duplicate labels for different destinations in the same tree.
  • Show four levels unless the section really needs that depth.

Content guidelines

  • Use nouns people recognize, such as “Press Releases” or “Board Meetings.”
  • Avoid vague labels like “Learn more,” “Resources,” or “Other” unless that is the actual page title and surrounding context makes it clear.
  • Keep the root label to the web area or section name.
  • Review long sidebars for trust and comprehension. Users should not need to guess where a financial-service page belongs.

Accessibility

  • The component renders a native <nav> with either aria-label or aria-labelledby.
  • It renders real <ul>, <li>, and <a> elements for navigation destinations.
  • Carets are separate native <button type="button"> controls with aria-expanded, aria-controls, and action labels such as “Expand News.”
  • Links preserve right-click, copy-link, open-in-new-tab, browser status text, and normal keyboard behavior.
  • Toggle buttons use normal button keyboard behavior: Enter or Space toggles the branch.
  • V1 does not use role="tree", treeitem, role="menu", menuitem, roving tabindex, or arrow-key navigation.
  • Collapsed branch content uses hidden, so keyboard and screen reader users do not encounter collapsed navigation destinations.
  • Branch reveal/collapse and caret rotation are suppressed when the user requests reduced motion.
  • Focus remains visible in forced-colors mode.

Known limitations

  • Items are property-driven in v1. Slotted custom trees are deferred.
  • The component does not observe the router automatically. Applications must pass currentHref or currentId.
  • V1 does not provide mobile drawer behavior.
  • V1 supports up to four item levels to match the existing Sidebar Nav indentation model.
  • Expanded/collapsed state is internal after render. Applications can set initial branches with item-level expanded: true.
  • Sidebar Nav — use when local navigation should render deterministic branches without user-controlled expansion.
  • Global Header — use for global site navigation.
  • Pagination — use for bounded result-page navigation.
  • Content Page Recipes — page-level layouts that can host Sidebar Menu.