blob: cef6200249f99d80844643fa127a4286ed40c961 [file] [edit]
@use "config" as *;
@use "functions" as *;
@use "layout/breakpoints" as *;
@use "mixins/box-shadow" as *;
@use "mixins/mask-icon" as *;
@use "mixins/tokens" as *;
@use "mixins/transition" as *;
// stylelint-disable custom-property-no-missing-var-function
// scss-docs-start navbar-breakpoints
$navbar-breakpoints: $breakpoints !default;
// scss-docs-end navbar-breakpoints
$navbar-tokens: () !default;
$navbar-dark-tokens: () !default;
$navbar-nav-tokens: () !default;
// scss-docs-start navbar-tokens
// stylelint-disable-next-line scss/dollar-variable-default
$navbar-tokens: defaults(
(
--navbar-padding-x: 0,
--navbar-padding-y: .5rem,
--navbar-min-height: 3.5rem,
--navbar-color: var(--fg-2),
--navbar-hover-color: var(--fg-1),
--navbar-disabled-color: var(--fg-3),
--navbar-active-color: var(--fg-body),
--navbar-brand-padding-y: .375rem, // Match nav link padding-y
--navbar-brand-margin-end: 1rem,
--navbar-brand-font-size: var(--font-size-md),
--navbar-brand-font-weight: var(--font-weight-medium),
--navbar-brand-color: var(--fg-body),
--navbar-brand-hover-color: var(--fg-body),
--navbar-nav-link-padding-x: .75rem,
--navbar-toggler-width: 2rem,
--navbar-toggler-padding-y: .25rem,
--navbar-toggler-padding-x: .75rem,
--navbar-toggler-font-size: var(--font-size-lg),
--navbar-toggler-border-color: color-mix(in oklch, var(--fg-body) 15%, transparent),
--navbar-toggler-border-radius: var(--radius-5),
--navbar-toggler-transition: box-shadow .15s ease-in-out,
--navbar-toggler-icon-size: 1.25rem,
--navbar-toggler-icon: #{escape-svg(url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path stroke='black' stroke-linecap='round' stroke-width='1' d='M1 3.5h14M1 8h14M1 12.5h14'/></svg>"))},
),
$navbar-tokens
);
// scss-docs-end navbar-tokens
// scss-docs-start navbar-dark-tokens
// stylelint-disable-next-line scss/dollar-variable-default
$navbar-dark-tokens: defaults(
(
--navbar-color: color-mix(in oklch, var(--white) .55, transparent),
--navbar-hover-color: color-mix(in oklch, var(--white) .75, transparent),
--navbar-disabled-color: color-mix(in oklch, var(--white) .25, transparent),
--navbar-active-color: var(--white),
--navbar-brand-color: var(--white),
--navbar-brand-hover-color: var(--white),
--navbar-toggler-border-color: color-mix(in oklch, var(--white) .1, transparent),
),
$navbar-dark-tokens
);
// scss-docs-end navbar-dark-tokens
// scss-docs-start navbar-nav-tokens
// stylelint-disable-next-line scss/dollar-variable-default
$navbar-nav-tokens: defaults(
(
--nav-gap: .25rem,
--nav-link-gap: .5rem,
--nav-link-padding-x: .5rem,
--nav-link-padding-y: .375rem,
--nav-link-color: var(--navbar-color),
--nav-link-border-width: var(--border-width),
//--nav-link-border-color: var(--border-color),
--nav-link-hover-color: var(--navbar-hover-color),
--nav-link-hover-bg: transparent,
--nav-link-active-color: var(--navbar-active-color),
--nav-link-active-bg: transparent,
--nav-link-disabled-color: var(--navbar-disabled-color),
),
$navbar-nav-tokens
);
// scss-docs-end navbar-nav-tokens
// stylelint-enable custom-property-no-missing-var-function
@layer components {
// Base navbar
.navbar {
@include tokens($navbar-tokens);
position: relative;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
min-height: var(--navbar-min-height);
padding: var(--navbar-padding-y) var(--navbar-padding-x);
@include set-container();
color: var(--navbar-color, var(--fg-body));
background-color: var(--navbar-bg, var(--bg-body));
// @include gradient-bg(var(--navbar-bg, var(--bg-body)));
// Container properties for nested containers
%container-flex-properties {
display: flex;
flex-wrap: inherit;
align-items: center;
justify-content: space-between;
}
> .container,
> .container-fluid {
@extend %container-flex-properties;
}
@each $breakpoint, $container-max-width in $container-max-widths {
> .#{breakpoint-prefix($breakpoint, $container-max-widths)}container {
@extend %container-flex-properties;
}
}
}
// Navbar brand
//
// Used for brand, project, or site names.
.navbar-brand {
padding-top: var(--navbar-brand-padding-y);
padding-bottom: var(--navbar-brand-padding-y);
margin-inline-end: var(--navbar-brand-margin-end);
font-size: var(--navbar-brand-font-size);
font-weight: var(--navbar-brand-font-weight);
color: var(--theme-fg, var(--navbar-brand-color));
text-decoration: none;
white-space: nowrap;
&:hover,
&:focus {
color: var(--theme-fg-emphasis, var(--navbar-brand-hover-color));
}
}
// Navigation within navbars. Sets all nav-link CSS variables needed for
// proper styling.
//
// Relies on `.nav` base class.
.navbar-nav {
@include tokens($navbar-nav-tokens);
display: flex;
flex-direction: column;
gap: var(--nav-gap);
padding-inline-start: 0;
margin-bottom: 0;
list-style-type: "";
.nav-link {
&.active,
&.show {
color: var(--theme-fg, var(--navbar-active-color));
border: var(--nav-link-border-width) solid var(--nav-link-border-color, transparent);
}
}
}
// Navbar text
//
// For adding text or inline elements to the navbar
.navbar-text {
padding-top: var(--navbar-brand-padding-y);
padding-bottom: var(--navbar-brand-padding-y);
color: var(--navbar-color);
a,
a:hover,
a:focus {
color: var(--theme-fg, var(--navbar-active-color));
}
}
// Button for toggling the navbar when in its collapsed state
.navbar-toggler {
--btn-bg: transparent;
--btn-hover-bg: var(--bg-2);
@include transition(var(--navbar-toggler-transition));
}
// Hamburger icon, rendered via CSS mask so it inherits the navbar color
.navbar-toggler-icon {
display: inline-block;
width: var(--navbar-toggler-icon-size);
height: var(--navbar-toggler-icon-size);
background-color: currentcolor;
@include mask-icon(var(--navbar-toggler-icon));
}
// scss-docs-start navbar-expand-loop
// 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
> .container,
> .container-fluid,
%navbar-expand-container {
flex-wrap: nowrap;
justify-content: flex-start;
}
.navbar-nav {
--nav-link-padding-x: var(--navbar-nav-link-padding-x);
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;
overflow: visible !important;
visibility: visible !important;
background-color: transparent !important;
border: 0 !important;
transform: none !important;
@include box-shadow(none);
@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();
}
}
}
}
// scss-docs-end navbar-expand-loop
// Prevent drawer flash on breakpoint crossing.
// When the navbar crosses from expanded (inline) to collapsed (drawer),
// the drawer transitions from visibility:visible to visibility:hidden.
// Without this override, the slide transition plays — briefly showing the
// panel sliding away. Disabling transitions when not [open] ensures only
// intentional show/hide actions animate.
// stylelint-disable-next-line no-duplicate-selectors
.navbar {
[class*="drawer"]:not([open], .hiding) {
@include transition(none !important);
}
}
.navbar-translucent {
position: relative;
background-color: transparent;
&::before {
position: absolute;
inset: 0;
z-index: -1;
content: "";
background-color: color-mix(in oklch, var(--navbar-bg, var(--bg-body)) 80%, transparent);
background-image: none;
backdrop-filter: blur(5px) saturate(180%);
}
}
.navbar[data-bs-theme="dark"] {
@include tokens($navbar-dark-tokens);
}
}