Skip to content

Nav Pills

Filled section navigation for settings, account, and admin sub-nav. The current item uses a filled (soft primary) background.

This is not Tabs (underline tablist with panels) and not List Group (bordered selectable list). For app chrome, pair with App shell. For always-vertical hierarchical nav, see Side Navigation.

Use a <nav> and mark the current page with aria-current="page". Direct links, or a list of links, both work.

<nav class="af-nav-pills" aria-label="Settings">
  <a href="#profile" aria-current="page">Profile</a>
  <a href="#security">Security</a>
  <a href="#notifications">Notifications</a>
  <a href="#billing">Billing</a>
</nav>

As a list (screen readers announce the count):

<nav aria-label="Settings">
  <ul class="af-nav-pills">
    <li>
      <a href="#profile" aria-current="page">Profile</a>
    </li>
    <li>
      <a href="#security">Security</a>
    </li>
    <li>
      <a href="#notifications">Notifications</a>
    </li>
  </ul>
</nav>
  • Below lg (1024px): row, no wrap, horizontal scroll
  • lg and up: column
  • Active: aria-current="page" (or aria-current="true" / af-is-active) gets the filled style

Force orientation when the fallback doesn’t match the layout:

  • af-is-vertical — always column (for example inside af-app__sidebar)
  • af-is-horizontal — always row + scroll
NeedUse
In-page panelsaf-tabs
Bordered selectable listaf-list-group
Nested / hierarchical sidebaraf-side-nav
  • Wrap in <nav aria-label="…">
  • Current destination: aria-current="page" — this is not an ARIA tablist (role="tab" / aria-selected)
  • Keyboard: native link/button focus; keep visible :focus-visible