Skip to content

<nav>

Semanticus CSS adds opinionated styling to <nav> to reduce boilerplate for common navigation patterns like horizontal navs, breadcrumbs, and sidebars.

Accessibility: Keep in mind this element has the implicit role="navigation", which means screen readers expose it as a navigation landmark, allowing users to jump directly to or skip past the navigation, so it's best not to combine it with other roles like role="group" and role="list".

Basic Usage

  • <nav> is a flex container that uses justify-content: space-between to distribute its children across the horizontal axis;
  • All direct children of <nav> will have their margin-block set to 0;
  • In case of a single child, it will grow to fill the available space;
live preview
editable html
<nav>
  <a href="#"><strong>Acme Corp</strong></a>
  
  <p>tag line</p>
  
  <a href="#!" class="secondary">Log out</a>
</nav>

Horizontal Navigation

  • <ul> children also become a horizontal flex container;
  • <li> children will become unstyled and inlined;
  • <a> children will lose their underline except on :hover.
  • <button> and <details> (Dropdowns) children will automatically match the height and padding of links.
live preview
editable html
<nav>
  <div>
    <img style="width: 30px" src="https://semanticus.design/logo.svg" alt="Brand logo">
    <strong class="fs-6">Acme Corp</strong>
  </div>
  
  <ul>
    <li><a href="#about">About</a></li>
    <li><a href="#products" aria-current="page">Products</a></li>
    <li><button>Log In</button></li>
  </ul>
</nav>

Breadcrumbs are implemented using a single <ol> element inside a <nav> — the semantic way to represent the current page's location within a navigational hierarchy.

Each breadcrumb item is represented as an <li> element, and the current page is typically indicated by adding aria-current="page" to the <a> or the corresponding <li> element.

Accessibility: Don't forget to add aria-label="Breadcrumbs" to the <nav> element for better accessibility.

live preview
editable html
<nav aria-label="Breadcrumbs">
  <ol>
    <li><a href="#">Home</a></li>
    <li><a href="#category">Category</a></li>
    <li aria-current="page"><a href="#page">Page</a></li>
  </ol>
</nav>

Vertical Navigation

  • <nav>, <ul> and <ol> elements get stacked vertically when inside an <aside>;
  • When <nav> is a direct child of an <aside> it will stretch itself to fill the available height.
live preview
editable html
<aside style="height: 300px; width: 200px">
  <nav>
    <ul>
      <li>
        <div class="hstack gap-1">
          <img style="width: 30px" src="https://semanticus.design/logo.svg" alt="Brand logo" />
          <strong class="fs-6">Semanticus CSS</strong>
        </div>
      </li>
      <li><hr /></li>
    
      <li><a href="#about">About</a></li>
      <li><a href="#getting-started" aria-current="page">Getting Started</a></li>
      <li><a href="#advanced-usage">Advanced Usage</a></li>
      <li><a href="#uninstall">Uninstall</a></li>
    
      <li class="flex-grow-1"></li>
      <li><button class="ghost">Support</button></li>
    </ul>
  </nav>
</aside>

Button-Based Pagination

The simplest pagination pattern uses buttons within a group:

Note: When a step isn't available yet but should be announced, use aria-disabled="true" instead of the native disabled attribute to keep the element focusable and discoverable by assistive technology users. Remember that aria-disabled does not block activation on its own, so you must also prevent activation/navigation in code (for example, in a JavaScript handler). In case you want to remove it from the tab order as well, add tabindex="-1".

live preview
editable html
<nav aria-label="Pagination">
  <div role="group">
    <button>Previous</button>
    <button>1</button>
    <button>2</button>
    <button aria-current="page">3</button>
    <button aria-disabled="true" tabindex="-1">Next</button>
  </div>
</nav>

For server-side rendering or distinct page URLs, use anchor elements with role="button":

Note: disabled is not a valid attribute for <a> elements, so in this case you really need to use aria-disabled="true" instead.

live preview
editable html
<nav aria-label="Pagination">
  <div role="group">
    <a role="button" aria-disabled="true" tabindex="-1">Previous</a>
    <a href="#page-1" role="button" aria-current="page">1</a>
    <a href="#page-2" role="button">2</a>
    <a href="#page-3" role="button">3</a>
    <a href="#page-3" role="button">Next</a>
  </div>
</nav>