@use "config" as *;
@use "variables" as *;
@use "mixins/border-radius" as *;
-@use "mixins/transition" as *;
@use "mixins/gradients" as *;
+@use "mixins/focus-ring" as *;
+@use "mixins/transition" as *;
@use "vendor/rfs" as *;
// scss-docs-start nav-variables
+$nav-gap: .125rem !default;
+$nav-link-gap: .5rem !default;
$nav-link-padding-y: .5rem !default;
$nav-link-padding-x: 1rem !default;
-$nav-link-font-size: null !default;
-$nav-link-font-weight: null !default;
-$nav-link-color: var(--#{$prefix}link-color) !default;
-$nav-link-hover-color: var(--#{$prefix}link-hover-color) !default;
+$nav-link-color: var(--#{$prefix}fg-2) !default;
+$nav-link-hover-color: var(--#{$prefix}fg-1) !default;
+$nav-link-hover-bg: var(--#{$prefix}bg-1) !default;
$nav-link-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out !default;
-$nav-link-disabled-color: var(--#{$prefix}secondary-color) !default;
-$nav-link-focus-box-shadow: $focus-ring-box-shadow !default;
+$nav-link-disabled-color: var(--#{$prefix}fg-4) !default;
+$nav-link-active-color: var(--#{$prefix}fg-body) !default;
+$nav-link-active-bg: var(--#{$prefix}bg-2) !default;
$nav-tabs-border-color: var(--#{$prefix}border-color) !default;
$nav-tabs-border-width: var(--#{$prefix}border-width) !default;
$nav-tabs-border-radius: var(--#{$prefix}border-radius) !default;
-$nav-tabs-link-hover-border-color: var(--#{$prefix}secondary-bg) var(--#{$prefix}secondary-bg) $nav-tabs-border-color !default;
+$nav-tabs-link-hover-border-color: var(--#{$prefix}border-subtle) !default;
$nav-tabs-link-active-color: var(--#{$prefix}emphasis-color) !default;
$nav-tabs-link-active-bg: var(--#{$prefix}bg-body) !default;
$nav-tabs-link-active-border-color: var(--#{$prefix}border-color) var(--#{$prefix}border-color) $nav-tabs-link-active-bg !default;
-$nav-pills-border-radius: var(--#{$prefix}border-radius) !default;
$nav-pills-link-active-color: $component-active-color !default;
$nav-pills-link-active-bg: $component-active-bg !default;
@layer components {
.nav {
// scss-docs-start nav-css-vars
+ --#{$prefix}nav-gap: #{$nav-gap};
+ --#{$prefix}nav-link-gap: #{$nav-link-gap};
--#{$prefix}nav-link-padding-x: #{$nav-link-padding-x};
--#{$prefix}nav-link-padding-y: #{$nav-link-padding-y};
- @include rfs($nav-link-font-size, --#{$prefix}nav-link-font-size);
- --#{$prefix}nav-link-font-weight: #{$nav-link-font-weight};
--#{$prefix}nav-link-color: #{$nav-link-color};
--#{$prefix}nav-link-hover-color: #{$nav-link-hover-color};
+ --#{$prefix}nav-link-hover-bg: #{$nav-link-hover-bg};
+ --#{$prefix}nav-link-active-color: #{$nav-link-active-color};
+ --#{$prefix}nav-link-active-bg: #{$nav-link-active-bg};
--#{$prefix}nav-link-disabled-color: #{$nav-link-disabled-color};
// scss-docs-end nav-css-vars
display: flex;
flex-wrap: wrap;
+ gap: var(--#{$prefix}nav-gap);
padding-inline-start: 0;
margin-bottom: 0;
list-style: none;
}
+ .nav-item {
+ display: flex;
+
+ }
+
.nav-link {
- display: block;
+ display: flex;
+ gap: var(--#{$prefix}nav-link-gap);
+ align-items: center;
+ justify-content: center;
padding: var(--#{$prefix}nav-link-padding-y) var(--#{$prefix}nav-link-padding-x);
- @include font-size(var(--#{$prefix}nav-link-font-size));
font-weight: var(--#{$prefix}nav-link-font-weight);
color: var(--#{$prefix}nav-link-color);
text-decoration: none;
background: none;
border: 0;
+ @include border-radius(var(--#{$prefix}border-radius));
+ // @include font-size(var(--#{$prefix}nav-link-font-size));
@include transition($nav-link-transition);
&:hover,
&:focus {
color: var(--#{$prefix}nav-link-hover-color);
+ background-color: var(--#{$prefix}nav-link-hover-bg);
}
&:focus-visible {
- outline: 0;
- box-shadow: $nav-link-focus-box-shadow;
+ color: var(--#{$prefix}nav-link-hover-color);
+ @include focus-ring(true);
+ --#{$prefix}focus-ring-offset: 1px;
+ }
+
+ &.active,
+ &:active {
+ color: var(--#{$prefix}nav-link-active-color);
+ background-color: var(--#{$prefix}nav-link-active-bg);
}
// Disabled state lightens text
.nav-link {
margin-bottom: calc(-1 * var(--#{$prefix}nav-tabs-border-width));
border: var(--#{$prefix}nav-tabs-border-width) solid transparent;
- @include border-top-radius(var(--#{$prefix}nav-tabs-border-radius));
+ @include border-bottom-radius(0);
- &:hover,
- &:focus {
+ &:hover {
// Prevents active .nav-link tab overlapping focus outline of previous/next .nav-link
isolation: isolate;
border-color: var(--#{$prefix}nav-tabs-link-hover-border-color);
+ border-bottom-color: var(--#{$prefix}nav-tabs-border-color);
}
}
color: var(--#{$prefix}nav-tabs-link-active-color);
background-color: var(--#{$prefix}nav-tabs-link-active-bg);
border-color: var(--#{$prefix}nav-tabs-link-active-border-color);
+ border-bottom-color: var(--#{$prefix}nav-tabs-link-active-bg);
}
.dropdown-menu {
.nav-pills {
// scss-docs-start nav-pills-css-vars
- --#{$prefix}nav-pills-border-radius: #{$nav-pills-border-radius};
--#{$prefix}nav-pills-link-active-color: #{$nav-pills-link-active-color};
--#{$prefix}nav-pills-link-active-bg: #{$nav-pills-link-active-bg};
// scss-docs-end nav-pills-css-vars
- .nav-link {
- @include border-radius(var(--#{$prefix}nav-pills-border-radius));
- }
-
.nav-link.active,
.show > .nav-link {
color: var(--#{$prefix}nav-pills-link-active-color);
.nav-underline {
// scss-docs-start nav-underline-css-vars
- --#{$prefix}nav-underline-gap: #{$nav-underline-gap};
+ --#{$prefix}nav-gap: #{$nav-underline-gap};
+ --#{$prefix}nav-link-active-bg: transparent;
+ // --#{$prefix}nav-underline-gap: #{$nav-underline-gap};
--#{$prefix}nav-underline-border-width: #{$nav-underline-border-width};
--#{$prefix}nav-underline-link-active-color: #{$nav-underline-link-active-color};
// scss-docs-end nav-underline-css-vars
- gap: var(--#{$prefix}nav-underline-gap);
-
.nav-link {
padding-inline: 0;
border-block-end: var(--#{$prefix}nav-underline-border-width) solid transparent;
+ @include border-radius(0);
&:hover,
&:focus {
$navbar-padding-y: $spacer * .5 !default;
$navbar-padding-x: null !default;
-$navbar-nav-link-padding-x: .5rem !default;
+$navbar-nav-link-padding-x: .75rem !default;
$navbar-brand-font-size: $font-size-lg !default;
// Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link
$navbar-toggler-focus-width: $btn-focus-width !default;
$navbar-toggler-transition: box-shadow .15s ease-in-out !default;
-$navbar-light-color: color-mix(in srgb, var(--#{$prefix}fg-black) 65%, transparent) !default;
-$navbar-light-hover-color: color-mix(in srgb, var(--#{$prefix}fg-black) 80%, transparent) !default;
-$navbar-light-active-color: color-mix(in srgb, var(--#{$prefix}fg-black) 100%, transparent) !default;
-$navbar-light-disabled-color: color-mix(in srgb, var(--#{$prefix}fg-black) 30%, transparent) !default;
+$navbar-light-color: var(--#{$prefix}fg-2) !default;
+$navbar-light-hover-color: var(--#{$prefix}fg-1) !default;
+$navbar-light-active-color: var(--#{$prefix}fg) !default;
+$navbar-light-disabled-color: var(--#{$prefix}fg-3) !default;
$navbar-light-icon-color: rgba($body-color, .75) !default;
$navbar-light-toggler-icon-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'><path stroke='#{$navbar-light-icon-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>") !default;
$navbar-light-toggler-border-color: rgba(var(--#{$prefix}emphasis-color-rgb), .15) !default;
.navbar-nav {
// scss-docs-start navbar-nav-css-vars
- --#{$prefix}nav-link-padding-x: 0;
+ // --#{$prefix}nav-link-padding-x: 0;
// @mdo-do: fix this, navbar shouldn't need to reuse nav link variables mb? or we need to bring them in…
// --#{$prefix}nav-link-padding-y: #{$nav-link-padding-y};
// @include rfs($nav-link-font-size, --#{$prefix}nav-link-font-size);
}
}
- .dropdown-menu {
- position: static;
- }
+ // .dropdown-menu {
+ // position: static;
+ // }
}
justify-content: flex-start;
.navbar-nav {
+ --#{$prefix}nav-link-padding-x: var(--#{$prefix}navbar-nav-link-padding-x);
flex-direction: row;
- .dropdown-menu {
- position: absolute;
- }
+ // .dropdown-menu {
+ // position: absolute;
+ // }
- .nav-link {
- padding-inline: var(--#{$prefix}navbar-nav-link-padding-x);
- }
+ // .nav-link {
+ // padding-inline: var(--#{$prefix}navbar-nav-link-padding-x);
+ // }
}
.navbar-nav-scroll {
Here’s an example of all the sub-components included in a responsive light-themed navbar that automatically collapses at the `lg` (large) breakpoint.
-<Example code={`<nav class="navbar navbar-expand-lg bg-body-tertiary">
+<Example code={`<nav class="navbar navbar-expand-lg">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
- <ul class="navbar-nav me-auto mb-2 mb-lg-0">
+ <ul class="nav navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
</ul>
<form class="d-flex" role="search">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search"/>
- <button class="btn btn-outline-success" type="submit">Search</button>
+ <button class="btn btn-subtle theme-primary" type="submit">Search</button>
</form>
</div>
</div>
---
title: Navs and tabs
-description: Documentation and examples for how to use Bootstrap’s included navigation components.
+description: Add lists of links to your pages with Bootstrap’s nav components and JavaScript-powered tabs.
aliases: "/docs/[[config:docs_version]]/components/navs/"
toc: true
---
The base `.nav` component is built with flexbox and provide a strong foundation for building all types of navigation components. It includes some style overrides (for working with lists), some link padding for larger hit areas, and basic disabled styling.
<Callout>
-The base `.nav` component does not include any `.active` state. The following examples include the class, mainly to demonstrate that this particular class does not trigger any special styling.
-
To convey the active state to assistive technologies, use the `aria-current` attribute — using the `page` value for current page, or `true` for the current item in a set.
</Callout>
Change the style of `.nav`s component with modifiers and utilities. Mix and match as needed, or build your own.
-### Horizontal alignment
-
-Change the horizontal alignment of your nav with [flexbox utilities]([[docsref:/utilities/flex#justify-content]]). By default, navs are left-aligned, but you can easily change them to center or right-aligned.
+### Tabs
-Centered with `.justify-content-center`:
+Takes the basic nav from above and adds the `.nav-tabs` class to generate a tabbed interface. Use them to create tabbable regions with our [tab JavaScript plugin](#javascript-behavior).
-<Example code={`<ul class="nav justify-content-center">
+<Example code={`<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Active</a>
</li>
</li>
</ul>`} />
-Right-aligned with `.justify-content-end`:
+### Pills
-<Example code={`<ul class="nav justify-content-end">
+Take that same HTML, but use `.nav-pills` instead for a more themed appearance.
+
+<Example code={`<ul class="nav nav-pills">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Active</a>
</li>
</li>
</ul>`} />
-### Vertical
+### Underline
-Stack your navigation by changing the flex item direction with the `.flex-column` utility. Need to stack them on some viewports but not others? Use the responsive versions (e.g., `.flex-sm-column`).
+Take that same HTML, but use `.nav-underline` instead:
-<Example code={`<ul class="nav flex-column">
+<Example code={`<ul class="nav nav-underline">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Active</a>
</li>
</li>
</ul>`} />
-As always, vertical navigation is possible without `<ul>`s, too.
+## Alignment
-<Example code={`<nav class="nav flex-column">
- <a class="nav-link active" aria-current="page" href="#">Active</a>
- <a class="nav-link" href="#">Link</a>
- <a class="nav-link" href="#">Link</a>
- <a class="nav-link disabled" aria-disabled="true">Disabled</a>
- </nav>`} />
+Change the alignment of your nav with [flexbox utilities]([[docsref:/utilities/flex]]). By default, navs are horizontal and left-aligned, but you can easily modify them to center or right-aligned, and even stacked vertically.
-### Tabs
+### Horizontal
-Takes the basic nav from above and adds the `.nav-tabs` class to generate a tabbed interface. Use them to create tabbable regions with our [tab JavaScript plugin](#javascript-behavior).
+Centered with `.justify-content-center`:
-<Example code={`<ul class="nav nav-tabs">
+<Example code={`<ul class="nav justify-content-center">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Active</a>
</li>
</li>
</ul>`} />
-### Pills
-
-Take that same HTML, but use `.nav-pills` instead:
+Right-aligned with `.justify-content-end`:
-<Example code={`<ul class="nav nav-pills">
+<Example code={`<ul class="nav justify-content-end">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Active</a>
</li>
</li>
</ul>`} />
-### Underline
+### Vertical
-Take that same HTML, but use `.nav-underline` instead:
+Stack your navigation by changing the flex item direction with the `.flex-column` utility. Need to stack them on some viewports but not others? Use the responsive versions (e.g., `.flex-sm-column`).
-<Example code={`<ul class="nav nav-underline">
+<Example code={`<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Active</a>
</li>
</li>
</ul>`} />
+As always, vertical navigation is possible without `<ul>`s, too.
+
+<Example code={`<nav class="nav flex-column">
+ <a class="nav-link active" aria-current="page" href="#">Active</a>
+ <a class="nav-link" href="#">Link</a>
+ <a class="nav-link" href="#">Link</a>
+ <a class="nav-link disabled" aria-disabled="true">Disabled</a>
+ </nav>`} />
+
### Fill and justify
Force your `.nav`’s contents to extend the full available width with one of two modifier classes. To proportionately fill all available space with your `.nav-item`s, use `.nav-fill`. Notice that all horizontal space is occupied, but not every nav item has the same width.