Navbar
Build responsive site and application navigation with branding, nav links, forms, and a drawer-based mobile menu — composable from Chassis sub-components.
Overview
The navbar is the primary navigation surface for a site or application. It composes a branding area, a set of navigation links, optional forms or text, and a drawer-based mobile menu — all wrapped in a single <nav> element that is responsive by default.
Key features
- Collapses into a slide-in drawer at a chosen breakpoint via the
.{breakpoint}:navbar-expandmodifier - Built-in sub-components for branding (
.navbar-brand), navigation (.navbar-nav), forms, and inline text (.navbar-text) - Container-query based — the expand transition responds to the navbar's own width, not the viewport
- Themed through standard Chassis context classes (
.context.<color>) anddata-cx-theme="dark" - Translucent variant for navbars positioned over content
- Integrates with the Drawer, Collapse, and Menu JavaScript plugins
Basic structure
A complete navbar combines five elements: the .navbar wrapper, an inner container (typically .container.fluid), a .navbar-brand, a .navbar-toggler button, and a <dialog class="drawer"> that holds the navigation when collapsed. Below the chosen .{breakpoint}:navbar-expand breakpoint, the toggler reveals the drawer; above it, the drawer's contents flow inline and the toggler hides automatically.
Resize the example below to preview the transition between drawer and inline modes.
<nav class="navbar medium:navbar-expand bg-even" aria-label="Main navigation">
<div class="container fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="button icon-only navbar-toggler" type="button" data-cx-toggle="drawer" data-cx-target="#navbarDrawer" aria-controls="navbarDrawer" aria-expanded="false" aria-label="Toggle navigation">
<svg class="icon navbar-toggler-icon" aria-hidden="true"><use href="#bars-outline"></use></svg>
</button>
<dialog class="drawer drawer-end" tabindex="-1" id="navbarDrawer" aria-labelledby="navbarDrawerLabel">
<div class="drawer-header">
<h2 class="drawer-title" id="navbarDrawerLabel">Menu</h2>
<button type="button" class="close-button" data-cx-dismiss="drawer" aria-label="Close"></button>
</div>
<div class="drawer-body mb-small medium:mb-0">
<ul class="navbar-nav me-auto">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<button class="nav-link menu-toggle" type="button" data-cx-toggle="menu" aria-expanded="false">
Menu
</button>
<div class="menu">
<a class="menu-item" href="#">Action</a>
<a class="menu-item" href="#">Another action</a>
<hr class="menu-divider">
<a class="menu-item" href="#">Something else here</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link disabled" aria-disabled="true">Disabled</a>
</li>
</ul>
<form class="hstack gap-small" role="search">
<input class="form-input" type="search" placeholder="Search" aria-label="Search"/>
<button class="button neutral smooth icon-only" type="submit" aria-label="Search">
<svg class="icon" aria-hidden="true"><use href="#search-solid"></use></svg>
</button>
</form>
</div>
</dialog>
</div>
</nav>Content components
The navbar exposes a small set of sub-components — brand, nav, forms, and inline text — that combine into a complete navigation surface. Each can appear independently or together inside the same .navbar.
Branding
The .navbar-brand sets the project or product identity at the start of the navbar. It works on any element, but an anchor is the most common choice since the brand typically links to the home page.
Text
Wrap a text label in any element carrying .navbar-brand.
<nav class="navbar bg-even" aria-label="Main navigation">
<div class="container fluid">
<a class="navbar-brand" href="#">Navbar</a>
</div>
</nav>Image
Replace the text with an <img> for an image-only brand.
<nav class="navbar bg-even" aria-label="Main navigation">
<div class="container">
<a class="navbar-brand" href="#">
<img src="/static/images/site-logo.svg" alt="Chassis CSS" height="24">
</a>
</div>
</nav>Image and text
Combine an image and text in the same brand element. The .d-inline-block and .align-text-top utilities keep the image aligned with the surrounding text baseline.
<nav class="navbar bg-even" aria-label="Main navigation">
<div class="container fluid">
<a class="navbar-brand" href="#">
<img src="/static/images/site-logo.svg" alt="Logo" height="24" class="d-inline-block align-text-top">
<span class="ms-xsmall font-strong">CSS</span>
</a>
</div>
</nav>Navigation links
Navbar navigation uses .nav-link inside a .navbar-nav container. The container holds the links inside the drawer below the expand breakpoint and lays them out inline above it, where they grow to occupy the available horizontal space.
Mark the current link with .active and aria-current="page".
<nav class="navbar small:navbar-expand bg-even" aria-label="Main navigation">
<div class="container fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="button icon-only navbar-toggler" type="button" data-cx-toggle="drawer" data-cx-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<svg class="icon navbar-toggler-icon" aria-hidden="true"><use href="#bars-outline"></use></svg>
</button>
<dialog class="drawer drawer-end" tabindex="-1" id="navbarNav" aria-labelledby="navbarNavLabel">
<div class="drawer-header">
<h3 class="drawer-title" id="navbarNavLabel">Menu</h3>
<button type="button" class="close-button" data-cx-dismiss="drawer" aria-label="Close"></button>
</div>
<div class="drawer-body">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
<li class="nav-item">
<a class="nav-link disabled" aria-disabled="true">Disabled</a>
</li>
</ul>
</div>
</dialog>
</div>
</nav>Alternative markup
The <ul> / <li> structure is optional. A plain <div class="navbar-nav"> containing direct <a class="nav-link"> children produces the same result, and pairs naturally with .nav-pills or other nav variants.
<nav class="navbar small:navbar-expand bg-even" aria-label="Main navigation">
<div class="container fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="button icon-only navbar-toggler" type="button" data-cx-toggle="drawer" data-cx-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<svg class="icon navbar-toggler-icon" aria-hidden="true"><use href="#bars-outline"></use></svg>
</button>
<dialog class="drawer drawer-end" tabindex="-1" id="navbarNavAltMarkup" aria-labelledby="navbarNavAltMarkupLabel">
<div class="drawer-header">
<h3 class="drawer-title" id="navbarNavAltMarkupLabel">Menu</h3>
<button type="button" class="close-button" data-cx-dismiss="drawer" aria-label="Close"></button>
</div>
<div class="drawer-body">
<div class="nav-pills navbar-nav">
<a class="nav-link active" aria-current="page" href="#">Home</a>
<a class="nav-link" href="#">Link</a>
<a class="nav-link" href="#">About</a>
<a class="nav-link disabled" aria-disabled="true">Disabled</a>
</div>
</div>
</dialog>
</div>
</nav>With menus
The Menu plugin nests inside a .nav-item, with the trigger marked by data-cx-toggle="menu". The wrapping .nav-item is required so the menu positions correctly relative to its trigger.
<nav class="navbar medium:navbar-expand bg-even" aria-label="Main navigation">
<div class="container fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="button icon-only navbar-toggler" type="button" data-cx-toggle="drawer" data-cx-target="#navbarNavMenu" aria-controls="navbarNavMenu" aria-expanded="false" aria-label="Toggle navigation">
<svg class="icon navbar-toggler-icon" aria-hidden="true"><use href="#bars-outline"></use></svg>
</button>
<dialog class="drawer drawer-end" tabindex="-1" id="navbarNavMenu" aria-labelledby="navbarNavMenuLabel">
<div class="drawer-header">
<h2 class="drawer-title" id="navbarNavMenuLabel">Menu</h2>
<button type="button" class="close-button" data-cx-dismiss="drawer" aria-label="Close"></button>
</div>
<div class="drawer-body">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
<li class="nav-item">
<button class="nav-link" type="button" data-cx-toggle="menu" aria-expanded="false">
Menu
</button>
<div class="menu">
<a class="menu-item" href="#">Action</a>
<a class="menu-item" href="#">Another action</a>
<a class="menu-item" href="#">Something else here</a>
</div>
</li>
</ul>
</div>
</dialog>
</div>
</nav>Forms
Form controls placed inside a navbar use the standard form classes. The navbar's flex layout defaults to justify-content: space-between, so a brand on the left and a form on the right align automatically without additional utilities.
A standalone search form:
<nav class="navbar bg-even" aria-label="Main navigation">
<div class="container fluid">
<form class="d-flex" role="search">
<input class="form-input me-small" type="search" placeholder="Search" aria-label="Search"/>
<button class="button primary outline" type="submit">Search</button>
</form>
</div>
</nav>The same form alongside a brand — the flex layout pushes the form to the opposite edge:
<nav class="navbar bg-even" aria-label="Main navigation">
<div class="container fluid">
<a class="navbar-brand">Navbar</a>
<form class="d-flex" role="search">
<input class="form-input me-small" type="search" placeholder="Search" aria-label="Search"/>
<button class="button primary outline" type="submit">Search</button>
</form>
</div>
</nav>Input groups work too. When the navbar is essentially a form, using the <form> element as the inner container saves a level of markup.
<nav class="navbar bg-even" aria-label="Main navigation">
<form class="container fluid">
<div class="input-group">
<span class="input-addon" id="basic-addon1">@</span>
<input type="text" class="form-input" placeholder="Username" aria-label="Username" aria-describedby="basic-addon1"/>
<button type="submit" class="button primary">Submit</button>
</div>
</form>
</nav>Mixed button sizes inside a navbar form align via the same flex layout, with vertical alignment utilities available for finer adjustment.
<nav class="navbar bg-even" aria-label="Main navigation">
<form class="container fluid justify-content-start">
<button class="button primary outline me-small" type="button">Main button</button>
<button class="button small secondary outline" type="button">Smaller button</button>
<button type="submit" hidden>Submit</button>
</form>
</nav>Text content
The .navbar-text class adjusts vertical alignment and horizontal spacing for inline strings of text inside the navbar.
<nav class="navbar bg-even" aria-label="Main navigation">
<div class="container fluid">
<span class="navbar-text">
Navbar text with an inline element
</span>
</div>
</nav>Text combines naturally with other navbar components inside the drawer body.
<nav class="navbar medium:navbar-expand bg-even" aria-label="Main navigation">
<div class="container fluid">
<a class="navbar-brand" href="#">Navbar w/ text</a>
<button class="button icon-only navbar-toggler" type="button" data-cx-toggle="drawer" data-cx-target="#navbarText" aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation">
<svg class="icon navbar-toggler-icon" aria-hidden="true"><use href="#bars-outline"></use></svg>
</button>
<dialog class="drawer drawer-end" tabindex="-1" id="navbarText" aria-labelledby="navbarTextLabel">
<div class="drawer-header">
<h2 class="drawer-title" id="navbarTextLabel">Menu</h2>
<button type="button" class="close-button" data-cx-dismiss="drawer" aria-label="Close"></button>
</div>
<div class="drawer-body">
<ul class="navbar-nav me-auto mb-small medium:mb-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
</ul>
<span class="navbar-text">
Navbar text with an inline element
</span>
</div>
</dialog>
</div>
</nav>Theming
The navbar inherits Chassis's full theming system — dark mode toggles, context color variants, and a translucent variant for over-content navbars.
Dark mode
Apply data-cx-theme="dark" directly to the .navbar element to opt a single navbar into the dark theme regardless of the page's color scheme.
<nav class="navbar medium:navbar-expand bg-even" data-cx-theme="dark" aria-label="Main navigation">
<div class="container fluid">
<a class="navbar-brand" href="#">Dark navbar</a>
<button class="button icon-only navbar-toggler" type="button" data-cx-toggle="drawer" data-cx-target="#navbarDarkDrawer" aria-controls="navbarDarkDrawer" aria-expanded="false" aria-label="Toggle navigation">
<svg class="icon navbar-toggler-icon" aria-hidden="true"><use href="#bars-outline"></use></svg>
</button>
<dialog class="drawer drawer-end" tabindex="-1" id="navbarDarkDrawer" aria-labelledby="navbarDarkDrawerLabel">
<div class="drawer-header">
<h2 class="drawer-title" id="navbarDarkDrawerLabel">Menu</h2>
<button type="button" class="close-button" data-cx-dismiss="drawer" aria-label="Close"></button>
</div>
<div class="drawer-body mb-small medium:mb-0">
<ul class="navbar-nav me-auto">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<button class="nav-link" type="button" data-cx-toggle="menu" aria-expanded="false">
Menu
</button>
<div class="menu">
<a class="menu-item" href="#">Action</a>
<a class="menu-item" href="#">Another action</a>
<hr class="menu-divider">
<a class="menu-item" href="#">Something else here</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link disabled" aria-disabled="true">Disabled</a>
</li>
</ul>
<form class="hstack gap-small" role="search">
<input class="form-input" type="search" placeholder="Search" aria-label="Search"/>
<button class="button primary outline icon-only" type="submit" aria-label="Search">
<svg class="icon" aria-hidden="true"><use href="#search-solid"></use></svg>
</button>
</form>
</div>
</dialog>
</div>
</nav>Context variants
The .context.<color> modifier swaps the navbar's color palette to a semantic context. Combine with .solid for a saturated fill, with bg-* utilities for custom backgrounds, or with data-cx-theme to mix theme and context independently.
<nav class="navbar context primary solid" aria-label="Main navigation">
<!-- Solid primary on default theme -->
</nav>
<nav class="navbar context primary bg-even" data-cx-theme="dark" aria-label="Main navigation">
<!-- Primary tint on a dark sub-tree -->
</nav>
<nav class="navbar context primary bg-even" data-cx-theme="light" aria-label="Main navigation">
<!-- Primary tint on a light sub-tree -->
</nav>Translucent
The .translucent modifier blurs and saturates whatever sits behind the navbar — useful when the navbar is positioned over a hero image, video, or scrollable content.
<nav class="navbar translucent medium:navbar-expand" aria-label="Main navigation">
<div class="container fluid">
<a class="navbar-brand" href="#">Navbar</a>
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
</ul>
</div>
</nav>Layout options
The navbar can be wrapped in a container, hold its own container, sit fixed at the top or bottom of the viewport, or stick during scroll.
Containers
A navbar wrapped in a .container is centered on the page; the inner container is still required for the navbar's own padding. Placing the inner container directly inside .navbar instead centers only the navbar's contents while keeping its background full-width.
<div class="container">
<nav class="navbar large:navbar-expand bg-even" aria-label="Main navigation">
<div class="container fluid">
<a class="navbar-brand" href="#">Navbar</a>
</div>
</nav>
</div>Any responsive container variant is available to control how wide the navbar's contents appear.
<nav class="navbar large:navbar-expand bg-even" aria-label="Main navigation">
<div class="container medium">
<a class="navbar-brand" href="#">Navbar</a>
</div>
</nav>Placement
The position utilities — .fixed-top, .fixed-bottom, .sticky-top, .sticky-bottom — pull the navbar out of normal flow or pin it during scroll. Fixed navbars use position: fixed and may require a compensating offset on the body (e.g. padding-top) to prevent content overlap.
<nav class="navbar bg-evident">
<div class="container fluid">
<a class="navbar-brand" href="#">Default</a>
</div>
</nav><nav class="navbar bg-evident">
<div class="container fluid">
<a class="navbar-brand" href="#">Default</a>
</div>
</nav><nav class="navbar fixed-top bg-evident">
<div class="container fluid">
<a class="navbar-brand" href="#">Fixed top</a>
</div>
</nav><nav class="navbar fixed-bottom bg-evident">
<div class="container fluid">
<a class="navbar-brand" href="#">Fixed bottom</a>
</div>
</nav><nav class="navbar sticky-top bg-evident">
<div class="container fluid">
<a class="navbar-brand" href="#">Sticky top</a>
</div>
</nav><nav class="navbar sticky-bottom bg-evident">
<div class="container fluid">
<a class="navbar-brand" href="#">Sticky bottom</a>
</div>
</nav>Advanced features
Beyond the basic structure, the navbar exposes controls for tuning its responsive transition, the drawer's slide direction, the toggler's position, and integration with content that lives outside the .navbar element itself.
Responsive behavior
The .{breakpoint}:navbar-expand modifier controls when the navbar transitions between drawer mode and inline mode:
.small:navbar-expand— drawer below the small breakpoint, inline at small and above.medium:navbar-expand— drawer below medium, inline at medium and above.large:navbar-expand— drawer below large, inline at large and above.xlarge:navbar-expand— drawer below xlarge, inline at xlarge and above.2xlarge:navbar-expand— drawer below 2xlarge, inline at 2xlarge and above.navbar-expand— inline at all widths (toggler hidden, drawer markup renders flat inside the navbar)- No
.navbar-expandclass — drawer at all widths (toggler always visible, the drawer must be opened to access the nav)
The breakpoint trigger is implemented with container queries, so the transition responds to the navbar's own width rather than the viewport width.
Drawer placement
The drawer slides in from any side via the .drawer-{position} classes:
.drawer-start— left edge (or right in RTL).drawer-end— right edge (or left in RTL); used as the default in this doc's examples.drawer-top— top edge.drawer-bottom— bottom edge
The examples below omit the .{breakpoint}:navbar-expand class so the drawer is always visible regardless of viewport width.
<nav class="navbar medium:navbar-expand bg-even" aria-label="Main navigation">
<div class="container fluid">
<a class="navbar-brand" href="#">Left Drawer</a>
<button class="button icon-only navbar-toggler" type="button" data-cx-toggle="drawer" data-cx-target="#navbarLeftDrawer" aria-controls="navbarLeftDrawer" aria-expanded="false" aria-label="Toggle navigation">
<svg class="icon navbar-toggler-icon" aria-hidden="true"><use href="#bars-outline"></use></svg>
</button>
<dialog class="drawer drawer-start" tabindex="-1" id="navbarLeftDrawer" aria-labelledby="navbarLeftDrawerLabel">
<div class="drawer-header">
<h2 class="drawer-title" id="navbarLeftDrawerLabel">Menu</h2>
<button type="button" class="close-button" data-cx-dismiss="drawer" aria-label="Close"></button>
</div>
<div class="drawer-body">
<ul class="navbar-nav me-auto mb-small medium:mb-0">
<li class="nav-item"><a class="nav-link active" aria-current="page" href="#">Home</a></li>
<li class="nav-item"><a class="nav-link" href="#">Link</a></li>
<li class="nav-item"><a class="nav-link disabled" aria-disabled="true">Disabled</a></li>
</ul>
</div>
</dialog>
</div>
</nav><nav class="navbar medium:navbar-expand bg-even" aria-label="Main navigation">
<div class="container fluid">
<a class="navbar-brand" href="#">Top Drawer</a>
<button class="button icon-only navbar-toggler" type="button" data-cx-toggle="drawer" data-cx-target="#navbarTopDrawer" aria-controls="navbarTopDrawer" aria-expanded="false" aria-label="Toggle navigation">
<svg class="icon navbar-toggler-icon" aria-hidden="true"><use href="#bars-outline"></use></svg>
</button>
<dialog class="drawer drawer-top" tabindex="-1" id="navbarTopDrawer" aria-labelledby="navbarTopDrawerLabel">
<div class="drawer-header">
<h2 class="drawer-title" id="navbarTopDrawerLabel">Menu</h2>
<button type="button" class="close-button" data-cx-dismiss="drawer" aria-label="Close"></button>
</div>
<div class="drawer-body">
<ul class="navbar-nav me-auto mb-small medium:mb-0">
<li class="nav-item"><a class="nav-link active" aria-current="page" href="#">Home</a></li>
<li class="nav-item"><a class="nav-link" href="#">Link</a></li>
<li class="nav-item"><a class="nav-link disabled" aria-disabled="true">Disabled</a></li>
</ul>
</div>
</dialog>
</div>
</nav>Toggle button
The .navbar-toggler has no fixed position — its location within the navbar is determined by its order in the markup relative to other flex siblings. Placing it before .navbar-brand renders it on the left; placing it after renders it on the right. The flex container distributes spacing between siblings automatically, so no positioning utility classes are required.
With no .navbar-brand visible (the brand lives inside the drawer):
<nav class="navbar medium:navbar-expand bg-even" aria-label="Main navigation">
<div class="container fluid">
<button class="button icon-only navbar-toggler" type="button" data-cx-toggle="drawer" data-cx-target="#navbarTogglerDemo01" aria-controls="navbarTogglerDemo01" aria-expanded="false" aria-label="Toggle navigation">
<svg class="icon navbar-toggler-icon" aria-hidden="true"><use href="#bars-outline"></use></svg>
</button>
<dialog class="drawer drawer-end" tabindex="-1" id="navbarTogglerDemo01" aria-labelledby="navbarTogglerDemo01Label">
<div class="drawer-header">
<h2 class="drawer-title" id="navbarTogglerDemo01Label">Hidden brand</h2>
<button type="button" class="close-button" data-cx-dismiss="drawer" aria-label="Close"></button>
</div>
<div class="drawer-body">
<a class="navbar-brand" href="#">Hidden brand</a>
<ul class="navbar-nav me-auto mb-small medium:mb-0">
<li class="nav-item"><a class="nav-link active" aria-current="page" href="#">Home</a></li>
<li class="nav-item"><a class="nav-link" href="#">Link</a></li>
<li class="nav-item"><a class="nav-link disabled" aria-disabled="true">Disabled</a></li>
</ul>
<form class="d-flex" role="search">
<input class="form-control me-small" type="search" placeholder="Search" aria-label="Search"/>
<button class="button outline success" type="submit">Search</button>
</form>
</div>
</dialog>
</div>
</nav>External content
The drawer trigger matches on id and data-cx-target, so the controlled drawer can live anywhere in the document — not necessarily inside the .navbar. Use this when the controlled content is structurally separate from the navigation surface.
<dialog class="drawer drawer-top" tabindex="-1" id="navbarToggleExternalContent" data-cx-theme="dark" aria-labelledby="navbarToggleExternalContentLabel">
<div class="drawer-header">
<h2 class="drawer-title" id="navbarToggleExternalContentLabel">Collapsed content</h2>
<button type="button" class="close-button" data-cx-dismiss="drawer" aria-label="Close"></button>
</div>
<div class="drawer-body">
<span class="fg-main">Toggleable via the navbar toggler.</span>
</div>
</dialog>
<nav class="navbar bg-body" data-cx-theme="dark" aria-label="Main navigation">
<div class="container fluid">
<button class="button icon-only navbar-toggler" type="button" data-cx-toggle="drawer" data-cx-target="#navbarToggleExternalContent" aria-controls="navbarToggleExternalContent" aria-expanded="false" aria-label="Toggle navigation">
<svg class="icon navbar-toggler-icon" aria-hidden="true"><use href="#bars-outline"></use></svg>
</button>
</div>
</nav>When the controlled container precedes the toggler in document order, keyboard and assistive technology users may have trouble locating the newly revealed content. Move focus to the drawer programmatically on open, and keep the aria-controls attribute pointing at the controlled element so the toggler-to-content relationship is exposed.
Accessibility
An accessible navbar relies on semantic markup and ARIA attributes that assistive technologies can interpret.
- Use a
<nav>element (orrole="navigation"on a generic element) so the navbar is exposed as a landmark region. - Mark the current page with
aria-current="page"on the active.nav-link, oraria-current="true"for the current item in a non-page set. - The
.navbar-togglermust carryaria-label,aria-controls(pointing at the drawer's id), andaria-expanded(kept in sync by the Drawer plugin).
Chassis CSS respects user accessibility preferences by automatically disabling animations when the prefers-reduced-motion media query is detected. See the reduced motion guidelines in our accessibility documentation for implementation details.
CSS
This component can be customized through Sass variables at compile time.
Custom properties
This component exposes CSS custom properties to control its appearance at runtime.
--padding-x: var(--navbar-padding-x, #{$navbar-padding-x});
--padding-y: var(--navbar-padding-y, #{$navbar-padding-y});
--fg-color: var(--navbar-fg-color, #{$navbar-fg-color});
--bg-color: var(--navbar-bg-color, #{$navbar-bg-color});
--nav-gap: var(--navbar-nav-gap, #{$navbar-nav-gap});
--link-padding-x: var(--navbar-link-padding-x, #{$navbar-link-padding-x});
--link-padding-y: var(--navbar-link-padding-y, #{$navbar-link-padding-y});
--link-main-color: var(--navbar-link-main-color, #{$navbar-link-main-color});
--link-hover-color: var(--navbar-link-hover-color, #{$navbar-link-hover-color});
--link-active-color: var(--navbar-link-active-color, #{$navbar-link-active-color});
--link-disabled-color: var(--navbar-link-disabled-color, #{$navbar-link-disabled-color});
--brand-padding-y: var(--navbar-brand-padding-y, #{$navbar-brand-padding-y});
--brand-margin-end: var(--navbar-brand-margin-end, #{$navbar-brand-margin-end});
@include map-font($navbar-brand-font, navbar-brand, brand);
--brand-fg-color: var(--navbar-brand-fg-color, #{$navbar-brand-fg-color});
--brand-hover-color: var(--navbar-brand-hover-color, #{$navbar-brand-hover-color});
--toggler-idle-bg-color: var(--navbar-toggler-idle-bg-color, #{$navbar-toggler-idle-bg-color});
--toggler-hover-bg-color: var(--navbar-toggler-hover-bg-color, #{$navbar-toggler-hover-bg-color});
--toggler-icon-size: var(--navbar-toggler-icon-size, #{$navbar-toggler-icon-size});
--toggler-icon-color: var(--navbar-toggler-icon-color, #{$navbar-toggler-icon-color});
--translucent-opacity: var(--navbar-translucent-opacity, #{$navbar-translucent-opacity});
--translucent-blur: var(--navbar-translucent-blur, #{$navbar-translucent-blur});
--translucent-saturation: var(--navbar-translucent-saturation, #{$navbar-translucent-saturation});
@if $navbar-link-font {
@include map-font($navbar-link-font, navbar-link, link);
}Sass variables
This component uses Sass variables in scss/config/_defaults.scss to define its defaults.
$navbar-padding-y: var(--space-xsmall);
$navbar-padding-x: 0;
$navbar-fg-color: #{to-opacity(var(--fg-main), .65)};
$navbar-bg-color: var(--bg-main);
$navbar-nav-gap: 0;
$navbar-link-padding-x: var(--space-small);
$navbar-link-padding-y: var(--space-xsmall);
$navbar-link-font: null;
$navbar-link-main-color: $navbar-fg-color;
$navbar-link-hover-color: #{to-opacity(var(--fg-main), .85)};
$navbar-link-active-color: #{to-opacity(var(--fg-main), 1)};
$navbar-link-disabled-color: #{to-opacity(var(--fg-main), var(--opacity-fg-slight))};
$navbar-brand-font: $font-text-xlarge-normal;
$navbar-brand-padding-y: var(--space-2xsmall);
$navbar-brand-margin-end: 1rem;
$navbar-brand-fg-color: var(--fg-main);
$navbar-brand-hover-color: $navbar-brand-fg-color;
$navbar-toggler-idle-bg-color: transparent;
$navbar-toggler-hover-bg-color: var(--dim-slight);
$navbar-toggler-icon-color: $navbar-fg-color;
$navbar-toggler-icon-size: $icon-medium;
$navbar-translucent-opacity: $translucent-opacity;
$navbar-translucent-blur: var(--size-2xsmall);
$navbar-translucent-saturation: $translucent-saturation;Sass map
The global $breakpoints map is reassigned to $navbar-breakpoints in scss/_navbar.scss so the navbar's responsive expand/collapse classes can be configured independently of the framework's other breakpoint loops.
$navbar-breakpoints: $breakpoints;Sass loops
Responsive .{breakpoint}:navbar-expand classes are generated by looping over $navbar-breakpoints.
// Generate series of responsive `.navbar-expand` classes for configuring
// where your navbar collapses and expands. Uses container queries so the
// navbar responds to its own width, not the viewport width.
// Mixin for expanded state styles (applied to descendants)
@mixin navbar-expanded {
// Style the inner container since we can't style .navbar itself with container queries
> [class*="container"] {
flex-wrap: nowrap;
justify-content: flex-start;
}
.navbar-nav {
flex-direction: row;
}
.navbar-toggler {
display: none !important; // stylelint-disable-line declaration-no-important
}
[class*="drawer"] {
// stylelint-disable declaration-no-important
// Reset native <dialog> UA styles and below-breakpoint drawer styles.
// Must use !important to override both UA <dialog> defaults and the
// responsive drawer styles from media-breakpoint-down().
position: static !important;
inset: auto !important;
z-index: auto;
display: flex !important;
flex-grow: 1;
width: auto !important;
max-width: none !important;
height: auto !important;
max-height: none !important;
padding: 0;
margin: 0;
visibility: visible !important;
background-color: transparent !important;
border: 0 !important;
box-shadow: none !important;
transform: none !important;
@include transition(none);
// stylelint-enable declaration-no-important
.drawer-header {
display: none !important; // stylelint-disable-line declaration-no-important
}
.drawer-body {
display: flex;
flex-grow: 1;
flex-direction: row;
align-items: center;
padding: 0;
overflow-y: visible;
}
}
}
// Always expanded (no responsive behavior)
.navbar-expand {
@include navbar-expanded();
// Also set on navbar itself for non-responsive case
flex-wrap: nowrap;
justify-content: flex-start;
}
// Responsive navbar expand classes using container queries
@include loop-breakpoints-down($navbar-breakpoints) using ($breakpoint, $next, $prefix) {
@if $next {
.#{$prefix}navbar-expand {
@include container-breakpoint-up($next) {
@include navbar-expanded();
}
}
}
}