Navbar — Svelte

Navbar component — Svelte.

Navbar component

A responsive, accessible navigation bar with dropdown menus, search, and settings. The docs site uses the Astro Navbar in the layout. In a Svelte app, use the same BEM classes and HTML structure; wire open/close and keyboard behavior with Svelte state and event handlers.

Features

  • Desktop: Brand, nav links with dropdowns (e.g. Components, Themes), search trigger, settings button. Dropdowns can use a 2-column layout with vertical divider.
  • Mobile (≤1024px): Menu toggle (hamburger) on the left; search and settings (icon-only) on the right. Full-width overlay menu when open; mutually exclusive with search.
  • Sticky top, full-width border, smooth open/close transitions.
  • Full keyboard navigation for dropdowns (Arrow keys, Enter, Space, Escape, Home, End) and ARIA.
  • Settings button opens the Settings panel (window.openSettings() when using the design system scripts).

Key BEM classes and structure

Use these classes so styles apply correctly. Toggle navbar__menu--open on the menu and navbar--menu-open on the root nav for the mobile menu. Use navbar__item--has-dropdown and navbar__submenu for dropdowns; control visibility with a class (e.g. navbar__item--open) or aria-expanded and CSS.

  • navbar — root nav; add navbar--menu-open when mobile menu is open.
  • navbar__container — inner wrapper.
  • navbar__brand / navbar__brand-link — logo and home link.
  • navbar__toggle — mobile menu button; set aria-expanded from state.
  • navbar__menu — menu container; add navbar__menu--open when open.
  • navbar__item / navbar__item--has-dropdown — item wrapper; --has-dropdown for items with a submenu.
  • navbar__link — main link or dropdown trigger.
  • navbar__submenu / navbar__submenu--components / navbar__submenu--themes — submenu list and variants.
  • navbar__sublink — submenu link.
  • navbar__settings-btn — settings button.

Minimal structure example

Simplified markup; in practice you’ll add dropdown content, icons, and data attributes for your JS. In your script: let menuOpen = $state(false); let dropdownOpen = $state(false); (or use a single state for which dropdown is open).

svelte svelte
<nav class="navbar" class:navbar--menu-open={menuOpen}>
  <div class="navbar__container">
    <div class="navbar__brand">
      <a href="/" class="navbar__brand-link">Site name</a>
    </div>
    <button
      type="button"
      class="navbar__toggle"
      aria-label="Toggle menu"
      aria-expanded={menuOpen}
      onclick={() => (menuOpen = !menuOpen)}
    >
      <span class="navbar__toggle-icon" aria-hidden="true">...</span>
    </button>
    <div class="navbar__menu" class:navbar__menu--open={menuOpen} role="menu">
      <div class="navbar__item navbar__item--has-dropdown">
        <button type="button" class="navbar__link" aria-expanded={dropdownOpen} aria-haspopup="true">
          Docs
        </button>
        <ul class="navbar__submenu" role="menu" aria-hidden={!dropdownOpen}>
          <li><a href="/docs" class="navbar__sublink">Overview</a></li>
        </ul>
      </div>
      <a href="/search" class="navbar__item">Search</a>
      <button type="button" class="navbar__settings-btn" aria-label="Settings" onclick={() => window.openSettings?.()}>
        Settings
      </button>
    </div>
  </div>
</nav>

Implementing behavior in Svelte

  • Mobile menu: Bind menuOpen (or similar) to the toggle button; add navbar__menu--open to the menu and navbar--menu-open to the root when open. On mobile, close search when opening the menu if your layout shares the same pattern.
  • Dropdowns: Track which item is open (e.g. openDropdownIndex). Use aria-expanded and a class on the submenu for visibility. On desktop, consider measuring and adjusting submenu position to avoid viewport overflow (see Astro Navbar script).
  • Keyboard: Handle keydown on the menu: Arrow keys to move focus, Enter/Space to activate, Escape to close menu or dropdown. Use role="menu" and role="menuitem" (or menuitem on links) for ARIA.
  • Click outside: Close menu/dropdown when focus or click is outside the navbar (e.g. document click listener, or focus-within).

Full Astro Navbar documentation — structure, dropdown layout, and the inline script you can port to Svelte for toggle, dropdown positioning, and keyboard handling.

← Back to Svelte components