Navbar

How the Navbar works with a keyboard and assistive tech, and where it stands against WCAG 2.2 AA.

FreeReact and VueNavbar blocks9 blocksPro
AAWCAG 2.2 target
6/6contrast pairs passing
5keyboard interactions

The Navbar is a <header> around a <nav> of links, with one call to action. On small screens the links fold into a disclosure: a menu button that shows and hides a panel. It follows the WAI-ARIA Disclosure pattern rather than the menu pattern, so links behave as links. It is held to WCAG 2.2 AA.

Keyboard#

Tab

Moves through the skip link, the brand, each link and the call to action in reading order.

Shift+Tab

Moves back the same way.

Enter

Follows the focused link, or opens and closes the menu from the menu button.

Space

Opens and closes the menu from the menu button.

Esc

Closes the open menu and returns focus to the menu button.

Semantics#

<header>

The banner landmark, when it is not inside another sectioning element.

Always
<nav aria-label="Main">

The main navigation landmark. Use the same name on desktop and in the mobile panel; only one is shown at a time.

Always
aria-current="page"

Announced as the current page. The soft surface behind it only echoes it.

Current link
aria-expanded

true while the panel is open. The button is a <button> named Open menu or Close menu.

Menu button
aria-controls

Points at the panel's id.

Menu button
hidden

The closed panel is hidden, so its links can't be reached or read.

Menu closed
<a href="#main">

The first focusable element on the page, visible on focus, jumping to the main content.

Skip link

Colour contrast#

Every variant and state has to meet WCAG 2.2 Level AA. Measure the colours as they land on screen: a translucent hover or press wash over whatever sits behind it.

4.5:1

Link text · Default, Hover, Current

The 13.5–14px Medium link against the bar or the current link's surface, on desktop and in the mobile panel.

WCAG 1.4.3 Contrast (Minimum) ↗
4.5:1

Call to action · Default, Hover

White on #064438, 11.10:1, and 8.75:1 on hover.

WCAG 1.4.3 Contrast (Minimum) ↗
3:1

Menu button · Mobile

The menu and close glyphs are #1a1a1a on white, 17.40:1. The #e1e1e1 ring is 1.31:1, but the glyph alone identifies the control.

WCAG 1.4.11 Non-text Contrast ↗
3:1

Focus indicator · Focus visible

The preview rings in #59eaa9, 1.53:1 on white, which falls short. Use the library's #1a6ef8 (4.54:1) or the brand's dark green. A sticky bar must also not cover the element that has focus below it.

WCAG 1.4.11 Non-text Contrast ↗WCAG 2.4.13 Focus Appearance ↗WCAG 2.4.11 Focus Not Obscured ↗
Not colour alone

Current link · Current

The current link is marked with a filled surface as well as darker text, and aria-current says so to assistive tech.

WCAG 1.4.1 Use of Color ↗

Measured contrast#

Link text against the white bar or the current link's surface, read from the Navbar preview's colours. All 6 pairs reach their minimum.

Layout · elementDefaultHoverCurrent
Desktop · link5.02passes17.40passes15.68passes
Mobile panel · link8.86passes16.10passes9.90passes

Motion#

  • The mobile panel opens and closes at once; nothing slides.
  • Link colours change over 150ms. The preview does not turn that off under prefers-reduced-motion yet; it is a colour fade, not movement, but add motion-reduce:transition-none to match the library.

Checklist#

Add a skip link before the bar. The preview doesn't draw one.

Replace the #59eaa9 focus ring: it is 1.53:1 on white and fails WCAG 1.4.11.

The brand link has a name: the visible product name, or an aria-label when only the mark shows.

Desktop links are about 32px tall and mobile links 40px; the menu button and call to action are 36px. All clear the 24px minimum.

Keep the order the same on every page. Five or six links at most; group the rest or use a sidebar.

With a sticky bar, add scroll-padding-top equal to its height so focused elements and anchors don't land underneath it.

Close the mobile panel after a link is followed, and when the window grows past the breakpoint.