Skip to main content

U.S. flagU.S. flag

An official website of the United States government

CMS Design System

CMS Design System v2 is released!  See our migration guide.

Vertical navigation

Jump to guidance View related guidance in the U.S. Web Design System

Hierarchical, vertical navigation.

Code snippet
<ul class="ds-c-vertical-nav">
  <li class="ds-c-vertical-nav__item">
    <a class="ds-c-vertical-nav__label" href="javascript:void(0);">
      Parent link
    </a>
  </li>
  <li class="ds-c-vertical-nav__item">
    <button
      class="ds-c-vertical-nav__label ds-c-vertical-nav__label--current ds-c-vertical-nav__label--parent"
      title="Collapse sub-navigation"
      aria-expanded="true"
    >
      Current page
    </button>
    <ul class="ds-c-vertical-nav__subnav">
      <li class="ds-c-vertical-nav__item">
        <a class="ds-c-vertical-nav__label" href="javascript:void(0);">
          Child link
        </a>
      </li>
      <li class="ds-c-vertical-nav__item">
        <button
          class="ds-c-vertical-nav__label ds-c-vertical-nav__label--current ds-c-vertical-nav__label--parent"
          title="Collapse sub-navigation"
          aria-expanded="true"
        >
          Child link
        </button>
        <ul class="ds-c-vertical-nav__subnav">
          <li class="ds-c-vertical-nav__item">
            <a class="ds-c-vertical-nav__label" href="javascript:void(0);">
              Grandchild link
            </a>
          </li>
          <li class="ds-c-vertical-nav__item">
            <a
              class="ds-c-vertical-nav__label ds-c-vertical-nav__label--current"
              href="javascript:void(0);"
            >
              Grandchild link
            </a>
          </li>
        </ul>
      </li>
      <li class="ds-c-vertical-nav__item">
        <a class="ds-c-vertical-nav__label" href="javascript:void(0);">
          Child link
        </a>
      </li>
    </ul>
  </li>
  <li class="ds-c-vertical-nav__item">
    <a class="ds-c-vertical-nav__label" href="javascript:void(0);">
      Parent link
    </a>
  </li>
</ul>
React

<VerticalNav>

View source file

A VerticalNav component accepts list items as a JSON object and includes additional functionality like collapsible nested menus.

Code snippet
// Mock react-router example
const Link = ({ className, ...props }) => (
  // <Link to={props.href} {...props}>{props.children}</Link>
  <a className={classNames(className, 'special-link')} {...props}>
    {props.children}
  </a>
);
Link.propTypes = { children: PropTypes.node };

ReactDOM.render(
  <VerticalNav
    selectedId="team"
    items={[
      {
        label: 'Parent link',
        url: 'javascript:void(0);',
        id: 'parentlink1',
      },
      {
        label: 'Current page',
        selected: true,
        items: [
          {
            id: 'childlink1',
            label: 'Child link',
            url: 'javascript:void(0);',
          },
          {
            label: 'Child link',
            selected: true,
            component: Link,
            items: [
              {
                id: 'grandchildlink1',
                label: 'Grandchild link',
                url: 'javascript:void(0);',
              },
              {
                id: 'grandchildlink2',
                label: 'Grandchild link',
                url: 'javascript:void(0);',
                selected: true,
              },
            ],
          },
          {
            id: 'childlink3',
            label: 'Child link',
            url: 'javascript:void(0);',
          },
        ],
      },
      {
        label: 'Parent link',
        url: 'javascript:void(0);',
        id: 'parentlink2',
      },
    ]}
  />,
  document.getElementById('js-example')
);

Props

React Properties Documentation
NameTypeDefaultDescription
classNamestring

Additional classes to be added to the root element

collapsedboolfalse

Whether or not the menu is in a collapsed state

componentelement, elementType, func

When provided, this will render the passed in component for all VerticalNavItems. This is useful when integrating with React Router's <Link> or using your own custom component. If more specific control is needed, each VerticalNavItem object also accepts a component prop.

selectedIdstring

The id of the selected VerticalNavItem. This will also set the selected prop on the item's parents.

idstring
items

Required

arrayOf[custom]

An array of VerticalNavItem data objects

nestedbool

Indicates this list is nested within another nav item.

onLinkClickfunc

Called when one of the nav links is clicked, with the following arguments: SyntheticEvent, id, url

React

<VerticalNavItem>

View source file

Props

React Properties Documentation
NameTypeDefaultDescription
ariaCollapsedStateButtonLabelstring'Expand sub-navigation'

Aria label for the toggle button when the sub-navigation is collapsed

ariaExpandedStateButtonLabelstring'Collapse sub-navigation'

Aria label for the toggle button when the sub-navigation is expanded

classNamestring

Additional classes to be added to the root element

componentelement, elementType, func

When provided, this will render the passed in component. This is useful when integrating with React Router's <Link> or using your own custom component.

defaultCollapsedboolfalse

Whether or not the item's sub-navigation is in a collapsed state by default

onClickfunc

Called when the link is clicked, with the following arguments: SyntheticEvent, id, url.

This takes precedence over the VerticalNav onLinkClick prop

onSubnavTogglefunc

Called when this item's subnav is collapsed or expanded, with the following arguments: id, collapsed

idstring

Optional identifier. This can be handy if you're passing in an onClick handler. A unique ID will be generated if one isn't provided.

itemsarrayOf[custom]

An array of nested VerticalNavItem data objects to be rendered in a sub-navigation list.

label

Required

string, number, element, or array

Text to render for this nav item

urlstring

A URL to navigate to if this item is a link

selectedbool

If this item is currently selected

Guidance

When to use

  • To display a navigational hierarchy with one to three levels.
  • To display the “sub-navigation” within a section of the website.

When to consider alternatives

  • If the site has fewer than five pages, consider organizing the page without a navigational hierarchy.
  • If your page already has a horizontal and vertical navigation bar, consider ways to simplify your navigation system.
  • If your content is within a frame or sub-area of a page, consider ways to simplify your navigation system.

Usage

  • Indicate where a user is within the navigational hierarchy. Use the .ds-c-vertical-nav__label--current modifier to show users which page they have navigated to.
  • Keep the navigation links short and follow sentence case. They can be shorter derivatives of page titles themselves.
  • If the navigation hierarchy is too long, users may miss items at the bottom. If it’s too deep, users may miss items that require too many clicks. Usability test to find the right balance between breadth and depth.

Accessibility

  • Users should be able to tab through each link.
  • If you have nested menus that are collapsible, ensure the toggle button has its aria-controls and aria-expanded attributes set. This is done automatically for you if you're using the React components.
  • If your navigation list is longer than 3 items, consider using a skip navigation link. This allows screen reader and keyboard users to skip to the main content area(s).
  • If a skip navigation link is not an option, consider using:
    • A valid, descriptive page header
    • Landmark regions like <header>, <nav>, <main>, <aside>, <footer>
    • A role attribute like <div role="navigation">

Related patterns

Learn more