Navbar

A responsive <nav class="navbar">. Below $nav-expands (1200px) it collapses to a hamburger; above it, the full bar shows.

Structure

Navbar elements
ClassRole
.navbar.containerThe bar and its content width.
.navbar-brandAlways-visible left area — logo, key links, and the .hamburger button.
.navbar-menuThe main menu. Hidden below the breakpoint until the hamburger is pressed. Any <ul> inside is treated as navigation.
.navbar-start / .navbar-endOptional wrappers to split the menu left / right on wide screens.
.navbar-itemA vertically-centred item (link, text, button…) placed directly in the bar.
li.has-childrenA list item that contains a nested <ul> submenu.
.hide-above-nav / .hide-below-navShow an element only in the collapsed / expanded state.

Keyboard

Navbar keyboard interaction
KeyAction
Tab / Shift+TabMove through links. On wide screens a submenu opens while any link inside it has focus (:focus-within).
Enter / SpaceFollow the focused link. On narrow screens, on a .has-children link, toggles its submenu instead.
EscClose the open mobile menu / drawer.

Basic navbar

Submenus nest to any depth — put .has-children on every parent <li>. On wide screens the first level drops down, deeper levels fly out sideways; on narrow screens they indent.

Off-canvas drawer

Add .is-off-canvas to .navbar-menu and the collapsed menu slides in from the side instead of pushing the page down. Repeat the brand + hamburger inside a .navbar-top so the drawer has its own close control.

Overriding

The bar is branded: $navbar-family (default primary) at its 500 in both modes, with link and hover colours derived from that family's --jf-color-on-* companions. Submenus and the drawer sit on a neutral soft surface instead, so the whole navbar reads correctly in light and dark out of the box.

  • Rebrand — set $navbar-family.
  • Retune at runtime — the --jf-navbar-* custom properties, tabled below. They stay on :root, so set them there or on a scoped selector.
  • Breakpoint$nav-expands. Also update breakPoints.navBar in your JS if you change it — see the caveat below.

Keep the JS breakpoint in sync

The hamburger / submenu toggle logic in navbar.js decides mobile vs. desktop from a hardcoded JS global — breakPoints.navBar (src/js/breakpoints.js, default 1200, matching $nav-expands) — it doesn't read the CSS breakpoint. Change $nav-expands without updating breakPoints.navBar to match, and the JS and CSS disagree right at the boundary (a submenu that should hover-open instead needs a tap, or vice versa). This dual source of truth is a known limitation, parked for removal alongside the rest of the navbar's JS in a future navigation rewrite.

Variables

Sass variables

