Navigation Bar
The navigation bar is a full-width 3-column grid for top-level site navigation. The center column stays optically centered regardless of how much content sits on either side.
The bar is sticky by default and uses --v-space-pageoffset for inline padding, keeping content aligned with the page layout.
Use a nav element with an aria-label as the root.
import { IconButton, Wordmark } from '@volvo-cars/react-icons';
export function NavigationBar() { return ( <nav className="navigation-bar" aria-label="Main navigation"> <div slot="start"> <button type="button" className="tap-area p-8 -ml-8 lg:hidden"> Menu </button> <a href="#top" className="tap-area p-8 -ml-8 hidden lg:block"> Our Cars </a> <a href="#top" className="tap-area p-8 hidden lg:block"> Shop </a> </div> <a slot="center" href="#top" className="py-16 px-8"> <Wordmark /> </a> <div slot="end" className="gap-24"> <IconButton icon="profile" variant="clear" size="large" bleed aria-label="Account" className="hidden md:block" /> <IconButton icon="search" variant="clear" size="large" bleed aria-label="Search" /> </div> </nav> );}This component uses slots to give content built-in styling.
slot="start"– Left-aligned items (links, menu button)slot="center"– Centered item (typically the logo)slot="end"– Right-aligned items (sign-in, search)
<nav class="navigation-bar" aria-label="Main navigation" style="border: 1px solid grey"> <div slot="start" class="bg-feedback-gray" style="border: 1px solid grey"> <code>start</code> </div> <div slot="center" class="bg-feedback-gray" style="border: 1px solid grey"> <code>center</code> </div> <div slot="end" class="bg-feedback-gray" style="border: 1px solid grey"> <code>end</code> </div></nav>Height
Section titled “Height”The bar height is 48px on small screens and 64px from the md breakpoint. This value is exposed as the --v-size-navigation-bar-height custom property so sub-navigations and content can position themselves relative to it, e.g. scroll-margin-top: var(--v-size-navigation-bar-height).
Positioning
Section titled “Positioning”The navigation bar is position: sticky by default. Override it with the --navigation-bar-position custom property — set it directly on the element as an inline style, or on :root for remote control from another component.
Sub-navigation
Section titled “Sub-navigation”When two navigation bars are present, set --navigation-bar-position: static on the main bar so it scrolls away while the sub-bar stays sticky.
import { IconButton, Wordmark } from '@volvo-cars/react-icons';import type { CSSProperties } from 'react';import { useState } from 'react';
export function SubNavigation() { const [open, setOpen] = useState(false);
return ( <div style={{ maxHeight: 320, overflow: 'auto' }}> <nav className="navigation-bar" aria-label="Main navigation" style={ open ? ({ '--navigation-bar-position': 'static' } as CSSProperties) : undefined } > <div slot="start"> <button type="button" aria-expanded={open} onClick={() => setOpen((v) => !v)} className="tap-area p-8 -ml-8" > Our Cars </button> </div> <a slot="center" href="#top" className="py-16 px-8"> <Wordmark /> </a> <div slot="end"> <IconButton icon="search" variant="clear" size="large" bleed aria-label="Search" /> </div> </nav>
{open && ( <nav className="navigation-bar bg-secondary" aria-label="Our Cars"> <div slot="start"> <a href="#top" className="tap-area p-8 -ml-8"> EX30 </a> <a href="#top" className="tap-area p-8"> EX90 </a> </div> <div slot="end"> <IconButton icon="x" variant="clear" bleed aria-label="Close sub-navigation" onClick={() => setOpen(false)} /> </div> </nav> )}
<div style={{ height: 600 }} className="bg-secondary pt-24 pagelayout"> <p className="text-secondary"> {open ? 'Scroll to see the sub-navigation stick while the main bar scrolls away.' : 'Click Our Cars to open the sub-navigation.'} </p> </div> </div> );}Accessibility
Section titled “Accessibility”- Use a
navelement as the root with a descriptivearia-label(e.g. “Main navigation”, “Our Cars”) - When multiple
navelements are present, each must have a uniquearia-label - Use
aria-expandedon buttons that toggle sub-navigations
CSS reference
Section titled “CSS reference”| Class | Description |
|---|---|
navigation-bar | Sticky 3-column navigation grid. 48px height on mobile, 64px from md breakpoint. |
| Custom property | Description | Default |
|---|---|---|
--navigation-bar-position | Controls position. Set to static to unstick. | sticky |
--v-size-navigation-bar-height | The bar’s height. 48px on mobile, 64px from md. | — |