Navbar Sass variables
NameDefaultNotes
$generate-navbartrueEmit the navbar CSS at all.
$nav-expands1200pxWidth at which the bar switches from collapsed to expanded. Keep breakPoints.navBar in your JS in sync — see the note above.
$navbar-familyprimaryPalette family the bar is branded from. Everything below defaults off it.
$navbar-bg-colorget-color($navbar-family)Bar background → --jf-navbar-bg-color.
$navbar-link-bg-color$navbar-bg-colorTop-level link background → --jf-navbar-link-bg-color. Its text colour is contrast-picked from this.
$navbar-link-hover-bg-colorget-color-role($navbar-family, emphasis)Top-level link background on hover / focus → --jf-navbar-link-hover-bg-color.
$navbar-link-hover-weight$navbar-font-weightLink weight on hover → --jf-navbar-link-hover-weight. Changing it reflows the bar unless the face is variable.
$navbar-link-bordera 12% currentColor ruleDivider between top-level links → --jf-navbar-link-border.
$navbar-font-sizetoken(font-size-lg)Link text size while collapsed → --jf-navbar-font-size.
$navbar-font-size-expandedtoken(font-size-base)Link text size once expanded. Build-time only.
$navbar-font-familytoken(font-primary)Link typeface → --jf-navbar-font-family.
$navbar-font-weightget-weight(bold)Link weight → --jf-navbar-font-weight.
$navbar-text-transformnoneLink text-transform--jf-navbar-text-transform.
$navbar-link-padding-xget-space(xs)Link inline padding while collapsed → --jf-navbar-link-padding-x.
$navbar-link-padding-yget-space(2xs)Link block padding while collapsed → --jf-navbar-link-padding-y.
$navbar-link-padding-expanded-xget-space(xs)Link inline padding once expanded. Build-time only.
$navbar-link-padding-expanded-yget-space(xs)Link block padding once expanded. Build-time only.
$navbar-sublink-bg-colortoken(color-bg-soft)Submenu panel background → --jf-navbar-sublink-bg-color. A neutral surface, not the brand family, so submenus read correctly in both themes.
$navbar-sublink-hover-bg-colorget-color-role(neutral, muted)Submenu link background on hover → --jf-navbar-sublink-hover-bg-color.
$navbar-sublink-font-sizetoken(font-size-md)Submenu link text size while collapsed.
$navbar-sublink-font-size-expandedtoken(font-size-sm)Submenu link text size once expanded.
$navbar-sublink-font-familytoken(font-primary)Submenu link typeface.
$navbar-sublink-font-weight$navbar-font-weightSubmenu link weight — inherits the top-level link's by default.
$navbar-sublink-font-weight-hover$navbar-link-hover-weightSubmenu link weight on hover.
$navbar-sublink-text-transform$navbar-text-transformSubmenu link text-transform.
$navbar-dropdown-widthget-size(16) (256px)Width of an expanded submenu panel → --jf-navbar-dropdown-width.
$navbar-dropdown-anchors-right-after3Submenus on the nth top-level item and beyond open to the inline-start instead of the end, so a menu near the edge of the bar does not run off-screen.
$navbar-start-flex-alignstretchalign-items on .navbar-start once expanded.
$navbar-end-flex-aligncenteralign-items on .navbar-end once expanded.
$navbar-offcanvas-positionrightSide the .is-off-canvas drawer slides in from.
$navbar-offcanvas-width80%Drawer width.
$navbar-offcanvas-maxwidth480pxCap on that width.
$navbar-offcanvas-bg-colortoken(color-bg-soft)Drawer background.
$navbar-offcanvas-body-overlay50% blackScrim painted over the page behind an open drawer.
$navbar-offcanvas-transition-speedtoken(duration-slow)Drawer slide duration. Zeroed by prefers-reduced-motion along with every other duration token.

Custom properties

Navbar custom properties
NameDefaultNotes
--jf-navbar-bg-color$navbar-bg-colorBar background.
--jf-navbar-link-colorcontrast-pickedTop-level link text, chosen against --jf-navbar-link-bg-color.
--jf-navbar-link-bg-color$navbar-link-bg-colorTop-level link background.
--jf-navbar-link-hover-colorcontrast-pickedTop-level link text on hover / focus.
--jf-navbar-link-hover-bg-color$navbar-link-hover-bg-colorTop-level link background on hover / focus.
--jf-navbar-link-hover-weight$navbar-link-hover-weightTop-level link weight on hover.
--jf-navbar-link-border$navbar-link-borderDivider between top-level links.
--jf-navbar-sublink-colorcontrast-pickedSubmenu link text.
--jf-navbar-sublink-bg-color$navbar-sublink-bg-colorSubmenu panel background.
--jf-navbar-sublink-hover-colorcontrast-pickedSubmenu link text on hover.
--jf-navbar-sublink-hover-bg-color$navbar-sublink-hover-bg-colorSubmenu link background on hover.
--jf-navbar-font-size$navbar-font-sizeLink text size.
--jf-navbar-font-family$navbar-font-familyLink typeface.
--jf-navbar-font-weight$navbar-font-weightLink weight.
--jf-navbar-text-transform$navbar-text-transformLink text-transform.
--jf-navbar-link-padding-x$navbar-link-padding-xLink inline padding.
--jf-navbar-link-padding-y$navbar-link-padding-yLink block padding.
--jf-navbar-dropdown-width$navbar-dropdown-widthExpanded submenu panel width.