Implement CSS layers

Rearrange and comment import stack

Move content stylesheets to new folder
This commit is contained in:
Mark Otto 2025-02-19 23:08:52 -08:00
parent d36b7d5dfc
commit 4d08a84eb1
57 changed files with 5000 additions and 4888 deletions

View File

@ -10,153 +10,154 @@
// //
// Base styles // Base styles
// //
@layer components {
.accordion { .accordion {
// scss-docs-start accordion-css-vars // scss-docs-start accordion-css-vars
--#{$prefix}accordion-color: #{$accordion-color}; --#{$prefix}accordion-color: #{$accordion-color};
--#{$prefix}accordion-bg: #{$accordion-bg}; --#{$prefix}accordion-bg: #{$accordion-bg};
--#{$prefix}accordion-transition: #{$accordion-transition}; --#{$prefix}accordion-transition: #{$accordion-transition};
--#{$prefix}accordion-border-color: #{$accordion-border-color}; --#{$prefix}accordion-border-color: #{$accordion-border-color};
--#{$prefix}accordion-border-width: #{$accordion-border-width}; --#{$prefix}accordion-border-width: #{$accordion-border-width};
--#{$prefix}accordion-border-radius: #{$accordion-border-radius}; --#{$prefix}accordion-border-radius: #{$accordion-border-radius};
--#{$prefix}accordion-inner-border-radius: #{$accordion-inner-border-radius}; --#{$prefix}accordion-inner-border-radius: #{$accordion-inner-border-radius};
--#{$prefix}accordion-btn-padding-x: #{$accordion-button-padding-x}; --#{$prefix}accordion-btn-padding-x: #{$accordion-button-padding-x};
--#{$prefix}accordion-btn-padding-y: #{$accordion-button-padding-y}; --#{$prefix}accordion-btn-padding-y: #{$accordion-button-padding-y};
--#{$prefix}accordion-btn-color: #{$accordion-button-color}; --#{$prefix}accordion-btn-color: #{$accordion-button-color};
--#{$prefix}accordion-btn-bg: #{$accordion-button-bg}; --#{$prefix}accordion-btn-bg: #{$accordion-button-bg};
--#{$prefix}accordion-btn-icon: #{escape-svg($accordion-button-icon)}; --#{$prefix}accordion-btn-icon: #{escape-svg($accordion-button-icon)};
--#{$prefix}accordion-btn-icon-width: #{$accordion-icon-width}; --#{$prefix}accordion-btn-icon-width: #{$accordion-icon-width};
--#{$prefix}accordion-btn-icon-transform: #{$accordion-icon-transform}; --#{$prefix}accordion-btn-icon-transform: #{$accordion-icon-transform};
--#{$prefix}accordion-btn-icon-transition: #{$accordion-icon-transition}; --#{$prefix}accordion-btn-icon-transition: #{$accordion-icon-transition};
--#{$prefix}accordion-btn-active-icon: #{escape-svg($accordion-button-active-icon)}; --#{$prefix}accordion-btn-active-icon: #{escape-svg($accordion-button-active-icon)};
--#{$prefix}accordion-btn-focus-box-shadow: #{$accordion-button-focus-box-shadow}; --#{$prefix}accordion-btn-focus-box-shadow: #{$accordion-button-focus-box-shadow};
--#{$prefix}accordion-body-padding-x: #{$accordion-body-padding-x}; --#{$prefix}accordion-body-padding-x: #{$accordion-body-padding-x};
--#{$prefix}accordion-body-padding-y: #{$accordion-body-padding-y}; --#{$prefix}accordion-body-padding-y: #{$accordion-body-padding-y};
--#{$prefix}accordion-active-color: #{$accordion-button-active-color}; --#{$prefix}accordion-active-color: #{$accordion-button-active-color};
--#{$prefix}accordion-active-bg: #{$accordion-button-active-bg}; --#{$prefix}accordion-active-bg: #{$accordion-button-active-bg};
// scss-docs-end accordion-css-vars // scss-docs-end accordion-css-vars
}
.accordion-button {
position: relative;
display: flex;
align-items: center;
width: 100%;
padding: var(--#{$prefix}accordion-btn-padding-y) var(--#{$prefix}accordion-btn-padding-x);
@include font-size($font-size-base);
color: var(--#{$prefix}accordion-btn-color);
text-align: left; // Reset button style
background-color: var(--#{$prefix}accordion-btn-bg);
border: 0;
@include border-radius(0);
overflow-anchor: none;
@include transition(var(--#{$prefix}accordion-transition));
&:not(.collapsed) {
color: var(--#{$prefix}accordion-active-color);
background-color: var(--#{$prefix}accordion-active-bg);
box-shadow: inset 0 calc(-1 * var(--#{$prefix}accordion-border-width)) 0 var(--#{$prefix}accordion-border-color); // stylelint-disable-line function-disallowed-list
&::after {
background-image: var(--#{$prefix}accordion-btn-active-icon);
transform: var(--#{$prefix}accordion-btn-icon-transform);
}
} }
// Accordion icon .accordion-button {
&::after { position: relative;
flex-shrink: 0; display: flex;
width: var(--#{$prefix}accordion-btn-icon-width); align-items: center;
height: var(--#{$prefix}accordion-btn-icon-width); width: 100%;
margin-left: auto; padding: var(--#{$prefix}accordion-btn-padding-y) var(--#{$prefix}accordion-btn-padding-x);
content: ""; @include font-size($font-size-base);
background-image: var(--#{$prefix}accordion-btn-icon); color: var(--#{$prefix}accordion-btn-color);
background-repeat: no-repeat; text-align: left; // Reset button style
background-size: var(--#{$prefix}accordion-btn-icon-width); background-color: var(--#{$prefix}accordion-btn-bg);
@include transition(var(--#{$prefix}accordion-btn-icon-transition)); border: 0;
} @include border-radius(0);
overflow-anchor: none;
@include transition(var(--#{$prefix}accordion-transition));
&:hover { &:not(.collapsed) {
z-index: 2; color: var(--#{$prefix}accordion-active-color);
} background-color: var(--#{$prefix}accordion-active-bg);
box-shadow: inset 0 calc(-1 * var(--#{$prefix}accordion-border-width)) 0 var(--#{$prefix}accordion-border-color); // stylelint-disable-line function-disallowed-list
&:focus { &::after {
z-index: 3; background-image: var(--#{$prefix}accordion-btn-active-icon);
outline: 0; transform: var(--#{$prefix}accordion-btn-icon-transform);
box-shadow: var(--#{$prefix}accordion-btn-focus-box-shadow);
}
}
.accordion-header {
margin-bottom: 0;
}
.accordion-item {
color: var(--#{$prefix}accordion-color);
background-color: var(--#{$prefix}accordion-bg);
border: var(--#{$prefix}accordion-border-width) solid var(--#{$prefix}accordion-border-color);
&:first-of-type {
@include border-top-radius(var(--#{$prefix}accordion-border-radius));
> .accordion-header .accordion-button {
@include border-top-radius(var(--#{$prefix}accordion-inner-border-radius));
}
}
&:not(:first-of-type) {
border-top: 0;
}
// Only set a border-radius on the last item if the accordion is collapsed
&:last-of-type {
@include border-bottom-radius(var(--#{$prefix}accordion-border-radius));
> .accordion-header .accordion-button {
&.collapsed {
@include border-bottom-radius(var(--#{$prefix}accordion-inner-border-radius));
} }
} }
> .accordion-collapse { // Accordion icon
&::after {
flex-shrink: 0;
width: var(--#{$prefix}accordion-btn-icon-width);
height: var(--#{$prefix}accordion-btn-icon-width);
margin-left: auto;
content: "";
background-image: var(--#{$prefix}accordion-btn-icon);
background-repeat: no-repeat;
background-size: var(--#{$prefix}accordion-btn-icon-width);
@include transition(var(--#{$prefix}accordion-btn-icon-transition));
}
&:hover {
z-index: 2;
}
&:focus {
z-index: 3;
outline: 0;
box-shadow: var(--#{$prefix}accordion-btn-focus-box-shadow);
}
}
.accordion-header {
margin-bottom: 0;
}
.accordion-item {
color: var(--#{$prefix}accordion-color);
background-color: var(--#{$prefix}accordion-bg);
border: var(--#{$prefix}accordion-border-width) solid var(--#{$prefix}accordion-border-color);
&:first-of-type {
@include border-top-radius(var(--#{$prefix}accordion-border-radius));
> .accordion-header .accordion-button {
@include border-top-radius(var(--#{$prefix}accordion-inner-border-radius));
}
}
&:not(:first-of-type) {
border-top: 0;
}
// Only set a border-radius on the last item if the accordion is collapsed
&:last-of-type {
@include border-bottom-radius(var(--#{$prefix}accordion-border-radius)); @include border-bottom-radius(var(--#{$prefix}accordion-border-radius));
> .accordion-header .accordion-button {
&.collapsed {
@include border-bottom-radius(var(--#{$prefix}accordion-inner-border-radius));
}
}
> .accordion-collapse {
@include border-bottom-radius(var(--#{$prefix}accordion-border-radius));
}
} }
} }
}
.accordion-body { .accordion-body {
padding: var(--#{$prefix}accordion-body-padding-y) var(--#{$prefix}accordion-body-padding-x); padding: var(--#{$prefix}accordion-body-padding-y) var(--#{$prefix}accordion-body-padding-x);
} }
// Flush accordion items // Flush accordion items
// //
// Remove borders and border-radius to keep accordion items edge-to-edge. // Remove borders and border-radius to keep accordion items edge-to-edge.
.accordion-flush { .accordion-flush {
> .accordion-item { > .accordion-item {
border-right: 0; border-right: 0;
border-left: 0; border-left: 0;
@include border-radius(0);
&:first-child { border-top: 0; }
&:last-child { border-bottom: 0; }
// stylelint-disable selector-max-class
> .accordion-collapse,
> .accordion-header .accordion-button,
> .accordion-header .accordion-button.collapsed {
@include border-radius(0); @include border-radius(0);
}
// stylelint-enable selector-max-class
}
}
@if $enable-dark-mode { &:first-child { border-top: 0; }
@include color-mode(dark) { &:last-child { border-bottom: 0; }
.accordion-button::after {
--#{$prefix}accordion-btn-icon: #{escape-svg($accordion-button-icon-dark)}; // stylelint-disable selector-max-class
--#{$prefix}accordion-btn-active-icon: #{escape-svg($accordion-button-active-icon-dark)}; > .accordion-collapse,
> .accordion-header .accordion-button,
> .accordion-header .accordion-button.collapsed {
@include border-radius(0);
}
// stylelint-enable selector-max-class
}
}
@if $enable-dark-mode {
@include color-mode(dark) {
.accordion-button::after {
--#{$prefix}accordion-btn-icon: #{escape-svg($accordion-button-icon-dark)};
--#{$prefix}accordion-btn-active-icon: #{escape-svg($accordion-button-active-icon-dark)};
}
} }
} }
} }

View File

@ -7,67 +7,69 @@
// Base styles // Base styles
// //
.alert { @layer components {
// scss-docs-start alert-css-vars .alert {
--#{$prefix}alert-bg: transparent; // scss-docs-start alert-css-vars
--#{$prefix}alert-padding-x: #{$alert-padding-x}; --#{$prefix}alert-bg: transparent;
--#{$prefix}alert-padding-y: #{$alert-padding-y}; --#{$prefix}alert-padding-x: #{$alert-padding-x};
--#{$prefix}alert-margin-bottom: #{$alert-margin-bottom}; --#{$prefix}alert-padding-y: #{$alert-padding-y};
--#{$prefix}alert-color: inherit; --#{$prefix}alert-margin-bottom: #{$alert-margin-bottom};
--#{$prefix}alert-border-color: transparent; --#{$prefix}alert-color: inherit;
--#{$prefix}alert-border: #{$alert-border-width} solid var(--#{$prefix}alert-border-color); --#{$prefix}alert-border-color: transparent;
--#{$prefix}alert-border-radius: #{$alert-border-radius}; --#{$prefix}alert-border: #{$alert-border-width} solid var(--#{$prefix}alert-border-color);
--#{$prefix}alert-link-color: inherit; --#{$prefix}alert-border-radius: #{$alert-border-radius};
// scss-docs-end alert-css-vars --#{$prefix}alert-link-color: inherit;
// scss-docs-end alert-css-vars
position: relative; position: relative;
padding: var(--#{$prefix}alert-padding-y) var(--#{$prefix}alert-padding-x); padding: var(--#{$prefix}alert-padding-y) var(--#{$prefix}alert-padding-x);
margin-bottom: var(--#{$prefix}alert-margin-bottom); margin-bottom: var(--#{$prefix}alert-margin-bottom);
color: var(--#{$prefix}alert-color); color: var(--#{$prefix}alert-color);
background-color: var(--#{$prefix}alert-bg); background-color: var(--#{$prefix}alert-bg);
border: var(--#{$prefix}alert-border); border: var(--#{$prefix}alert-border);
@include border-radius(var(--#{$prefix}alert-border-radius)); @include border-radius(var(--#{$prefix}alert-border-radius));
}
// Headings for larger alerts
.alert-heading {
// Specified to prevent conflicts of changing $headings-color
color: inherit;
}
// Provide class for links that match alerts
.alert-link {
font-weight: $alert-link-font-weight;
color: var(--#{$prefix}alert-link-color);
}
// Dismissible alerts
//
// Expand the right padding and account for the close button's positioning.
.alert-dismissible {
padding-right: $alert-dismissible-padding-r;
// Adjust close link position
.btn-close {
position: absolute;
top: 0;
right: 0;
z-index: $stretched-link-z-index + 1;
padding: $alert-padding-y * 1.25 $alert-padding-x;
} }
}
// Headings for larger alerts
// scss-docs-start alert-modifiers .alert-heading {
// Generate contextual modifier classes for colorizing the alert // Specified to prevent conflicts of changing $headings-color
@each $state in map.keys($theme-colors) { color: inherit;
.alert-#{$state} {
--#{$prefix}alert-color: var(--#{$prefix}#{$state}-text-emphasis);
--#{$prefix}alert-bg: var(--#{$prefix}#{$state}-bg-subtle);
--#{$prefix}alert-border-color: var(--#{$prefix}#{$state}-border-subtle);
--#{$prefix}alert-link-color: var(--#{$prefix}#{$state}-text-emphasis);
} }
// Provide class for links that match alerts
.alert-link {
font-weight: $alert-link-font-weight;
color: var(--#{$prefix}alert-link-color);
}
// Dismissible alerts
//
// Expand the right padding and account for the close button's positioning.
.alert-dismissible {
padding-right: $alert-dismissible-padding-r;
// Adjust close link position
.btn-close {
position: absolute;
top: 0;
right: 0;
z-index: $stretched-link-z-index + 1;
padding: $alert-padding-y * 1.25 $alert-padding-x;
}
}
// scss-docs-start alert-modifiers
// Generate contextual modifier classes for colorizing the alert
@each $state in map.keys($theme-colors) {
.alert-#{$state} {
--#{$prefix}alert-color: var(--#{$prefix}#{$state}-text-emphasis);
--#{$prefix}alert-bg: var(--#{$prefix}#{$state}-bg-subtle);
--#{$prefix}alert-border-color: var(--#{$prefix}#{$state}-border-subtle);
--#{$prefix}alert-link-color: var(--#{$prefix}#{$state}-text-emphasis);
}
}
// scss-docs-end alert-modifiers
} }
// scss-docs-end alert-modifiers

View File

@ -9,36 +9,38 @@
// Requires one of the contextual, color modifier classes for `color` and // Requires one of the contextual, color modifier classes for `color` and
// `background-color`. // `background-color`.
.badge { @layer components {
// scss-docs-start badge-css-vars .badge {
--#{$prefix}badge-padding-x: #{$badge-padding-x}; // scss-docs-start badge-css-vars
--#{$prefix}badge-padding-y: #{$badge-padding-y}; --#{$prefix}badge-padding-x: #{$badge-padding-x};
@include rfs($badge-font-size, --#{$prefix}badge-font-size); --#{$prefix}badge-padding-y: #{$badge-padding-y};
--#{$prefix}badge-font-weight: #{$badge-font-weight}; @include rfs($badge-font-size, --#{$prefix}badge-font-size);
--#{$prefix}badge-color: #{$badge-color}; --#{$prefix}badge-font-weight: #{$badge-font-weight};
--#{$prefix}badge-border-radius: #{$badge-border-radius}; --#{$prefix}badge-color: #{$badge-color};
// scss-docs-end badge-css-vars --#{$prefix}badge-border-radius: #{$badge-border-radius};
// scss-docs-end badge-css-vars
display: inline-block; display: inline-block;
padding: var(--#{$prefix}badge-padding-y) var(--#{$prefix}badge-padding-x); padding: var(--#{$prefix}badge-padding-y) var(--#{$prefix}badge-padding-x);
@include font-size(var(--#{$prefix}badge-font-size)); @include font-size(var(--#{$prefix}badge-font-size));
font-weight: var(--#{$prefix}badge-font-weight); font-weight: var(--#{$prefix}badge-font-weight);
line-height: 1; line-height: 1;
color: var(--#{$prefix}badge-color); color: var(--#{$prefix}badge-color);
text-align: center; text-align: center;
white-space: nowrap; white-space: nowrap;
vertical-align: baseline; vertical-align: baseline;
@include border-radius(var(--#{$prefix}badge-border-radius)); @include border-radius(var(--#{$prefix}badge-border-radius));
@include gradient-bg(); @include gradient-bg();
// Empty badges collapse automatically // Empty badges collapse automatically
&:empty { &:empty {
display: none; display: none;
}
}
// Quick fix for badges in buttons
.btn .badge {
position: relative;
top: -1px;
} }
} }
// Quick fix for badges in buttons
.btn .badge {
position: relative;
top: -1px;
}

View File

@ -3,43 +3,45 @@
@use "mixins/border-radius" as *; @use "mixins/border-radius" as *;
@use "vendor/rfs" as *; @use "vendor/rfs" as *;
.breadcrumb { @layer components {
// scss-docs-start breadcrumb-css-vars .breadcrumb {
--#{$prefix}breadcrumb-padding-x: #{$breadcrumb-padding-x}; // scss-docs-start breadcrumb-css-vars
--#{$prefix}breadcrumb-padding-y: #{$breadcrumb-padding-y}; --#{$prefix}breadcrumb-padding-x: #{$breadcrumb-padding-x};
--#{$prefix}breadcrumb-margin-bottom: #{$breadcrumb-margin-bottom}; --#{$prefix}breadcrumb-padding-y: #{$breadcrumb-padding-y};
@include rfs($breadcrumb-font-size, --#{$prefix}breadcrumb-font-size); --#{$prefix}breadcrumb-margin-bottom: #{$breadcrumb-margin-bottom};
--#{$prefix}breadcrumb-bg: #{$breadcrumb-bg}; @include rfs($breadcrumb-font-size, --#{$prefix}breadcrumb-font-size);
--#{$prefix}breadcrumb-border-radius: #{$breadcrumb-border-radius}; --#{$prefix}breadcrumb-bg: #{$breadcrumb-bg};
--#{$prefix}breadcrumb-divider-color: #{$breadcrumb-divider-color}; --#{$prefix}breadcrumb-border-radius: #{$breadcrumb-border-radius};
--#{$prefix}breadcrumb-item-padding-x: #{$breadcrumb-item-padding-x}; --#{$prefix}breadcrumb-divider-color: #{$breadcrumb-divider-color};
--#{$prefix}breadcrumb-item-active-color: #{$breadcrumb-active-color}; --#{$prefix}breadcrumb-item-padding-x: #{$breadcrumb-item-padding-x};
// scss-docs-end breadcrumb-css-vars --#{$prefix}breadcrumb-item-active-color: #{$breadcrumb-active-color};
// scss-docs-end breadcrumb-css-vars
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
padding: var(--#{$prefix}breadcrumb-padding-y) var(--#{$prefix}breadcrumb-padding-x); padding: var(--#{$prefix}breadcrumb-padding-y) var(--#{$prefix}breadcrumb-padding-x);
margin-bottom: var(--#{$prefix}breadcrumb-margin-bottom); margin-bottom: var(--#{$prefix}breadcrumb-margin-bottom);
@include font-size(var(--#{$prefix}breadcrumb-font-size)); @include font-size(var(--#{$prefix}breadcrumb-font-size));
list-style: none; list-style: none;
background-color: var(--#{$prefix}breadcrumb-bg); background-color: var(--#{$prefix}breadcrumb-bg);
@include border-radius(var(--#{$prefix}breadcrumb-border-radius)); @include border-radius(var(--#{$prefix}breadcrumb-border-radius));
} }
.breadcrumb-item { .breadcrumb-item {
// The separator between breadcrumbs (by default, a forward-slash: "/") // The separator between breadcrumbs (by default, a forward-slash: "/")
+ .breadcrumb-item { + .breadcrumb-item {
padding-left: var(--#{$prefix}breadcrumb-item-padding-x); padding-left: var(--#{$prefix}breadcrumb-item-padding-x);
&::before { &::before {
float: left; // Suppress inline spacings and underlining of the separator float: left; // Suppress inline spacings and underlining of the separator
padding-right: var(--#{$prefix}breadcrumb-item-padding-x); padding-right: var(--#{$prefix}breadcrumb-item-padding-x);
color: var(--#{$prefix}breadcrumb-divider-color); color: var(--#{$prefix}breadcrumb-divider-color);
content: var(--#{$prefix}breadcrumb-divider, escape-svg($breadcrumb-divider)) #{"/* rtl:"} var(--#{$prefix}breadcrumb-divider, escape-svg($breadcrumb-divider-flipped)) #{"*/"}; content: var(--#{$prefix}breadcrumb-divider, escape-svg($breadcrumb-divider)) #{"/* rtl:"} var(--#{$prefix}breadcrumb-divider, escape-svg($breadcrumb-divider-flipped)) #{"*/"};
}
}
&.active {
color: var(--#{$prefix}breadcrumb-item-active-color);
} }
} }
&.active {
color: var(--#{$prefix}breadcrumb-item-active-color);
}
} }

View File

@ -3,150 +3,152 @@
@use "mixins/border-radius" as *; @use "mixins/border-radius" as *;
@use "mixins/box-shadow" as *; @use "mixins/box-shadow" as *;
// Make the div behave like a button @layer components {
.btn-group, // Make the div behave like a button
.btn-group-vertical { .btn-group,
position: relative; .btn-group-vertical {
display: inline-flex;
vertical-align: middle; // match .btn alignment given font-size hack above
> .btn {
position: relative; position: relative;
flex: 1 1 auto; display: inline-flex;
vertical-align: middle; // match .btn alignment given font-size hack above
> .btn {
position: relative;
flex: 1 1 auto;
}
// Bring the hover, focused, and "active" buttons to the front to overlay
// the borders properly
> .btn-check:checked + .btn,
> .btn-check:focus + .btn,
> .btn:hover,
> .btn:focus,
> .btn:active,
> .btn.active {
z-index: 1;
}
} }
// Bring the hover, focused, and "active" buttons to the front to overlay // Optional: Group multiple button groups together for a toolbar
// the borders properly .btn-toolbar {
> .btn-check:checked + .btn, display: flex;
> .btn-check:focus + .btn, flex-wrap: wrap;
> .btn:hover, justify-content: flex-start;
> .btn:focus,
> .btn:active, .input-group {
> .btn.active { width: auto;
z-index: 1; }
} }
}
.btn-group {
// Optional: Group multiple button groups together for a toolbar @include border-radius($btn-border-radius);
.btn-toolbar {
display: flex; // Prevent double borders when buttons are next to each other
flex-wrap: wrap; > :not(.btn-check:first-child) + .btn,
justify-content: flex-start; > .btn-group:not(:first-child) {
margin-left: calc(-1 * #{$btn-border-width}); // stylelint-disable-line function-disallowed-list
.input-group { }
width: auto;
} // Reset rounded corners
} > .btn:not(:last-child):not(.dropdown-toggle),
> .btn.dropdown-toggle-split:first-child,
.btn-group { > .btn-group:not(:last-child) > .btn {
@include border-radius($btn-border-radius); @include border-end-radius(0);
}
// Prevent double borders when buttons are next to each other
> :not(.btn-check:first-child) + .btn, // The left radius should be 0 if the button is:
> .btn-group:not(:first-child) { // - the "third or more" child
margin-left: calc(-1 * #{$btn-border-width}); // stylelint-disable-line function-disallowed-list // - the second child and the previous element isn't `.btn-check` (making it the first child visually)
} // - part of a btn-group which isn't the first child
> .btn:nth-child(n + 3),
// Reset rounded corners > :not(.btn-check) + .btn,
> .btn:not(:last-child):not(.dropdown-toggle), > .btn-group:not(:first-child) > .btn {
> .btn.dropdown-toggle-split:first-child, @include border-start-radius(0);
> .btn-group:not(:last-child) > .btn { }
@include border-end-radius(0); }
}
// Sizing
// The left radius should be 0 if the button is: //
// - the "third or more" child // Remix the default button sizing classes into new ones for easier manipulation.
// - the second child and the previous element isn't `.btn-check` (making it the first child visually)
// - part of a btn-group which isn't the first child .btn-group-sm > .btn { @extend .btn-sm; }
> .btn:nth-child(n + 3), .btn-group-lg > .btn { @extend .btn-lg; }
> :not(.btn-check) + .btn,
> .btn-group:not(:first-child) > .btn {
@include border-start-radius(0); //
} // Split button dropdowns
} //
// Sizing .dropdown-toggle-split {
// padding-right: $btn-padding-x * .75;
// Remix the default button sizing classes into new ones for easier manipulation. padding-left: $btn-padding-x * .75;
.btn-group-sm > .btn { @extend .btn-sm; } &::after,
.btn-group-lg > .btn { @extend .btn-lg; } .dropup &::after,
.dropend &::after {
margin-left: 0;
// }
// Split button dropdowns
// .dropstart &::before {
margin-right: 0;
.dropdown-toggle-split { }
padding-right: $btn-padding-x * .75; }
padding-left: $btn-padding-x * .75;
.btn-sm + .dropdown-toggle-split {
&::after, padding-right: $btn-padding-x-sm * .75;
.dropup &::after, padding-left: $btn-padding-x-sm * .75;
.dropend &::after { }
margin-left: 0;
} .btn-lg + .dropdown-toggle-split {
padding-right: $btn-padding-x-lg * .75;
.dropstart &::before { padding-left: $btn-padding-x-lg * .75;
margin-right: 0; }
}
}
// The clickable button for toggling the menu
.btn-sm + .dropdown-toggle-split { // Set the same inset shadow as the :active state
padding-right: $btn-padding-x-sm * .75; .btn-group.show .dropdown-toggle {
padding-left: $btn-padding-x-sm * .75; @include box-shadow($btn-active-box-shadow);
}
// Show no shadow for `.btn-link` since it has no other button styles.
.btn-lg + .dropdown-toggle-split { &.btn-link {
padding-right: $btn-padding-x-lg * .75; @include box-shadow(none);
padding-left: $btn-padding-x-lg * .75; }
} }
// The clickable button for toggling the menu //
// Set the same inset shadow as the :active state // Vertical button groups
.btn-group.show .dropdown-toggle { //
@include box-shadow($btn-active-box-shadow);
.btn-group-vertical {
// Show no shadow for `.btn-link` since it has no other button styles. flex-direction: column;
&.btn-link { align-items: flex-start;
@include box-shadow(none); justify-content: center;
}
} > .btn,
> .btn-group {
width: 100%;
// }
// Vertical button groups
// > .btn:not(:first-child),
> .btn-group:not(:first-child) {
.btn-group-vertical { margin-top: calc(-1 * #{$btn-border-width}); // stylelint-disable-line function-disallowed-list
flex-direction: column; }
align-items: flex-start;
justify-content: center; // Reset rounded corners
> .btn:not(:last-child):not(.dropdown-toggle),
> .btn, > .btn-group:not(:last-child) > .btn {
> .btn-group { @include border-bottom-radius(0);
width: 100%; }
}
// The top radius should be 0 if the button is:
> .btn:not(:first-child), // - the "third or more" child
> .btn-group:not(:first-child) { // - the second child and the previous element isn't `.btn-check` (making it the first child visually)
margin-top: calc(-1 * #{$btn-border-width}); // stylelint-disable-line function-disallowed-list // - part of a btn-group which isn't the first child
} > .btn:nth-child(n + 3),
> :not(.btn-check) + .btn,
// Reset rounded corners > .btn-group:not(:first-child) > .btn {
> .btn:not(:last-child):not(.dropdown-toggle), @include border-top-radius(0);
> .btn-group:not(:last-child) > .btn { }
@include border-bottom-radius(0);
}
// The top radius should be 0 if the button is:
// - the "third or more" child
// - the second child and the previous element isn't `.btn-check` (making it the first child visually)
// - part of a btn-group which isn't the first child
> .btn:nth-child(n + 3),
> :not(.btn-check) + .btn,
> .btn-group:not(:first-child) > .btn {
@include border-top-radius(0);
} }
} }

View File

@ -13,166 +13,177 @@
// Easily pump out default styles, as well as :hover, :focus, :active, // Easily pump out default styles, as well as :hover, :focus, :active,
// and disabled options for all buttons // and disabled options for all buttons
// scss-docs-start btn-variant-mixin @layer components {
@mixin button-variant( // scss-docs-start btn-variant-mixin
$background, @mixin button-variant(
$border, $background,
$color: color-contrast($background), $border,
$hover-background: if($color == $color-contrast-light, shade-color($background, $btn-hover-bg-shade-amount), tint-color($background, $btn-hover-bg-tint-amount)), $color: color-contrast($background),
$hover-border: if($color == $color-contrast-light, shade-color($border, $btn-hover-border-shade-amount), tint-color($border, $btn-hover-border-tint-amount)), $hover-background: if($color == $color-contrast-light, shade-color($background, $btn-hover-bg-shade-amount), tint-color($background, $btn-hover-bg-tint-amount)),
$hover-color: color-contrast($hover-background), $hover-border: if($color == $color-contrast-light, shade-color($border, $btn-hover-border-shade-amount), tint-color($border, $btn-hover-border-tint-amount)),
$active-background: if($color == $color-contrast-light, shade-color($background, $btn-active-bg-shade-amount), tint-color($background, $btn-active-bg-tint-amount)), $hover-color: color-contrast($hover-background),
$active-border: if($color == $color-contrast-light, shade-color($border, $btn-active-border-shade-amount), tint-color($border, $btn-active-border-tint-amount)), $active-background: if($color == $color-contrast-light, shade-color($background, $btn-active-bg-shade-amount), tint-color($background, $btn-active-bg-tint-amount)),
$active-color: color-contrast($active-background), $active-border: if($color == $color-contrast-light, shade-color($border, $btn-active-border-shade-amount), tint-color($border, $btn-active-border-tint-amount)),
$disabled-background: $background, $active-color: color-contrast($active-background),
$disabled-border: $border, $disabled-background: $background,
$disabled-color: color-contrast($disabled-background) $disabled-border: $border,
) { $disabled-color: color-contrast($disabled-background)
--#{$prefix}btn-color: #{$color}; ) {
--#{$prefix}btn-bg: #{$background}; --#{$prefix}btn-color: #{$color};
--#{$prefix}btn-border-color: #{$border}; --#{$prefix}btn-bg: #{$background};
--#{$prefix}btn-hover-color: #{$hover-color}; --#{$prefix}btn-border-color: #{$border};
--#{$prefix}btn-hover-bg: #{$hover-background}; --#{$prefix}btn-hover-color: #{$hover-color};
--#{$prefix}btn-hover-border-color: #{$hover-border}; --#{$prefix}btn-hover-bg: #{$hover-background};
--#{$prefix}btn-focus-shadow-rgb: #{to-rgb(mix($color, $border, 15%))}; --#{$prefix}btn-hover-border-color: #{$hover-border};
--#{$prefix}btn-active-color: #{$active-color}; --#{$prefix}btn-focus-shadow-rgb: #{to-rgb(mix($color, $border, 15%))};
--#{$prefix}btn-active-bg: #{$active-background}; --#{$prefix}btn-active-color: #{$active-color};
--#{$prefix}btn-active-border-color: #{$active-border}; --#{$prefix}btn-active-bg: #{$active-background};
--#{$prefix}btn-active-shadow: #{$btn-active-box-shadow}; --#{$prefix}btn-active-border-color: #{$active-border};
--#{$prefix}btn-disabled-color: #{$disabled-color}; --#{$prefix}btn-active-shadow: #{$btn-active-box-shadow};
--#{$prefix}btn-disabled-bg: #{$disabled-background}; --#{$prefix}btn-disabled-color: #{$disabled-color};
--#{$prefix}btn-disabled-border-color: #{$disabled-border}; --#{$prefix}btn-disabled-bg: #{$disabled-background};
} --#{$prefix}btn-disabled-border-color: #{$disabled-border};
// scss-docs-end btn-variant-mixin
// scss-docs-start btn-outline-variant-mixin
@mixin button-outline-variant(
$color,
$color-hover: color-contrast($color),
$active-background: $color,
$active-border: $color,
$active-color: color-contrast($active-background)
) {
--#{$prefix}btn-color: #{$color};
--#{$prefix}btn-border-color: #{$color};
--#{$prefix}btn-hover-color: #{$color-hover};
--#{$prefix}btn-hover-bg: #{$active-background};
--#{$prefix}btn-hover-border-color: #{$active-border};
--#{$prefix}btn-focus-shadow-rgb: #{to-rgb($color)};
--#{$prefix}btn-active-color: #{$active-color};
--#{$prefix}btn-active-bg: #{$active-background};
--#{$prefix}btn-active-border-color: #{$active-border};
--#{$prefix}btn-active-shadow: #{$btn-active-box-shadow};
--#{$prefix}btn-disabled-color: #{$color};
--#{$prefix}btn-disabled-bg: transparent;
--#{$prefix}btn-disabled-border-color: #{$color};
--#{$prefix}gradient: none;
}
// scss-docs-end btn-outline-variant-mixin
// scss-docs-start btn-size-mixin
@mixin button-size($padding-y, $padding-x, $font-size, $border-radius) {
--#{$prefix}btn-padding-y: #{$padding-y};
--#{$prefix}btn-padding-x: #{$padding-x};
@include rfs($font-size, --#{$prefix}btn-font-size);
--#{$prefix}btn-border-radius: #{$border-radius};
}
// scss-docs-end btn-size-mixin
//
// Base styles
//
.btn {
// scss-docs-start btn-css-vars
--#{$prefix}btn-padding-x: #{$btn-padding-x};
--#{$prefix}btn-padding-y: #{$btn-padding-y};
--#{$prefix}btn-font-family: #{$btn-font-family};
@include rfs($btn-font-size, --#{$prefix}btn-font-size);
--#{$prefix}btn-font-weight: #{$btn-font-weight};
--#{$prefix}btn-line-height: #{$btn-line-height};
--#{$prefix}btn-color: #{$btn-color};
--#{$prefix}btn-bg: transparent;
--#{$prefix}btn-border-width: #{$btn-border-width};
--#{$prefix}btn-border-color: transparent;
--#{$prefix}btn-border-radius: #{$btn-border-radius};
--#{$prefix}btn-hover-border-color: transparent;
--#{$prefix}btn-box-shadow: #{$btn-box-shadow};
--#{$prefix}btn-disabled-opacity: #{$btn-disabled-opacity};
--#{$prefix}btn-focus-box-shadow: 0 0 0 #{$btn-focus-width} rgba(var(--#{$prefix}btn-focus-shadow-rgb), .5);
// scss-docs-end btn-css-vars
display: inline-block;
padding: var(--#{$prefix}btn-padding-y) var(--#{$prefix}btn-padding-x);
font-family: var(--#{$prefix}btn-font-family);
@include font-size(var(--#{$prefix}btn-font-size));
font-weight: var(--#{$prefix}btn-font-weight);
line-height: var(--#{$prefix}btn-line-height);
color: var(--#{$prefix}btn-color);
text-align: center;
text-decoration: if($link-decoration == none, null, none);
white-space: $btn-white-space;
vertical-align: middle;
cursor: if($enable-button-pointers, pointer, null);
user-select: none;
border: var(--#{$prefix}btn-border-width) solid var(--#{$prefix}btn-border-color);
@include border-radius(var(--#{$prefix}btn-border-radius));
@include gradient-bg(var(--#{$prefix}btn-bg));
@include box-shadow(var(--#{$prefix}btn-box-shadow));
@include transition($btn-transition);
&:hover {
color: var(--#{$prefix}btn-hover-color);
text-decoration: if($link-hover-decoration == underline, none, null);
background-color: var(--#{$prefix}btn-hover-bg);
border-color: var(--#{$prefix}btn-hover-border-color);
} }
// scss-docs-end btn-variant-mixin
.btn-check + &:hover { // scss-docs-start btn-outline-variant-mixin
// override for the checkbox/radio buttons @mixin button-outline-variant(
$color,
$color-hover: color-contrast($color),
$active-background: $color,
$active-border: $color,
$active-color: color-contrast($active-background)
) {
--#{$prefix}btn-color: #{$color};
--#{$prefix}btn-border-color: #{$color};
--#{$prefix}btn-hover-color: #{$color-hover};
--#{$prefix}btn-hover-bg: #{$active-background};
--#{$prefix}btn-hover-border-color: #{$active-border};
--#{$prefix}btn-focus-shadow-rgb: #{to-rgb($color)};
--#{$prefix}btn-active-color: #{$active-color};
--#{$prefix}btn-active-bg: #{$active-background};
--#{$prefix}btn-active-border-color: #{$active-border};
--#{$prefix}btn-active-shadow: #{$btn-active-box-shadow};
--#{$prefix}btn-disabled-color: #{$color};
--#{$prefix}btn-disabled-bg: transparent;
--#{$prefix}btn-disabled-border-color: #{$color};
--#{$prefix}gradient: none;
}
// scss-docs-end btn-outline-variant-mixin
// scss-docs-start btn-size-mixin
@mixin button-size($padding-y, $padding-x, $font-size, $border-radius) {
--#{$prefix}btn-padding-y: #{$padding-y};
--#{$prefix}btn-padding-x: #{$padding-x};
@include rfs($font-size, --#{$prefix}btn-font-size);
--#{$prefix}btn-border-radius: #{$border-radius};
}
// scss-docs-end btn-size-mixin
//
// Base styles
//
.btn {
// scss-docs-start btn-css-vars
--#{$prefix}btn-padding-x: #{$btn-padding-x};
--#{$prefix}btn-padding-y: #{$btn-padding-y};
--#{$prefix}btn-font-family: #{$btn-font-family};
@include rfs($btn-font-size, --#{$prefix}btn-font-size);
--#{$prefix}btn-font-weight: #{$btn-font-weight};
--#{$prefix}btn-line-height: #{$btn-line-height};
--#{$prefix}btn-color: #{$btn-color};
--#{$prefix}btn-bg: transparent;
--#{$prefix}btn-border-width: #{$btn-border-width};
--#{$prefix}btn-border-color: transparent;
--#{$prefix}btn-border-radius: #{$btn-border-radius};
--#{$prefix}btn-hover-border-color: transparent;
--#{$prefix}btn-box-shadow: #{$btn-box-shadow};
--#{$prefix}btn-disabled-opacity: #{$btn-disabled-opacity};
--#{$prefix}btn-focus-box-shadow: 0 0 0 #{$btn-focus-width} rgba(var(--#{$prefix}btn-focus-shadow-rgb), .5);
// scss-docs-end btn-css-vars
display: inline-block;
padding: var(--#{$prefix}btn-padding-y) var(--#{$prefix}btn-padding-x);
font-family: var(--#{$prefix}btn-font-family);
@include font-size(var(--#{$prefix}btn-font-size));
font-weight: var(--#{$prefix}btn-font-weight);
line-height: var(--#{$prefix}btn-line-height);
color: var(--#{$prefix}btn-color); color: var(--#{$prefix}btn-color);
background-color: var(--#{$prefix}btn-bg); text-align: center;
border-color: var(--#{$prefix}btn-border-color); text-decoration: if($link-decoration == none, null, none);
} white-space: $btn-white-space;
vertical-align: middle;
cursor: if($enable-button-pointers, pointer, null);
user-select: none;
border: var(--#{$prefix}btn-border-width) solid var(--#{$prefix}btn-border-color);
@include border-radius(var(--#{$prefix}btn-border-radius));
@include gradient-bg(var(--#{$prefix}btn-bg));
@include box-shadow(var(--#{$prefix}btn-box-shadow));
@include transition($btn-transition);
&:focus-visible { &:hover {
color: var(--#{$prefix}btn-hover-color); color: var(--#{$prefix}btn-hover-color);
@include gradient-bg(var(--#{$prefix}btn-hover-bg)); text-decoration: if($link-hover-decoration == underline, none, null);
border-color: var(--#{$prefix}btn-hover-border-color); background-color: var(--#{$prefix}btn-hover-bg);
outline: 0; border-color: var(--#{$prefix}btn-hover-border-color);
// Avoid using mixin so we can pass custom focus shadow properly
@if $enable-shadows {
box-shadow: var(--#{$prefix}btn-box-shadow), var(--#{$prefix}btn-focus-box-shadow);
} @else {
box-shadow: var(--#{$prefix}btn-focus-box-shadow);
} }
}
.btn-check:focus-visible + & { .btn-check + &:hover {
border-color: var(--#{$prefix}btn-hover-border-color); // override for the checkbox/radio buttons
outline: 0; color: var(--#{$prefix}btn-color);
// Avoid using mixin so we can pass custom focus shadow properly background-color: var(--#{$prefix}btn-bg);
@if $enable-shadows { border-color: var(--#{$prefix}btn-border-color);
box-shadow: var(--#{$prefix}btn-box-shadow), var(--#{$prefix}btn-focus-box-shadow);
} @else {
box-shadow: var(--#{$prefix}btn-focus-box-shadow);
} }
}
.btn-check:checked + &,
:not(.btn-check) + &:active,
&:first-child:active,
&.active,
&.show {
color: var(--#{$prefix}btn-active-color);
background-color: var(--#{$prefix}btn-active-bg);
// Remove CSS gradients if they're enabled
background-image: if($enable-gradients, none, null);
border-color: var(--#{$prefix}btn-active-border-color);
@include box-shadow(var(--#{$prefix}btn-active-shadow));
&:focus-visible { &:focus-visible {
color: var(--#{$prefix}btn-hover-color);
@include gradient-bg(var(--#{$prefix}btn-hover-bg));
border-color: var(--#{$prefix}btn-hover-border-color);
outline: 0;
// Avoid using mixin so we can pass custom focus shadow properly
@if $enable-shadows {
box-shadow: var(--#{$prefix}btn-box-shadow), var(--#{$prefix}btn-focus-box-shadow);
} @else {
box-shadow: var(--#{$prefix}btn-focus-box-shadow);
}
}
.btn-check:focus-visible + & {
border-color: var(--#{$prefix}btn-hover-border-color);
outline: 0;
// Avoid using mixin so we can pass custom focus shadow properly
@if $enable-shadows {
box-shadow: var(--#{$prefix}btn-box-shadow), var(--#{$prefix}btn-focus-box-shadow);
} @else {
box-shadow: var(--#{$prefix}btn-focus-box-shadow);
}
}
.btn-check:checked + &,
:not(.btn-check) + &:active,
&:first-child:active,
&.active,
&.show {
color: var(--#{$prefix}btn-active-color);
background-color: var(--#{$prefix}btn-active-bg);
// Remove CSS gradients if they're enabled
background-image: if($enable-gradients, none, null);
border-color: var(--#{$prefix}btn-active-border-color);
@include box-shadow(var(--#{$prefix}btn-active-shadow));
&:focus-visible {
// Avoid using mixin so we can pass custom focus shadow properly
@if $enable-shadows {
box-shadow: var(--#{$prefix}btn-active-shadow), var(--#{$prefix}btn-focus-box-shadow);
} @else {
box-shadow: var(--#{$prefix}btn-focus-box-shadow);
}
}
}
.btn-check:checked:focus-visible + & {
// Avoid using mixin so we can pass custom focus shadow properly // Avoid using mixin so we can pass custom focus shadow properly
@if $enable-shadows { @if $enable-shadows {
box-shadow: var(--#{$prefix}btn-active-shadow), var(--#{$prefix}btn-focus-box-shadow); box-shadow: var(--#{$prefix}btn-active-shadow), var(--#{$prefix}btn-focus-box-shadow);
@ -180,119 +191,110 @@
box-shadow: var(--#{$prefix}btn-focus-box-shadow); box-shadow: var(--#{$prefix}btn-focus-box-shadow);
} }
} }
}
.btn-check:checked:focus-visible + & { &:disabled,
// Avoid using mixin so we can pass custom focus shadow properly &.disabled,
@if $enable-shadows { fieldset:disabled & {
box-shadow: var(--#{$prefix}btn-active-shadow), var(--#{$prefix}btn-focus-box-shadow); color: var(--#{$prefix}btn-disabled-color);
} @else { pointer-events: none;
box-shadow: var(--#{$prefix}btn-focus-box-shadow); background-color: var(--#{$prefix}btn-disabled-bg);
background-image: if($enable-gradients, none, null);
border-color: var(--#{$prefix}btn-disabled-border-color);
opacity: var(--#{$prefix}btn-disabled-opacity);
@include box-shadow(none);
} }
} }
&:disabled,
&.disabled,
fieldset:disabled & {
color: var(--#{$prefix}btn-disabled-color);
pointer-events: none;
background-color: var(--#{$prefix}btn-disabled-bg);
background-image: if($enable-gradients, none, null);
border-color: var(--#{$prefix}btn-disabled-border-color);
opacity: var(--#{$prefix}btn-disabled-opacity);
@include box-shadow(none);
}
}
//
// Alternate buttons
//
// // scss-docs-start btn-variant-loops
// Alternate buttons @each $color, $value in $theme-colors {
// .btn-#{$color} {
@if $color == "light" {
// scss-docs-start btn-variant-loops @include button-variant(
@each $color, $value in $theme-colors { $value,
.btn-#{$color} { $value,
@if $color == "light" { $hover-background: shade-color($value, $btn-hover-bg-shade-amount),
@include button-variant( $hover-border: shade-color($value, $btn-hover-border-shade-amount),
$value, $active-background: shade-color($value, $btn-active-bg-shade-amount),
$value, $active-border: shade-color($value, $btn-active-border-shade-amount)
$hover-background: shade-color($value, $btn-hover-bg-shade-amount), );
$hover-border: shade-color($value, $btn-hover-border-shade-amount), } @else if $color == "dark" {
$active-background: shade-color($value, $btn-active-bg-shade-amount), @include button-variant(
$active-border: shade-color($value, $btn-active-border-shade-amount) $value,
); $value,
} @else if $color == "dark" { $hover-background: tint-color($value, $btn-hover-bg-tint-amount),
@include button-variant( $hover-border: tint-color($value, $btn-hover-border-tint-amount),
$value, $active-background: tint-color($value, $btn-active-bg-tint-amount),
$value, $active-border: tint-color($value, $btn-active-border-tint-amount)
$hover-background: tint-color($value, $btn-hover-bg-tint-amount), );
$hover-border: tint-color($value, $btn-hover-border-tint-amount), } @else {
$active-background: tint-color($value, $btn-active-bg-tint-amount), @include button-variant($value, $value);
$active-border: tint-color($value, $btn-active-border-tint-amount) }
);
} @else {
@include button-variant($value, $value);
} }
} }
}
@each $color, $value in $theme-colors { @each $color, $value in $theme-colors {
.btn-outline-#{$color} { .btn-outline-#{$color} {
@include button-outline-variant($value); @include button-outline-variant($value);
}
} }
} // scss-docs-end btn-variant-loops
// scss-docs-end btn-variant-loops
// //
// Link buttons // Link buttons
// //
// Make a button look and behave like a link // Make a button look and behave like a link
.btn-link { .btn-link {
--#{$prefix}btn-font-weight: #{$font-weight-normal}; --#{$prefix}btn-font-weight: #{$font-weight-normal};
--#{$prefix}btn-color: #{$btn-link-color}; --#{$prefix}btn-color: #{$btn-link-color};
--#{$prefix}btn-bg: transparent; --#{$prefix}btn-bg: transparent;
--#{$prefix}btn-border-color: transparent; --#{$prefix}btn-border-color: transparent;
--#{$prefix}btn-hover-color: #{$btn-link-hover-color}; --#{$prefix}btn-hover-color: #{$btn-link-hover-color};
--#{$prefix}btn-hover-border-color: transparent; --#{$prefix}btn-hover-border-color: transparent;
--#{$prefix}btn-active-color: #{$btn-link-hover-color}; --#{$prefix}btn-active-color: #{$btn-link-hover-color};
--#{$prefix}btn-active-border-color: transparent; --#{$prefix}btn-active-border-color: transparent;
--#{$prefix}btn-disabled-color: #{$btn-link-disabled-color}; --#{$prefix}btn-disabled-color: #{$btn-link-disabled-color};
--#{$prefix}btn-disabled-border-color: transparent; --#{$prefix}btn-disabled-border-color: transparent;
--#{$prefix}btn-box-shadow: 0 0 0 #000; // Can't use `none` as keyword negates all values when used with multiple shadows --#{$prefix}btn-box-shadow: 0 0 0 #000; // Can't use `none` as keyword negates all values when used with multiple shadows
--#{$prefix}btn-focus-shadow-rgb: #{$btn-link-focus-shadow-rgb}; --#{$prefix}btn-focus-shadow-rgb: #{$btn-link-focus-shadow-rgb};
text-decoration: $link-decoration; text-decoration: $link-decoration;
@if $enable-gradients { @if $enable-gradients {
background-image: none; background-image: none;
}
&:hover,
&:focus-visible {
text-decoration: $link-hover-decoration;
}
&:focus-visible {
color: var(--#{$prefix}btn-color);
}
&:hover {
color: var(--#{$prefix}btn-hover-color);
}
// No need for an active state here
} }
&:hover,
&:focus-visible { //
text-decoration: $link-hover-decoration; // Button Sizes
//
.btn-lg {
@include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-border-radius-lg);
} }
&:focus-visible { .btn-sm {
color: var(--#{$prefix}btn-color); @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-border-radius-sm);
} }
&:hover {
color: var(--#{$prefix}btn-hover-color);
}
// No need for an active state here
}
//
// Button Sizes
//
.btn-lg {
@include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-border-radius-lg);
}
.btn-sm {
@include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-border-radius-sm);
} }

View File

@ -8,234 +8,236 @@
// Base styles // Base styles
// //
.card { @layer components {
// scss-docs-start card-css-vars .card {
--#{$prefix}card-spacer-y: #{$card-spacer-y}; // scss-docs-start card-css-vars
--#{$prefix}card-spacer-x: #{$card-spacer-x}; --#{$prefix}card-spacer-y: #{$card-spacer-y};
--#{$prefix}card-title-spacer-y: #{$card-title-spacer-y}; --#{$prefix}card-spacer-x: #{$card-spacer-x};
--#{$prefix}card-title-color: #{$card-title-color}; --#{$prefix}card-title-spacer-y: #{$card-title-spacer-y};
--#{$prefix}card-subtitle-color: #{$card-subtitle-color}; --#{$prefix}card-title-color: #{$card-title-color};
--#{$prefix}card-border-width: #{$card-border-width}; --#{$prefix}card-subtitle-color: #{$card-subtitle-color};
--#{$prefix}card-border-color: #{$card-border-color}; --#{$prefix}card-border-width: #{$card-border-width};
--#{$prefix}card-border-radius: #{$card-border-radius}; --#{$prefix}card-border-color: #{$card-border-color};
--#{$prefix}card-box-shadow: #{$card-box-shadow}; --#{$prefix}card-border-radius: #{$card-border-radius};
--#{$prefix}card-inner-border-radius: #{$card-inner-border-radius}; --#{$prefix}card-box-shadow: #{$card-box-shadow};
--#{$prefix}card-cap-padding-y: #{$card-cap-padding-y}; --#{$prefix}card-inner-border-radius: #{$card-inner-border-radius};
--#{$prefix}card-cap-padding-x: #{$card-cap-padding-x}; --#{$prefix}card-cap-padding-y: #{$card-cap-padding-y};
--#{$prefix}card-cap-bg: #{$card-cap-bg}; --#{$prefix}card-cap-padding-x: #{$card-cap-padding-x};
--#{$prefix}card-cap-color: #{$card-cap-color}; --#{$prefix}card-cap-bg: #{$card-cap-bg};
--#{$prefix}card-height: #{$card-height}; --#{$prefix}card-cap-color: #{$card-cap-color};
--#{$prefix}card-color: #{$card-color}; --#{$prefix}card-height: #{$card-height};
--#{$prefix}card-bg: #{$card-bg}; --#{$prefix}card-color: #{$card-color};
--#{$prefix}card-img-overlay-padding: #{$card-img-overlay-padding}; --#{$prefix}card-bg: #{$card-bg};
--#{$prefix}card-group-margin: #{$card-group-margin}; --#{$prefix}card-img-overlay-padding: #{$card-img-overlay-padding};
// scss-docs-end card-css-vars --#{$prefix}card-group-margin: #{$card-group-margin};
// scss-docs-end card-css-vars
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106 min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106
height: var(--#{$prefix}card-height); height: var(--#{$prefix}card-height);
color: var(--#{$prefix}body-color); color: var(--#{$prefix}body-color);
word-wrap: break-word; word-wrap: break-word;
background-color: var(--#{$prefix}card-bg); background-color: var(--#{$prefix}card-bg);
background-clip: border-box; background-clip: border-box;
border: var(--#{$prefix}card-border-width) solid var(--#{$prefix}card-border-color); border: var(--#{$prefix}card-border-width) solid var(--#{$prefix}card-border-color);
@include border-radius(var(--#{$prefix}card-border-radius)); @include border-radius(var(--#{$prefix}card-border-radius));
@include box-shadow(var(--#{$prefix}card-box-shadow)); @include box-shadow(var(--#{$prefix}card-box-shadow));
> hr { > hr {
margin-right: 0; margin-right: 0;
margin-left: 0; margin-left: 0;
}
> .list-group {
border-top: inherit;
border-bottom: inherit;
&:first-child {
border-top-width: 0;
@include border-top-radius(var(--#{$prefix}card-inner-border-radius));
}
&:last-child {
border-bottom-width: 0;
@include border-bottom-radius(var(--#{$prefix}card-inner-border-radius));
}
}
// Due to specificity of the above selector (`.card > .list-group`), we must
// use a child selector here to prevent double borders.
> .card-header + .list-group,
> .list-group + .card-footer {
border-top: 0;
}
} }
> .list-group { .card-body {
border-top: inherit; // Enable `flex-grow: 1` for decks and groups so that card blocks take up
border-bottom: inherit; // as much space as possible, ensuring footers are aligned to the bottom.
flex: 1 1 auto;
padding: var(--#{$prefix}card-spacer-y) var(--#{$prefix}card-spacer-x);
color: var(--#{$prefix}card-color);
}
.card-title {
margin-bottom: var(--#{$prefix}card-title-spacer-y);
color: var(--#{$prefix}card-title-color);
}
.card-subtitle {
margin-top: calc(-.5 * var(--#{$prefix}card-title-spacer-y)); // stylelint-disable-line function-disallowed-list
margin-bottom: 0;
color: var(--#{$prefix}card-subtitle-color);
}
.card-text:last-child {
margin-bottom: 0;
}
.card-link {
&:hover {
text-decoration: if($link-hover-decoration == underline, none, null);
}
+ .card-link {
margin-left: var(--#{$prefix}card-spacer-x);
}
}
//
// Optional textual caps
//
.card-header {
padding: var(--#{$prefix}card-cap-padding-y) var(--#{$prefix}card-cap-padding-x);
margin-bottom: 0; // Removes the default margin-bottom of <hN>
color: var(--#{$prefix}card-cap-color);
background-color: var(--#{$prefix}card-cap-bg);
border-bottom: var(--#{$prefix}card-border-width) solid var(--#{$prefix}card-border-color);
&:first-child { &:first-child {
border-top-width: 0; @include border-radius(var(--#{$prefix}card-inner-border-radius) var(--#{$prefix}card-inner-border-radius) 0 0);
@include border-top-radius(var(--#{$prefix}card-inner-border-radius));
}
&:last-child {
border-bottom-width: 0;
@include border-bottom-radius(var(--#{$prefix}card-inner-border-radius));
} }
} }
// Due to specificity of the above selector (`.card > .list-group`), we must .card-footer {
// use a child selector here to prevent double borders. padding: var(--#{$prefix}card-cap-padding-y) var(--#{$prefix}card-cap-padding-x);
> .card-header + .list-group, color: var(--#{$prefix}card-cap-color);
> .list-group + .card-footer { background-color: var(--#{$prefix}card-cap-bg);
border-top: 0; border-top: var(--#{$prefix}card-border-width) solid var(--#{$prefix}card-border-color);
}
}
.card-body { &:last-child {
// Enable `flex-grow: 1` for decks and groups so that card blocks take up @include border-radius(0 0 var(--#{$prefix}card-inner-border-radius) var(--#{$prefix}card-inner-border-radius));
// as much space as possible, ensuring footers are aligned to the bottom. }
flex: 1 1 auto;
padding: var(--#{$prefix}card-spacer-y) var(--#{$prefix}card-spacer-x);
color: var(--#{$prefix}card-color);
}
.card-title {
margin-bottom: var(--#{$prefix}card-title-spacer-y);
color: var(--#{$prefix}card-title-color);
}
.card-subtitle {
margin-top: calc(-.5 * var(--#{$prefix}card-title-spacer-y)); // stylelint-disable-line function-disallowed-list
margin-bottom: 0;
color: var(--#{$prefix}card-subtitle-color);
}
.card-text:last-child {
margin-bottom: 0;
}
.card-link {
&:hover {
text-decoration: if($link-hover-decoration == underline, none, null);
} }
+ .card-link {
margin-left: var(--#{$prefix}card-spacer-x);
}
}
// //
// Optional textual caps // Header navs
// //
.card-header { .card-header-tabs {
padding: var(--#{$prefix}card-cap-padding-y) var(--#{$prefix}card-cap-padding-x); margin-right: calc(-.5 * var(--#{$prefix}card-cap-padding-x)); // stylelint-disable-line function-disallowed-list
margin-bottom: 0; // Removes the default margin-bottom of <hN> margin-bottom: calc(-1 * var(--#{$prefix}card-cap-padding-y)); // stylelint-disable-line function-disallowed-list
color: var(--#{$prefix}card-cap-color); margin-left: calc(-.5 * var(--#{$prefix}card-cap-padding-x)); // stylelint-disable-line function-disallowed-list
background-color: var(--#{$prefix}card-cap-bg); border-bottom: 0;
border-bottom: var(--#{$prefix}card-border-width) solid var(--#{$prefix}card-border-color);
&:first-child { .nav-link.active {
@include border-radius(var(--#{$prefix}card-inner-border-radius) var(--#{$prefix}card-inner-border-radius) 0 0); background-color: var(--#{$prefix}card-bg);
} border-bottom-color: var(--#{$prefix}card-bg);
} }
.card-footer {
padding: var(--#{$prefix}card-cap-padding-y) var(--#{$prefix}card-cap-padding-x);
color: var(--#{$prefix}card-cap-color);
background-color: var(--#{$prefix}card-cap-bg);
border-top: var(--#{$prefix}card-border-width) solid var(--#{$prefix}card-border-color);
&:last-child {
@include border-radius(0 0 var(--#{$prefix}card-inner-border-radius) var(--#{$prefix}card-inner-border-radius));
}
}
//
// Header navs
//
.card-header-tabs {
margin-right: calc(-.5 * var(--#{$prefix}card-cap-padding-x)); // stylelint-disable-line function-disallowed-list
margin-bottom: calc(-1 * var(--#{$prefix}card-cap-padding-y)); // stylelint-disable-line function-disallowed-list
margin-left: calc(-.5 * var(--#{$prefix}card-cap-padding-x)); // stylelint-disable-line function-disallowed-list
border-bottom: 0;
.nav-link.active {
background-color: var(--#{$prefix}card-bg);
border-bottom-color: var(--#{$prefix}card-bg);
}
}
.card-header-pills {
margin-right: calc(-.5 * var(--#{$prefix}card-cap-padding-x)); // stylelint-disable-line function-disallowed-list
margin-left: calc(-.5 * var(--#{$prefix}card-cap-padding-x)); // stylelint-disable-line function-disallowed-list
}
// Card image
.card-img-overlay {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: var(--#{$prefix}card-img-overlay-padding);
@include border-radius(var(--#{$prefix}card-inner-border-radius));
}
.card-img,
.card-img-top,
.card-img-bottom {
width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
}
.card-img,
.card-img-top {
@include border-top-radius(var(--#{$prefix}card-inner-border-radius));
}
.card-img,
.card-img-bottom {
@include border-bottom-radius(var(--#{$prefix}card-inner-border-radius));
}
//
// Card groups
//
.card-group {
// The child selector allows nested `.card` within `.card-group`
// to display properly.
> .card {
margin-bottom: var(--#{$prefix}card-group-margin);
} }
@include media-breakpoint-up(sm) { .card-header-pills {
display: flex; margin-right: calc(-.5 * var(--#{$prefix}card-cap-padding-x)); // stylelint-disable-line function-disallowed-list
flex-flow: row wrap; margin-left: calc(-.5 * var(--#{$prefix}card-cap-padding-x)); // stylelint-disable-line function-disallowed-list
}
// Card image
.card-img-overlay {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: var(--#{$prefix}card-img-overlay-padding);
@include border-radius(var(--#{$prefix}card-inner-border-radius));
}
.card-img,
.card-img-top,
.card-img-bottom {
width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
}
.card-img,
.card-img-top {
@include border-top-radius(var(--#{$prefix}card-inner-border-radius));
}
.card-img,
.card-img-bottom {
@include border-bottom-radius(var(--#{$prefix}card-inner-border-radius));
}
//
// Card groups
//
.card-group {
// The child selector allows nested `.card` within `.card-group` // The child selector allows nested `.card` within `.card-group`
// to display properly. // to display properly.
> .card { > .card {
flex: 1 0 0; margin-bottom: var(--#{$prefix}card-group-margin);
margin-bottom: 0; }
+ .card { @include media-breakpoint-up(sm) {
margin-left: 0; display: flex;
border-left: 0; flex-flow: row wrap;
} // The child selector allows nested `.card` within `.card-group`
// to display properly.
> .card {
flex: 1 0 0;
margin-bottom: 0;
// Handle rounded corners + .card {
@if $enable-rounded { margin-left: 0;
&:not(:last-child) { border-left: 0;
@include border-end-radius(0);
.card-img-top,
.card-header {
// stylelint-disable-next-line property-disallowed-list
border-top-right-radius: 0;
}
.card-img-bottom,
.card-footer {
// stylelint-disable-next-line property-disallowed-list
border-bottom-right-radius: 0;
}
} }
&:not(:first-child) { // Handle rounded corners
@include border-start-radius(0); @if $enable-rounded {
&:not(:last-child) {
@include border-end-radius(0);
.card-img-top, .card-img-top,
.card-header { .card-header {
// stylelint-disable-next-line property-disallowed-list // stylelint-disable-next-line property-disallowed-list
border-top-left-radius: 0; border-top-right-radius: 0;
}
.card-img-bottom,
.card-footer {
// stylelint-disable-next-line property-disallowed-list
border-bottom-right-radius: 0;
}
} }
.card-img-bottom,
.card-footer { &:not(:first-child) {
// stylelint-disable-next-line property-disallowed-list @include border-start-radius(0);
border-bottom-left-radius: 0;
.card-img-top,
.card-header {
// stylelint-disable-next-line property-disallowed-list
border-top-left-radius: 0;
}
.card-img-bottom,
.card-footer {
// stylelint-disable-next-line property-disallowed-list
border-bottom-left-radius: 0;
}
} }
} }
} }

View File

@ -19,216 +19,218 @@
// 5. .carousel-item-next.carousel-item-start and .carousel-item-prev.carousel-item-end // 5. .carousel-item-next.carousel-item-start and .carousel-item-prev.carousel-item-end
// is the upcoming slide in transition. // is the upcoming slide in transition.
.carousel { @layer components {
position: relative; .carousel {
} position: relative;
}
.carousel.pointer-event { .carousel.pointer-event {
touch-action: pan-y; touch-action: pan-y;
} }
.carousel-inner { .carousel-inner {
position: relative; position: relative;
width: 100%; width: 100%;
overflow: hidden; overflow: hidden;
@include clearfix(); @include clearfix();
} }
.carousel-item {
position: relative;
display: none;
float: left;
width: 100%;
margin-right: -100%;
backface-visibility: hidden;
@include transition($carousel-transition);
}
.carousel-item.active,
.carousel-item-next,
.carousel-item-prev {
display: block;
}
.carousel-item-next:not(.carousel-item-start),
.active.carousel-item-end {
transform: translateX(100%);
}
.carousel-item-prev:not(.carousel-item-end),
.active.carousel-item-start {
transform: translateX(-100%);
}
//
// Alternate transitions
//
.carousel-fade {
.carousel-item { .carousel-item {
opacity: 0; position: relative;
transition-property: opacity; display: none;
transform: none; float: left;
width: 100%;
margin-right: -100%;
backface-visibility: hidden;
@include transition($carousel-transition);
} }
.carousel-item.active, .carousel-item.active,
.carousel-item-next.carousel-item-start, .carousel-item-next,
.carousel-item-prev.carousel-item-end { .carousel-item-prev {
z-index: 1; display: block;
opacity: 1;
} }
.active.carousel-item-start, .carousel-item-next:not(.carousel-item-start),
.active.carousel-item-end { .active.carousel-item-end {
z-index: 0; transform: translateX(100%);
opacity: 0;
@include transition(opacity 0s $carousel-transition-duration);
} }
}
.carousel-item-prev:not(.carousel-item-end),
// .active.carousel-item-start {
// Left/right controls for nav transform: translateX(-100%);
//
.carousel-control-prev,
.carousel-control-next {
position: absolute;
top: 0;
bottom: 0;
z-index: 1;
// Use flex for alignment (1-3)
display: flex; // 1. allow flex styles
align-items: center; // 2. vertically center contents
justify-content: center; // 3. horizontally center contents
width: $carousel-control-width;
padding: 0;
color: $carousel-control-color;
text-align: center;
background: none;
filter: var(--#{$prefix}carousel-control-icon-filter);
border: 0;
opacity: $carousel-control-opacity;
@include transition($carousel-control-transition);
// Hover/focus state
&:hover,
&:focus {
color: $carousel-control-color;
text-decoration: none;
outline: 0;
opacity: $carousel-control-hover-opacity;
} }
}
.carousel-control-prev {
left: 0;
background-image: if($enable-gradients, linear-gradient(90deg, rgba($black, .25), rgba($black, .001)), null);
}
.carousel-control-next {
right: 0;
background-image: if($enable-gradients, linear-gradient(270deg, rgba($black, .25), rgba($black, .001)), null);
}
// Icons for within
.carousel-control-prev-icon,
.carousel-control-next-icon {
display: inline-block;
width: $carousel-control-icon-width;
height: $carousel-control-icon-width;
background-repeat: no-repeat;
background-position: 50%;
background-size: 100% 100%;
}
.carousel-control-prev-icon { //
background-image: escape-svg($carousel-control-prev-icon-bg) #{"/*rtl:" + escape-svg($carousel-control-next-icon-bg) + "*/"}; // Alternate transitions
} //
.carousel-control-next-icon {
background-image: escape-svg($carousel-control-next-icon-bg) #{"/*rtl:" + escape-svg($carousel-control-prev-icon-bg) + "*/"};
}
// Optional indicator pips/controls .carousel-fade {
// .carousel-item {
// Add a container (such as a list) with the following class and add an item (ideally a focusable control, opacity: 0;
// like a button) with data-bs-target for each slide your carousel holds. transition-property: opacity;
transform: none;
}
.carousel-indicators { .carousel-item.active,
position: absolute; .carousel-item-next.carousel-item-start,
right: 0; .carousel-item-prev.carousel-item-end {
bottom: 0; z-index: 1;
left: 0; opacity: 1;
z-index: 2; }
display: flex;
justify-content: center;
padding: 0;
// Use the .carousel-control's width as margin so we don't overlay those
margin-right: $carousel-control-width;
margin-bottom: 1rem;
margin-left: $carousel-control-width;
[data-bs-target] { .active.carousel-item-start,
box-sizing: content-box; .active.carousel-item-end {
flex: 0 1 auto; z-index: 0;
width: $carousel-indicator-width; opacity: 0;
height: $carousel-indicator-height; @include transition(opacity 0s $carousel-transition-duration);
}
}
//
// Left/right controls for nav
//
.carousel-control-prev,
.carousel-control-next {
position: absolute;
top: 0;
bottom: 0;
z-index: 1;
// Use flex for alignment (1-3)
display: flex; // 1. allow flex styles
align-items: center; // 2. vertically center contents
justify-content: center; // 3. horizontally center contents
width: $carousel-control-width;
padding: 0; padding: 0;
margin-right: $carousel-indicator-spacer; color: $carousel-control-color;
margin-left: $carousel-indicator-spacer; text-align: center;
text-indent: -999px; background: none;
cursor: pointer; filter: var(--#{$prefix}carousel-control-icon-filter);
background-color: var(--#{$prefix}carousel-indicator-active-bg);
background-clip: padding-box;
border: 0; border: 0;
// Use transparent borders to increase the hit area by 10px on top and bottom. opacity: $carousel-control-opacity;
border-top: $carousel-indicator-hit-area-height solid transparent; @include transition($carousel-control-transition);
border-bottom: $carousel-indicator-hit-area-height solid transparent;
opacity: $carousel-indicator-opacity; // Hover/focus state
@include transition($carousel-indicator-transition); &:hover,
&:focus {
color: $carousel-control-color;
text-decoration: none;
outline: 0;
opacity: $carousel-control-hover-opacity;
}
}
.carousel-control-prev {
left: 0;
background-image: if($enable-gradients, linear-gradient(90deg, rgba($black, .25), rgba($black, .001)), null);
}
.carousel-control-next {
right: 0;
background-image: if($enable-gradients, linear-gradient(270deg, rgba($black, .25), rgba($black, .001)), null);
} }
.active { // Icons for within
opacity: $carousel-indicator-active-opacity; .carousel-control-prev-icon,
.carousel-control-next-icon {
display: inline-block;
width: $carousel-control-icon-width;
height: $carousel-control-icon-width;
background-repeat: no-repeat;
background-position: 50%;
background-size: 100% 100%;
}
.carousel-control-prev-icon {
background-image: escape-svg($carousel-control-prev-icon-bg) #{"/*rtl:" + escape-svg($carousel-control-next-icon-bg) + "*/"};
}
.carousel-control-next-icon {
background-image: escape-svg($carousel-control-next-icon-bg) #{"/*rtl:" + escape-svg($carousel-control-prev-icon-bg) + "*/"};
}
// Optional indicator pips/controls
//
// Add a container (such as a list) with the following class and add an item (ideally a focusable control,
// like a button) with data-bs-target for each slide your carousel holds.
.carousel-indicators {
position: absolute;
right: 0;
bottom: 0;
left: 0;
z-index: 2;
display: flex;
justify-content: center;
padding: 0;
// Use the .carousel-control's width as margin so we don't overlay those
margin-right: $carousel-control-width;
margin-bottom: 1rem;
margin-left: $carousel-control-width;
[data-bs-target] {
box-sizing: content-box;
flex: 0 1 auto;
width: $carousel-indicator-width;
height: $carousel-indicator-height;
padding: 0;
margin-right: $carousel-indicator-spacer;
margin-left: $carousel-indicator-spacer;
text-indent: -999px;
cursor: pointer;
background-color: var(--#{$prefix}carousel-indicator-active-bg);
background-clip: padding-box;
border: 0;
// Use transparent borders to increase the hit area by 10px on top and bottom.
border-top: $carousel-indicator-hit-area-height solid transparent;
border-bottom: $carousel-indicator-hit-area-height solid transparent;
opacity: $carousel-indicator-opacity;
@include transition($carousel-indicator-transition);
}
.active {
opacity: $carousel-indicator-active-opacity;
}
} }
}
// Optional captions // Optional captions
// //
// //
.carousel-caption { .carousel-caption {
position: absolute; position: absolute;
right: (100% - $carousel-caption-width) * .5; right: (100% - $carousel-caption-width) * .5;
bottom: $carousel-caption-spacer; bottom: $carousel-caption-spacer;
left: (100% - $carousel-caption-width) * .5; left: (100% - $carousel-caption-width) * .5;
padding-top: $carousel-caption-padding-y; padding-top: $carousel-caption-padding-y;
padding-bottom: $carousel-caption-padding-y; padding-bottom: $carousel-caption-padding-y;
color: var(--#{$prefix}carousel-caption-color); color: var(--#{$prefix}carousel-caption-color);
text-align: center; text-align: center;
} }
// Dark mode carousel // Dark mode carousel
@mixin carousel-dark() { @mixin carousel-dark() {
--#{$prefix}carousel-indicator-active-bg: #{$carousel-indicator-active-bg-dark}; --#{$prefix}carousel-indicator-active-bg: #{$carousel-indicator-active-bg-dark};
--#{$prefix}carousel-caption-color: #{$carousel-caption-color-dark}; --#{$prefix}carousel-caption-color: #{$carousel-caption-color-dark};
--#{$prefix}carousel-control-icon-filter: #{$carousel-control-icon-filter-dark}; --#{$prefix}carousel-control-icon-filter: #{$carousel-control-icon-filter-dark};
} }
.carousel-dark { .carousel-dark {
@include carousel-dark();
}
:root,
[data-bs-theme="light"] {
--#{$prefix}carousel-indicator-active-bg: #{$carousel-indicator-active-bg};
--#{$prefix}carousel-caption-color: #{$carousel-caption-color};
--#{$prefix}carousel-control-icon-filter: #{$carousel-control-icon-filter};
}
@if $enable-dark-mode {
@include color-mode(dark, true) {
@include carousel-dark(); @include carousel-dark();
} }
:root,
[data-bs-theme="light"] {
--#{$prefix}carousel-indicator-active-bg: #{$carousel-indicator-active-bg};
--#{$prefix}carousel-caption-color: #{$carousel-caption-color};
--#{$prefix}carousel-control-icon-filter: #{$carousel-control-icon-filter};
}
@if $enable-dark-mode {
@include color-mode(dark, true) {
@include carousel-dark();
}
}
} }

View File

@ -8,64 +8,66 @@
// If you want the anchor version, it requires `href="#"`. // If you want the anchor version, it requires `href="#"`.
// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
.btn-close { @layer components {
// scss-docs-start close-css-vars .btn-close {
--#{$prefix}btn-close-color: #{$btn-close-color}; // scss-docs-start close-css-vars
--#{$prefix}btn-close-bg: #{ escape-svg($btn-close-bg) }; --#{$prefix}btn-close-color: #{$btn-close-color};
--#{$prefix}btn-close-opacity: #{$btn-close-opacity}; --#{$prefix}btn-close-bg: #{ escape-svg($btn-close-bg) };
--#{$prefix}btn-close-hover-opacity: #{$btn-close-hover-opacity}; --#{$prefix}btn-close-opacity: #{$btn-close-opacity};
--#{$prefix}btn-close-focus-shadow: #{$btn-close-focus-shadow}; --#{$prefix}btn-close-hover-opacity: #{$btn-close-hover-opacity};
--#{$prefix}btn-close-focus-opacity: #{$btn-close-focus-opacity}; --#{$prefix}btn-close-focus-shadow: #{$btn-close-focus-shadow};
--#{$prefix}btn-close-disabled-opacity: #{$btn-close-disabled-opacity}; --#{$prefix}btn-close-focus-opacity: #{$btn-close-focus-opacity};
// scss-docs-end close-css-vars --#{$prefix}btn-close-disabled-opacity: #{$btn-close-disabled-opacity};
// scss-docs-end close-css-vars
box-sizing: content-box; box-sizing: content-box;
width: $btn-close-width; width: $btn-close-width;
height: $btn-close-height; height: $btn-close-height;
padding: $btn-close-padding-y $btn-close-padding-x; padding: $btn-close-padding-y $btn-close-padding-x;
color: var(--#{$prefix}btn-close-color);
background: transparent var(--#{$prefix}btn-close-bg) center / $btn-close-width auto no-repeat; // include transparent for button elements
filter: var(--#{$prefix}btn-close-filter);
border: 0; // for button elements
@include border-radius();
opacity: var(--#{$prefix}btn-close-opacity);
// Override <a>'s hover style
&:hover {
color: var(--#{$prefix}btn-close-color); color: var(--#{$prefix}btn-close-color);
text-decoration: none; background: transparent var(--#{$prefix}btn-close-bg) center / $btn-close-width auto no-repeat; // include transparent for button elements
opacity: var(--#{$prefix}btn-close-hover-opacity); filter: var(--#{$prefix}btn-close-filter);
border: 0; // for button elements
@include border-radius();
opacity: var(--#{$prefix}btn-close-opacity);
// Override <a>'s hover style
&:hover {
color: var(--#{$prefix}btn-close-color);
text-decoration: none;
opacity: var(--#{$prefix}btn-close-hover-opacity);
}
&:focus {
outline: 0;
box-shadow: var(--#{$prefix}btn-close-focus-shadow);
opacity: var(--#{$prefix}btn-close-focus-opacity);
}
&:disabled,
&.disabled {
pointer-events: none;
user-select: none;
opacity: var(--#{$prefix}btn-close-disabled-opacity);
}
} }
&:focus { @mixin btn-close-white() {
outline: 0; --#{$prefix}btn-close-filter: #{$btn-close-filter-dark};
box-shadow: var(--#{$prefix}btn-close-focus-shadow);
opacity: var(--#{$prefix}btn-close-focus-opacity);
} }
&:disabled, .btn-close-white {
&.disabled {
pointer-events: none;
user-select: none;
opacity: var(--#{$prefix}btn-close-disabled-opacity);
}
}
@mixin btn-close-white() {
--#{$prefix}btn-close-filter: #{$btn-close-filter-dark};
}
.btn-close-white {
@include btn-close-white();
}
:root,
[data-bs-theme="light"] {
--#{$prefix}btn-close-filter: #{$btn-close-filter};
}
@if $enable-dark-mode {
@include color-mode(dark, true) {
@include btn-close-white(); @include btn-close-white();
} }
:root,
[data-bs-theme="light"] {
--#{$prefix}btn-close-filter: #{$btn-close-filter};
}
@if $enable-dark-mode {
@include color-mode(dark, true) {
@include btn-close-white();
}
}
} }

View File

@ -9,253 +9,255 @@
@use "vendor/rfs" as *; @use "vendor/rfs" as *;
@use "layout/breakpoints" as *; @use "layout/breakpoints" as *;
// The dropdown wrapper (`<div>`) @layer components {
.dropup, // The dropdown wrapper (`<div>`)
.dropend, .dropup,
.dropdown, .dropend,
.dropstart, .dropdown,
.dropup-center, .dropstart,
.dropdown-center { .dropup-center,
position: relative; .dropdown-center {
} position: relative;
.dropdown-toggle {
white-space: nowrap;
// Generate the caret automatically
@include caret();
}
// The dropdown menu
.dropdown-menu {
// scss-docs-start dropdown-css-vars
--#{$prefix}dropdown-zindex: #{$zindex-dropdown};
--#{$prefix}dropdown-min-width: #{$dropdown-min-width};
--#{$prefix}dropdown-padding-x: #{$dropdown-padding-x};
--#{$prefix}dropdown-padding-y: #{$dropdown-padding-y};
--#{$prefix}dropdown-spacer: #{$dropdown-spacer};
@include rfs($dropdown-font-size, --#{$prefix}dropdown-font-size);
--#{$prefix}dropdown-color: #{$dropdown-color};
--#{$prefix}dropdown-bg: #{$dropdown-bg};
--#{$prefix}dropdown-border-color: #{$dropdown-border-color};
--#{$prefix}dropdown-border-radius: #{$dropdown-border-radius};
--#{$prefix}dropdown-border-width: #{$dropdown-border-width};
--#{$prefix}dropdown-inner-border-radius: #{$dropdown-inner-border-radius};
--#{$prefix}dropdown-divider-bg: #{$dropdown-divider-bg};
--#{$prefix}dropdown-divider-margin-y: #{$dropdown-divider-margin-y};
--#{$prefix}dropdown-box-shadow: #{$dropdown-box-shadow};
--#{$prefix}dropdown-link-color: #{$dropdown-link-color};
--#{$prefix}dropdown-link-hover-color: #{$dropdown-link-hover-color};
--#{$prefix}dropdown-link-hover-bg: #{$dropdown-link-hover-bg};
--#{$prefix}dropdown-link-active-color: #{$dropdown-link-active-color};
--#{$prefix}dropdown-link-active-bg: #{$dropdown-link-active-bg};
--#{$prefix}dropdown-link-disabled-color: #{$dropdown-link-disabled-color};
--#{$prefix}dropdown-item-padding-x: #{$dropdown-item-padding-x};
--#{$prefix}dropdown-item-padding-y: #{$dropdown-item-padding-y};
--#{$prefix}dropdown-header-color: #{$dropdown-header-color};
--#{$prefix}dropdown-header-padding-x: #{$dropdown-header-padding-x};
--#{$prefix}dropdown-header-padding-y: #{$dropdown-header-padding-y};
// scss-docs-end dropdown-css-vars
position: absolute;
z-index: var(--#{$prefix}dropdown-zindex);
display: none; // none by default, but block on "open" of the menu
min-width: var(--#{$prefix}dropdown-min-width);
padding: var(--#{$prefix}dropdown-padding-y) var(--#{$prefix}dropdown-padding-x);
margin: 0; // Override default margin of ul
@include font-size(var(--#{$prefix}dropdown-font-size));
color: var(--#{$prefix}dropdown-color);
text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)
list-style: none;
background-color: var(--#{$prefix}dropdown-bg);
background-clip: padding-box;
border: var(--#{$prefix}dropdown-border-width) solid var(--#{$prefix}dropdown-border-color);
@include border-radius(var(--#{$prefix}dropdown-border-radius));
@include box-shadow(var(--#{$prefix}dropdown-box-shadow));
&[data-bs-popper] {
top: 100%;
left: 0;
margin-top: var(--#{$prefix}dropdown-spacer);
} }
@if $dropdown-padding-y == 0 { .dropdown-toggle {
> .dropdown-item:first-child, white-space: nowrap;
> li:first-child .dropdown-item {
@include border-top-radius(var(--#{$prefix}dropdown-inner-border-radius));
}
> .dropdown-item:last-child,
> li:last-child .dropdown-item {
@include border-bottom-radius(var(--#{$prefix}dropdown-inner-border-radius));
}
// Generate the caret automatically
@include caret();
} }
}
// scss-docs-start responsive-breakpoints // The dropdown menu
// We deliberately hardcode the `bs-` prefix because we check .dropdown-menu {
// this custom property in JS to determine Popper's positioning // scss-docs-start dropdown-css-vars
--#{$prefix}dropdown-zindex: #{$zindex-dropdown};
--#{$prefix}dropdown-min-width: #{$dropdown-min-width};
--#{$prefix}dropdown-padding-x: #{$dropdown-padding-x};
--#{$prefix}dropdown-padding-y: #{$dropdown-padding-y};
--#{$prefix}dropdown-spacer: #{$dropdown-spacer};
@include rfs($dropdown-font-size, --#{$prefix}dropdown-font-size);
--#{$prefix}dropdown-color: #{$dropdown-color};
--#{$prefix}dropdown-bg: #{$dropdown-bg};
--#{$prefix}dropdown-border-color: #{$dropdown-border-color};
--#{$prefix}dropdown-border-radius: #{$dropdown-border-radius};
--#{$prefix}dropdown-border-width: #{$dropdown-border-width};
--#{$prefix}dropdown-inner-border-radius: #{$dropdown-inner-border-radius};
--#{$prefix}dropdown-divider-bg: #{$dropdown-divider-bg};
--#{$prefix}dropdown-divider-margin-y: #{$dropdown-divider-margin-y};
--#{$prefix}dropdown-box-shadow: #{$dropdown-box-shadow};
--#{$prefix}dropdown-link-color: #{$dropdown-link-color};
--#{$prefix}dropdown-link-hover-color: #{$dropdown-link-hover-color};
--#{$prefix}dropdown-link-hover-bg: #{$dropdown-link-hover-bg};
--#{$prefix}dropdown-link-active-color: #{$dropdown-link-active-color};
--#{$prefix}dropdown-link-active-bg: #{$dropdown-link-active-bg};
--#{$prefix}dropdown-link-disabled-color: #{$dropdown-link-disabled-color};
--#{$prefix}dropdown-item-padding-x: #{$dropdown-item-padding-x};
--#{$prefix}dropdown-item-padding-y: #{$dropdown-item-padding-y};
--#{$prefix}dropdown-header-color: #{$dropdown-header-color};
--#{$prefix}dropdown-header-padding-x: #{$dropdown-header-padding-x};
--#{$prefix}dropdown-header-padding-y: #{$dropdown-header-padding-y};
// scss-docs-end dropdown-css-vars
@each $breakpoint in map.keys($grid-breakpoints) { position: absolute;
@include media-breakpoint-up($breakpoint) { z-index: var(--#{$prefix}dropdown-zindex);
$infix: breakpoint-infix($breakpoint, $grid-breakpoints); display: none; // none by default, but block on "open" of the menu
min-width: var(--#{$prefix}dropdown-min-width);
padding: var(--#{$prefix}dropdown-padding-y) var(--#{$prefix}dropdown-padding-x);
margin: 0; // Override default margin of ul
@include font-size(var(--#{$prefix}dropdown-font-size));
color: var(--#{$prefix}dropdown-color);
text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)
list-style: none;
background-color: var(--#{$prefix}dropdown-bg);
background-clip: padding-box;
border: var(--#{$prefix}dropdown-border-width) solid var(--#{$prefix}dropdown-border-color);
@include border-radius(var(--#{$prefix}dropdown-border-radius));
@include box-shadow(var(--#{$prefix}dropdown-box-shadow));
.dropdown-menu#{$infix}-start { &[data-bs-popper] {
--bs-position: start; top: 100%;
left: 0;
margin-top: var(--#{$prefix}dropdown-spacer);
}
&[data-bs-popper] { @if $dropdown-padding-y == 0 {
right: auto; > .dropdown-item:first-child,
left: 0; > li:first-child .dropdown-item {
@include border-top-radius(var(--#{$prefix}dropdown-inner-border-radius));
} }
> .dropdown-item:last-child,
> li:last-child .dropdown-item {
@include border-bottom-radius(var(--#{$prefix}dropdown-inner-border-radius));
}
} }
}
.dropdown-menu#{$infix}-end { // scss-docs-start responsive-breakpoints
--bs-position: end; // We deliberately hardcode the `bs-` prefix because we check
// this custom property in JS to determine Popper's positioning
&[data-bs-popper] { @each $breakpoint in map.keys($grid-breakpoints) {
right: 0; @include media-breakpoint-up($breakpoint) {
left: auto; $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
.dropdown-menu#{$infix}-start {
--bs-position: start;
&[data-bs-popper] {
right: auto;
left: 0;
}
}
.dropdown-menu#{$infix}-end {
--bs-position: end;
&[data-bs-popper] {
right: 0;
left: auto;
}
} }
} }
} }
} // scss-docs-end responsive-breakpoints
// scss-docs-end responsive-breakpoints
// Allow for dropdowns to go bottom up (aka, dropup-menu) // Allow for dropdowns to go bottom up (aka, dropup-menu)
// Just add .dropup after the standard .dropdown class and you're set. // Just add .dropup after the standard .dropdown class and you're set.
.dropup { .dropup {
.dropdown-menu[data-bs-popper] { .dropdown-menu[data-bs-popper] {
top: auto; top: auto;
bottom: 100%; bottom: 100%;
margin-top: 0; margin-top: 0;
margin-bottom: var(--#{$prefix}dropdown-spacer); margin-bottom: var(--#{$prefix}dropdown-spacer);
} }
.dropdown-toggle { .dropdown-toggle {
@include caret(up); @include caret(up);
}
}
.dropend {
.dropdown-menu[data-bs-popper] {
top: 0;
right: auto;
left: 100%;
margin-top: 0;
margin-left: var(--#{$prefix}dropdown-spacer);
}
.dropdown-toggle {
@include caret(end);
&::after {
vertical-align: 0;
} }
} }
}
.dropstart { .dropend {
.dropdown-menu[data-bs-popper] { .dropdown-menu[data-bs-popper] {
top: 0; top: 0;
right: 100%; right: auto;
left: auto; left: 100%;
margin-top: 0; margin-top: 0;
margin-right: var(--#{$prefix}dropdown-spacer); margin-left: var(--#{$prefix}dropdown-spacer);
} }
.dropdown-toggle { .dropdown-toggle {
@include caret(start); @include caret(end);
&::before { &::after {
vertical-align: 0; vertical-align: 0;
}
} }
} }
}
.dropstart {
.dropdown-menu[data-bs-popper] {
top: 0;
right: 100%;
left: auto;
margin-top: 0;
margin-right: var(--#{$prefix}dropdown-spacer);
}
// Dividers (basically an `<hr>`) within the dropdown .dropdown-toggle {
.dropdown-divider { @include caret(start);
height: 0; &::before {
margin: var(--#{$prefix}dropdown-divider-margin-y) 0; vertical-align: 0;
overflow: hidden; }
border-top: 1px solid var(--#{$prefix}dropdown-divider-bg); }
opacity: 1; // Revisit in v6 to de-dupe styles that conflict with <hr> element
}
// Links, buttons, and more within the dropdown menu
//
// `<button>`-specific styles are denoted with `// For <button>s`
.dropdown-item {
display: block;
width: 100%; // For `<button>`s
padding: var(--#{$prefix}dropdown-item-padding-y) var(--#{$prefix}dropdown-item-padding-x);
clear: both;
font-weight: $font-weight-normal;
color: var(--#{$prefix}dropdown-link-color);
text-align: inherit; // For `<button>`s
text-decoration: if($link-decoration == none, null, none);
white-space: nowrap; // prevent links from randomly breaking onto new lines
background-color: transparent; // For `<button>`s
border: 0; // For `<button>`s
@include border-radius(var(--#{$prefix}dropdown-item-border-radius, 0));
&:hover,
&:focus {
color: var(--#{$prefix}dropdown-link-hover-color);
text-decoration: if($link-hover-decoration == underline, none, null);
@include gradient-bg(var(--#{$prefix}dropdown-link-hover-bg));
} }
&.active,
&:active { // Dividers (basically an `<hr>`) within the dropdown
color: var(--#{$prefix}dropdown-link-active-color); .dropdown-divider {
text-decoration: none; height: 0;
@include gradient-bg(var(--#{$prefix}dropdown-link-active-bg)); margin: var(--#{$prefix}dropdown-divider-margin-y) 0;
overflow: hidden;
border-top: 1px solid var(--#{$prefix}dropdown-divider-bg);
opacity: 1; // Revisit in v6 to de-dupe styles that conflict with <hr> element
} }
&.disabled, // Links, buttons, and more within the dropdown menu
&:disabled { //
color: var(--#{$prefix}dropdown-link-disabled-color); // `<button>`-specific styles are denoted with `// For <button>s`
pointer-events: none; .dropdown-item {
background-color: transparent; display: block;
// Remove CSS gradients if they're enabled width: 100%; // For `<button>`s
background-image: if($enable-gradients, none, null); padding: var(--#{$prefix}dropdown-item-padding-y) var(--#{$prefix}dropdown-item-padding-x);
clear: both;
font-weight: $font-weight-normal;
color: var(--#{$prefix}dropdown-link-color);
text-align: inherit; // For `<button>`s
text-decoration: if($link-decoration == none, null, none);
white-space: nowrap; // prevent links from randomly breaking onto new lines
background-color: transparent; // For `<button>`s
border: 0; // For `<button>`s
@include border-radius(var(--#{$prefix}dropdown-item-border-radius, 0));
&:hover,
&:focus {
color: var(--#{$prefix}dropdown-link-hover-color);
text-decoration: if($link-hover-decoration == underline, none, null);
@include gradient-bg(var(--#{$prefix}dropdown-link-hover-bg));
}
&.active,
&:active {
color: var(--#{$prefix}dropdown-link-active-color);
text-decoration: none;
@include gradient-bg(var(--#{$prefix}dropdown-link-active-bg));
}
&.disabled,
&:disabled {
color: var(--#{$prefix}dropdown-link-disabled-color);
pointer-events: none;
background-color: transparent;
// Remove CSS gradients if they're enabled
background-image: if($enable-gradients, none, null);
}
}
.dropdown-menu.show {
display: block;
}
// Dropdown section headers
.dropdown-header {
display: block;
padding: var(--#{$prefix}dropdown-header-padding-y) var(--#{$prefix}dropdown-header-padding-x);
margin-bottom: 0; // for use with heading elements
@include font-size($font-size-sm);
color: var(--#{$prefix}dropdown-header-color);
white-space: nowrap; // as with > li > a
}
// Dropdown text
.dropdown-item-text {
display: block;
padding: var(--#{$prefix}dropdown-item-padding-y) var(--#{$prefix}dropdown-item-padding-x);
color: var(--#{$prefix}dropdown-link-color);
}
// Dark dropdowns
.dropdown-menu-dark {
// scss-docs-start dropdown-dark-css-vars
--#{$prefix}dropdown-color: #{$dropdown-dark-color};
--#{$prefix}dropdown-bg: #{$dropdown-dark-bg};
--#{$prefix}dropdown-border-color: #{$dropdown-dark-border-color};
--#{$prefix}dropdown-box-shadow: #{$dropdown-dark-box-shadow};
--#{$prefix}dropdown-link-color: #{$dropdown-dark-link-color};
--#{$prefix}dropdown-link-hover-color: #{$dropdown-dark-link-hover-color};
--#{$prefix}dropdown-divider-bg: #{$dropdown-dark-divider-bg};
--#{$prefix}dropdown-link-hover-bg: #{$dropdown-dark-link-hover-bg};
--#{$prefix}dropdown-link-active-color: #{$dropdown-dark-link-active-color};
--#{$prefix}dropdown-link-active-bg: #{$dropdown-dark-link-active-bg};
--#{$prefix}dropdown-link-disabled-color: #{$dropdown-dark-link-disabled-color};
--#{$prefix}dropdown-header-color: #{$dropdown-dark-header-color};
// scss-docs-end dropdown-dark-css-vars
} }
} }
.dropdown-menu.show {
display: block;
}
// Dropdown section headers
.dropdown-header {
display: block;
padding: var(--#{$prefix}dropdown-header-padding-y) var(--#{$prefix}dropdown-header-padding-x);
margin-bottom: 0; // for use with heading elements
@include font-size($font-size-sm);
color: var(--#{$prefix}dropdown-header-color);
white-space: nowrap; // as with > li > a
}
// Dropdown text
.dropdown-item-text {
display: block;
padding: var(--#{$prefix}dropdown-item-padding-y) var(--#{$prefix}dropdown-item-padding-x);
color: var(--#{$prefix}dropdown-link-color);
}
// Dark dropdowns
.dropdown-menu-dark {
// scss-docs-start dropdown-dark-css-vars
--#{$prefix}dropdown-color: #{$dropdown-dark-color};
--#{$prefix}dropdown-bg: #{$dropdown-dark-bg};
--#{$prefix}dropdown-border-color: #{$dropdown-dark-border-color};
--#{$prefix}dropdown-box-shadow: #{$dropdown-dark-box-shadow};
--#{$prefix}dropdown-link-color: #{$dropdown-dark-link-color};
--#{$prefix}dropdown-link-hover-color: #{$dropdown-dark-link-hover-color};
--#{$prefix}dropdown-divider-bg: #{$dropdown-dark-divider-bg};
--#{$prefix}dropdown-link-hover-bg: #{$dropdown-dark-link-hover-bg};
--#{$prefix}dropdown-link-active-color: #{$dropdown-dark-link-active-color};
--#{$prefix}dropdown-link-active-bg: #{$dropdown-dark-link-active-bg};
--#{$prefix}dropdown-link-disabled-color: #{$dropdown-dark-link-disabled-color};
--#{$prefix}dropdown-header-color: #{$dropdown-dark-header-color};
// scss-docs-end dropdown-dark-css-vars
}

View File

@ -1,49 +0,0 @@
@use "config" as *;
@use "variables" as *;
@use "vendor/rfs" as *;
@use "mixins/image" as *;
@use "mixins/border-radius" as *;
@use "mixins/box-shadow" as *;
// Responsive images (ensure images don't scale beyond their parents)
//
// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.
// We previously tried the "images are responsive by default" approach in Bootstrap v2,
// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)
// which weren't expecting the images within themselves to be involuntarily resized.
// See also https://github.com/twbs/bootstrap/issues/18178
.img-fluid {
@include img-fluid();
}
// Image thumbnails
.img-thumbnail {
padding: $thumbnail-padding;
background-color: $thumbnail-bg;
border: $thumbnail-border-width solid $thumbnail-border-color;
@include border-radius($thumbnail-border-radius);
@include box-shadow($thumbnail-box-shadow);
// Keep them at most 100% wide
@include img-fluid();
}
//
// Figures
//
.figure {
// Ensures the caption's text aligns with the image.
display: inline-block;
}
.figure-img {
margin-bottom: $spacer * .5;
line-height: 1;
}
.figure-caption {
@include font-size($figure-caption-font-size);
color: $figure-caption-color;
}

View File

@ -10,196 +10,198 @@
// //
// Easily usable on <ul>, <ol>, or <div>. // Easily usable on <ul>, <ol>, or <div>.
.list-group { @layer components {
// scss-docs-start list-group-css-vars .list-group {
--#{$prefix}list-group-color: #{$list-group-color}; // scss-docs-start list-group-css-vars
--#{$prefix}list-group-bg: #{$list-group-bg}; --#{$prefix}list-group-color: #{$list-group-color};
--#{$prefix}list-group-border-color: #{$list-group-border-color}; --#{$prefix}list-group-bg: #{$list-group-bg};
--#{$prefix}list-group-border-width: #{$list-group-border-width}; --#{$prefix}list-group-border-color: #{$list-group-border-color};
--#{$prefix}list-group-border-radius: #{$list-group-border-radius}; --#{$prefix}list-group-border-width: #{$list-group-border-width};
--#{$prefix}list-group-item-padding-x: #{$list-group-item-padding-x}; --#{$prefix}list-group-border-radius: #{$list-group-border-radius};
--#{$prefix}list-group-item-padding-y: #{$list-group-item-padding-y}; --#{$prefix}list-group-item-padding-x: #{$list-group-item-padding-x};
--#{$prefix}list-group-action-color: #{$list-group-action-color}; --#{$prefix}list-group-item-padding-y: #{$list-group-item-padding-y};
--#{$prefix}list-group-action-hover-color: #{$list-group-action-hover-color}; --#{$prefix}list-group-action-color: #{$list-group-action-color};
--#{$prefix}list-group-action-hover-bg: #{$list-group-hover-bg}; --#{$prefix}list-group-action-hover-color: #{$list-group-action-hover-color};
--#{$prefix}list-group-action-active-color: #{$list-group-action-active-color}; --#{$prefix}list-group-action-hover-bg: #{$list-group-hover-bg};
--#{$prefix}list-group-action-active-bg: #{$list-group-action-active-bg}; --#{$prefix}list-group-action-active-color: #{$list-group-action-active-color};
--#{$prefix}list-group-disabled-color: #{$list-group-disabled-color}; --#{$prefix}list-group-action-active-bg: #{$list-group-action-active-bg};
--#{$prefix}list-group-disabled-bg: #{$list-group-disabled-bg}; --#{$prefix}list-group-disabled-color: #{$list-group-disabled-color};
--#{$prefix}list-group-active-color: #{$list-group-active-color}; --#{$prefix}list-group-disabled-bg: #{$list-group-disabled-bg};
--#{$prefix}list-group-active-bg: #{$list-group-active-bg}; --#{$prefix}list-group-active-color: #{$list-group-active-color};
--#{$prefix}list-group-active-border-color: #{$list-group-active-border-color}; --#{$prefix}list-group-active-bg: #{$list-group-active-bg};
// scss-docs-end list-group-css-vars --#{$prefix}list-group-active-border-color: #{$list-group-active-border-color};
// scss-docs-end list-group-css-vars
display: flex; display: flex;
flex-direction: column; flex-direction: column;
// No need to set list-style: none; since .list-group-item is block level // No need to set list-style: none; since .list-group-item is block level
padding-left: 0; // reset padding because ul and ol padding-left: 0; // reset padding because ul and ol
margin-bottom: 0; margin-bottom: 0;
@include border-radius(var(--#{$prefix}list-group-border-radius)); @include border-radius(var(--#{$prefix}list-group-border-radius));
}
.list-group-numbered {
list-style-type: none;
counter-reset: section;
> .list-group-item::before {
// Increments only this instance of the section counter
content: counters(section, ".") ". ";
counter-increment: section;
}
}
// Interactive list items
//
// Use anchor or button elements instead of `li`s or `div`s to create interactive
// list items. Includes an extra `.active` modifier class for selected items.
.list-group-item-action {
width: 100%; // For `<button>`s (anchors become 100% by default though)
color: var(--#{$prefix}list-group-action-color);
text-align: inherit; // For `<button>`s (anchors inherit)
// Hover state
&:hover,
&:focus {
z-index: 1; // Place hover/focus items above their siblings for proper border styling
color: var(--#{$prefix}list-group-action-hover-color);
text-decoration: none;
background-color: var(--#{$prefix}list-group-action-hover-bg);
} }
&:active { .list-group-numbered {
color: var(--#{$prefix}list-group-action-active-color); list-style-type: none;
background-color: var(--#{$prefix}list-group-action-active-bg); counter-reset: section;
}
}
// Individual list items > .list-group-item::before {
// // Increments only this instance of the section counter
// Use on `li`s or `div`s within the `.list-group` parent. content: counters(section, ".") ". ";
counter-increment: section;
.list-group-item {
position: relative;
display: block;
padding: var(--#{$prefix}list-group-item-padding-y) var(--#{$prefix}list-group-item-padding-x);
color: var(--#{$prefix}list-group-color);
text-decoration: if($link-decoration == none, null, none);
background-color: var(--#{$prefix}list-group-bg);
border: var(--#{$prefix}list-group-border-width) solid var(--#{$prefix}list-group-border-color);
&:first-child {
@include border-top-radius(inherit);
}
&:last-child {
@include border-bottom-radius(inherit);
}
&.disabled,
&:disabled {
color: var(--#{$prefix}list-group-disabled-color);
pointer-events: none;
background-color: var(--#{$prefix}list-group-disabled-bg);
}
// Include both here for `<a>`s and `<button>`s
&.active {
z-index: 2; // Place active items above their siblings for proper border styling
color: var(--#{$prefix}list-group-active-color);
background-color: var(--#{$prefix}list-group-active-bg);
border-color: var(--#{$prefix}list-group-active-border-color);
}
// stylelint-disable-next-line scss/selector-no-redundant-nesting-selector
& + .list-group-item {
border-top-width: 0;
&.active {
margin-top: calc(-1 * var(--#{$prefix}list-group-border-width)); // stylelint-disable-line function-disallowed-list
border-top-width: var(--#{$prefix}list-group-border-width);
} }
} }
}
// Horizontal // Interactive list items
// //
// Change the layout of list group items from vertical (default) to horizontal. // Use anchor or button elements instead of `li`s or `div`s to create interactive
// list items. Includes an extra `.active` modifier class for selected items.
@each $breakpoint in map.keys($grid-breakpoints) { .list-group-item-action {
@include media-breakpoint-up($breakpoint) { width: 100%; // For `<button>`s (anchors become 100% by default though)
$infix: breakpoint-infix($breakpoint, $grid-breakpoints); color: var(--#{$prefix}list-group-action-color);
text-align: inherit; // For `<button>`s (anchors inherit)
.list-group-horizontal#{$infix} { // Hover state
flex-direction: row; &:hover,
&:focus {
z-index: 1; // Place hover/focus items above their siblings for proper border styling
color: var(--#{$prefix}list-group-action-hover-color);
text-decoration: none;
background-color: var(--#{$prefix}list-group-action-hover-bg);
}
> .list-group-item { &:active {
&:first-child:not(:last-child) { color: var(--#{$prefix}list-group-action-active-color);
@include border-bottom-start-radius(var(--#{$prefix}list-group-border-radius)); background-color: var(--#{$prefix}list-group-action-active-bg);
@include border-top-end-radius(0); }
} }
&:last-child:not(:first-child) { // Individual list items
@include border-top-end-radius(var(--#{$prefix}list-group-border-radius)); //
@include border-bottom-start-radius(0); // Use on `li`s or `div`s within the `.list-group` parent.
}
&.active { .list-group-item {
margin-top: 0; position: relative;
} display: block;
padding: var(--#{$prefix}list-group-item-padding-y) var(--#{$prefix}list-group-item-padding-x);
color: var(--#{$prefix}list-group-color);
text-decoration: if($link-decoration == none, null, none);
background-color: var(--#{$prefix}list-group-bg);
border: var(--#{$prefix}list-group-border-width) solid var(--#{$prefix}list-group-border-color);
+ .list-group-item { &:first-child {
border-top-width: var(--#{$prefix}list-group-border-width); @include border-top-radius(inherit);
border-left-width: 0; }
&:last-child {
@include border-bottom-radius(inherit);
}
&.disabled,
&:disabled {
color: var(--#{$prefix}list-group-disabled-color);
pointer-events: none;
background-color: var(--#{$prefix}list-group-disabled-bg);
}
// Include both here for `<a>`s and `<button>`s
&.active {
z-index: 2; // Place active items above their siblings for proper border styling
color: var(--#{$prefix}list-group-active-color);
background-color: var(--#{$prefix}list-group-active-bg);
border-color: var(--#{$prefix}list-group-active-border-color);
}
// stylelint-disable-next-line scss/selector-no-redundant-nesting-selector
& + .list-group-item {
border-top-width: 0;
&.active {
margin-top: calc(-1 * var(--#{$prefix}list-group-border-width)); // stylelint-disable-line function-disallowed-list
border-top-width: var(--#{$prefix}list-group-border-width);
}
}
}
// Horizontal
//
// Change the layout of list group items from vertical (default) to horizontal.
@each $breakpoint in map.keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
.list-group-horizontal#{$infix} {
flex-direction: row;
> .list-group-item {
&:first-child:not(:last-child) {
@include border-bottom-start-radius(var(--#{$prefix}list-group-border-radius));
@include border-top-end-radius(0);
}
&:last-child:not(:first-child) {
@include border-top-end-radius(var(--#{$prefix}list-group-border-radius));
@include border-bottom-start-radius(0);
}
&.active { &.active {
margin-left: calc(-1 * var(--#{$prefix}list-group-border-width)); // stylelint-disable-line function-disallowed-list margin-top: 0;
border-left-width: var(--#{$prefix}list-group-border-width); }
+ .list-group-item {
border-top-width: var(--#{$prefix}list-group-border-width);
border-left-width: 0;
&.active {
margin-left: calc(-1 * var(--#{$prefix}list-group-border-width)); // stylelint-disable-line function-disallowed-list
border-left-width: var(--#{$prefix}list-group-border-width);
}
} }
} }
} }
} }
} }
}
// Flush list items // Flush list items
// //
// Remove borders and border-radius to keep list group items edge-to-edge. Most // Remove borders and border-radius to keep list group items edge-to-edge. Most
// useful within other components (e.g., cards). // useful within other components (e.g., cards).
.list-group-flush { .list-group-flush {
@include border-radius(0); @include border-radius(0);
> .list-group-item { > .list-group-item {
border-width: 0 0 var(--#{$prefix}list-group-border-width); border-width: 0 0 var(--#{$prefix}list-group-border-width);
&:last-child { &:last-child {
border-bottom-width: 0; border-bottom-width: 0;
}
} }
} }
}
// scss-docs-start list-group-modifiers // scss-docs-start list-group-modifiers
// List group contextual variants // List group contextual variants
// //
// Add modifier classes to change text and background color on individual items. // Add modifier classes to change text and background color on individual items.
// Organizationally, this must come after the `:hover` states. // Organizationally, this must come after the `:hover` states.
@each $state in map.keys($theme-colors) { @each $state in map.keys($theme-colors) {
.list-group-item-#{$state} { .list-group-item-#{$state} {
--#{$prefix}list-group-color: var(--#{$prefix}#{$state}-text-emphasis); --#{$prefix}list-group-color: var(--#{$prefix}#{$state}-text-emphasis);
--#{$prefix}list-group-bg: var(--#{$prefix}#{$state}-bg-subtle); --#{$prefix}list-group-bg: var(--#{$prefix}#{$state}-bg-subtle);
--#{$prefix}list-group-border-color: var(--#{$prefix}#{$state}-border-subtle); --#{$prefix}list-group-border-color: var(--#{$prefix}#{$state}-border-subtle);
--#{$prefix}list-group-action-hover-color: var(--#{$prefix}emphasis-color); --#{$prefix}list-group-action-hover-color: var(--#{$prefix}emphasis-color);
--#{$prefix}list-group-action-hover-bg: var(--#{$prefix}#{$state}-border-subtle); --#{$prefix}list-group-action-hover-bg: var(--#{$prefix}#{$state}-border-subtle);
--#{$prefix}list-group-action-active-color: var(--#{$prefix}emphasis-color); --#{$prefix}list-group-action-active-color: var(--#{$prefix}emphasis-color);
--#{$prefix}list-group-action-active-bg: var(--#{$prefix}#{$state}-border-subtle); --#{$prefix}list-group-action-active-bg: var(--#{$prefix}#{$state}-border-subtle);
--#{$prefix}list-group-active-color: var(--#{$prefix}#{$state}-bg-subtle); --#{$prefix}list-group-active-color: var(--#{$prefix}#{$state}-bg-subtle);
--#{$prefix}list-group-active-bg: var(--#{$prefix}#{$state}-text-emphasis); --#{$prefix}list-group-active-bg: var(--#{$prefix}#{$state}-text-emphasis);
--#{$prefix}list-group-active-border-color: var(--#{$prefix}#{$state}-text-emphasis); --#{$prefix}list-group-active-border-color: var(--#{$prefix}#{$state}-text-emphasis);
}
} }
// scss-docs-end list-group-modifiers
} }
// scss-docs-end list-group-modifiers

View File

@ -16,232 +16,233 @@
// .modal-dialog - positioning shell for the actual modal // .modal-dialog - positioning shell for the actual modal
// .modal-content - actual modal w/ bg and corners and stuff // .modal-content - actual modal w/ bg and corners and stuff
@layer components {
// Container that the modal scrolls within // Container that the modal scrolls within
.modal {
// scss-docs-start modal-css-vars
--#{$prefix}modal-zindex: #{$zindex-modal};
--#{$prefix}modal-width: #{$modal-md};
--#{$prefix}modal-padding: #{$modal-inner-padding};
--#{$prefix}modal-margin: #{$modal-dialog-margin};
--#{$prefix}modal-color: #{$modal-content-color};
--#{$prefix}modal-bg: #{$modal-content-bg};
--#{$prefix}modal-border-color: #{$modal-content-border-color};
--#{$prefix}modal-border-width: #{$modal-content-border-width};
--#{$prefix}modal-border-radius: #{$modal-content-border-radius};
--#{$prefix}modal-box-shadow: #{$modal-content-box-shadow-xs};
--#{$prefix}modal-inner-border-radius: #{$modal-content-inner-border-radius};
--#{$prefix}modal-header-padding-x: #{$modal-header-padding-x};
--#{$prefix}modal-header-padding-y: #{$modal-header-padding-y};
--#{$prefix}modal-header-padding: #{$modal-header-padding}; // Todo in v6: Split this padding into x and y
--#{$prefix}modal-header-border-color: #{$modal-header-border-color};
--#{$prefix}modal-header-border-width: #{$modal-header-border-width};
--#{$prefix}modal-title-line-height: #{$modal-title-line-height};
--#{$prefix}modal-footer-gap: #{$modal-footer-margin-between};
--#{$prefix}modal-footer-bg: #{$modal-footer-bg};
--#{$prefix}modal-footer-border-color: #{$modal-footer-border-color};
--#{$prefix}modal-footer-border-width: #{$modal-footer-border-width};
// scss-docs-end modal-css-vars
position: fixed;
top: 0;
left: 0;
z-index: var(--#{$prefix}modal-zindex);
display: none;
width: 100%;
height: 100%;
overflow-x: hidden;
overflow-y: auto;
// Prevent Chrome on Windows from adding a focus outline. For details, see
// https://github.com/twbs/bootstrap/pull/10951.
outline: 0;
// We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a
// gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342
// See also https://github.com/twbs/bootstrap/issues/17695
}
// Shell div to position the modal with bottom padding
.modal-dialog {
position: relative;
width: auto;
margin: var(--#{$prefix}modal-margin);
// allow clicks to pass through for custom click handling to close modal
pointer-events: none;
// When fading in the modal, animate it to slide down
.modal.fade & {
transform: $modal-fade-transform;
@include transition($modal-transition);
}
.modal.show & {
transform: $modal-show-transform;
}
// When trying to close, animate focus to scale
.modal.modal-static & {
transform: $modal-scale-transform;
}
}
.modal-dialog-scrollable {
height: calc(100% - var(--#{$prefix}modal-margin) * 2);
.modal-content {
max-height: 100%;
overflow: hidden;
}
.modal-body {
overflow-y: auto;
}
}
.modal-dialog-centered {
display: flex;
align-items: center;
min-height: calc(100% - var(--#{$prefix}modal-margin) * 2);
}
// Actual modal
.modal-content {
position: relative;
display: flex;
flex-direction: column;
width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog`
// counteract the pointer-events: none; in the .modal-dialog
color: var(--#{$prefix}modal-color);
pointer-events: auto;
background-color: var(--#{$prefix}modal-bg);
background-clip: padding-box;
border: var(--#{$prefix}modal-border-width) solid var(--#{$prefix}modal-border-color);
@include border-radius(var(--#{$prefix}modal-border-radius));
@include box-shadow(var(--#{$prefix}modal-box-shadow));
// Remove focus outline from opened modal
outline: 0;
}
// Modal background
.modal-backdrop {
// scss-docs-start modal-backdrop-css-vars
--#{$prefix}backdrop-zindex: #{$zindex-modal-backdrop};
--#{$prefix}backdrop-bg: #{$modal-backdrop-bg};
--#{$prefix}backdrop-opacity: #{$modal-backdrop-opacity};
// scss-docs-end modal-backdrop-css-vars
@include overlay-backdrop(var(--#{$prefix}backdrop-zindex), var(--#{$prefix}backdrop-bg), var(--#{$prefix}backdrop-opacity));
}
// Modal header
// Top section of the modal w/ title and dismiss
.modal-header {
display: flex;
flex-shrink: 0;
align-items: center;
padding: var(--#{$prefix}modal-header-padding);
border-bottom: var(--#{$prefix}modal-header-border-width) solid var(--#{$prefix}modal-header-border-color);
@include border-top-radius(var(--#{$prefix}modal-inner-border-radius));
.btn-close {
padding: calc(var(--#{$prefix}modal-header-padding-y) * .5) calc(var(--#{$prefix}modal-header-padding-x) * .5);
margin: calc(-.5 * var(--#{$prefix}modal-header-padding-y)) calc(-.5 * var(--#{$prefix}modal-header-padding-x)) calc(-.5 * var(--#{$prefix}modal-header-padding-y)) auto;
}
}
// Title text within header
.modal-title {
margin-bottom: 0;
line-height: var(--#{$prefix}modal-title-line-height);
}
// Modal body
// Where all modal content resides (sibling of .modal-header and .modal-footer)
.modal-body {
position: relative;
// Enable `flex-grow: 1` so that the body take up as much space as possible
// when there should be a fixed height on `.modal-dialog`.
flex: 1 1 auto;
padding: var(--#{$prefix}modal-padding);
}
// Footer (for actions)
.modal-footer {
display: flex;
flex-shrink: 0;
flex-wrap: wrap;
align-items: center; // vertically center
justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items
padding: calc(var(--#{$prefix}modal-padding) - var(--#{$prefix}modal-footer-gap) * .5);
background-color: var(--#{$prefix}modal-footer-bg);
border-top: var(--#{$prefix}modal-footer-border-width) solid var(--#{$prefix}modal-footer-border-color);
@include border-bottom-radius(var(--#{$prefix}modal-inner-border-radius));
// Place margin between footer elements
// This solution is far from ideal because of the universal selector usage,
// but is needed to fix https://github.com/twbs/bootstrap/issues/24800
> * {
margin: calc(var(--#{$prefix}modal-footer-gap) * .5); // Todo in v6: replace with gap on parent class
}
}
// Scale up the modal
@include media-breakpoint-up(sm) {
.modal { .modal {
--#{$prefix}modal-margin: #{$modal-dialog-margin-y-sm-up}; // scss-docs-start modal-css-vars
--#{$prefix}modal-box-shadow: #{$modal-content-box-shadow-sm-up}; --#{$prefix}modal-zindex: #{$zindex-modal};
--#{$prefix}modal-width: #{$modal-md};
--#{$prefix}modal-padding: #{$modal-inner-padding};
--#{$prefix}modal-margin: #{$modal-dialog-margin};
--#{$prefix}modal-color: #{$modal-content-color};
--#{$prefix}modal-bg: #{$modal-content-bg};
--#{$prefix}modal-border-color: #{$modal-content-border-color};
--#{$prefix}modal-border-width: #{$modal-content-border-width};
--#{$prefix}modal-border-radius: #{$modal-content-border-radius};
--#{$prefix}modal-box-shadow: #{$modal-content-box-shadow-xs};
--#{$prefix}modal-inner-border-radius: #{$modal-content-inner-border-radius};
--#{$prefix}modal-header-padding-x: #{$modal-header-padding-x};
--#{$prefix}modal-header-padding-y: #{$modal-header-padding-y};
--#{$prefix}modal-header-padding: #{$modal-header-padding}; // Todo in v6: Split this padding into x and y
--#{$prefix}modal-header-border-color: #{$modal-header-border-color};
--#{$prefix}modal-header-border-width: #{$modal-header-border-width};
--#{$prefix}modal-title-line-height: #{$modal-title-line-height};
--#{$prefix}modal-footer-gap: #{$modal-footer-margin-between};
--#{$prefix}modal-footer-bg: #{$modal-footer-bg};
--#{$prefix}modal-footer-border-color: #{$modal-footer-border-color};
--#{$prefix}modal-footer-border-width: #{$modal-footer-border-width};
// scss-docs-end modal-css-vars
position: fixed;
top: 0;
left: 0;
z-index: var(--#{$prefix}modal-zindex);
display: none;
width: 100%;
height: 100%;
overflow-x: hidden;
overflow-y: auto;
// Prevent Chrome on Windows from adding a focus outline. For details, see
// https://github.com/twbs/bootstrap/pull/10951.
outline: 0;
// We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a
// gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342
// See also https://github.com/twbs/bootstrap/issues/17695
} }
// Automatically set modal's width for larger viewports // Shell div to position the modal with bottom padding
.modal-dialog { .modal-dialog {
max-width: var(--#{$prefix}modal-width); position: relative;
margin-right: auto; width: auto;
margin-left: auto; margin: var(--#{$prefix}modal-margin);
// allow clicks to pass through for custom click handling to close modal
pointer-events: none;
// When fading in the modal, animate it to slide down
.modal.fade & {
transform: $modal-fade-transform;
@include transition($modal-transition);
}
.modal.show & {
transform: $modal-show-transform;
}
// When trying to close, animate focus to scale
.modal.modal-static & {
transform: $modal-scale-transform;
}
} }
.modal-sm { .modal-dialog-scrollable {
--#{$prefix}modal-width: #{$modal-sm}; height: calc(100% - var(--#{$prefix}modal-margin) * 2);
.modal-content {
max-height: 100%;
overflow: hidden;
}
.modal-body {
overflow-y: auto;
}
} }
}
@include media-breakpoint-up(lg) { .modal-dialog-centered {
.modal-lg, display: flex;
.modal-xl { align-items: center;
--#{$prefix}modal-width: #{$modal-lg}; min-height: calc(100% - var(--#{$prefix}modal-margin) * 2);
} }
}
@include media-breakpoint-up(xl) { // Actual modal
.modal-xl { .modal-content {
--#{$prefix}modal-width: #{$modal-xl}; position: relative;
display: flex;
flex-direction: column;
width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog`
// counteract the pointer-events: none; in the .modal-dialog
color: var(--#{$prefix}modal-color);
pointer-events: auto;
background-color: var(--#{$prefix}modal-bg);
background-clip: padding-box;
border: var(--#{$prefix}modal-border-width) solid var(--#{$prefix}modal-border-color);
@include border-radius(var(--#{$prefix}modal-border-radius));
@include box-shadow(var(--#{$prefix}modal-box-shadow));
// Remove focus outline from opened modal
outline: 0;
} }
}
// scss-docs-start modal-fullscreen-loop // Modal background
@each $breakpoint in map.keys($grid-breakpoints) { .modal-backdrop {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints); // scss-docs-start modal-backdrop-css-vars
$postfix: if($infix != "", $infix + "-down", ""); --#{$prefix}backdrop-zindex: #{$zindex-modal-backdrop};
--#{$prefix}backdrop-bg: #{$modal-backdrop-bg};
--#{$prefix}backdrop-opacity: #{$modal-backdrop-opacity};
// scss-docs-end modal-backdrop-css-vars
@include media-breakpoint-down($breakpoint) { @include overlay-backdrop(var(--#{$prefix}backdrop-zindex), var(--#{$prefix}backdrop-bg), var(--#{$prefix}backdrop-opacity));
.modal-fullscreen#{$postfix} { }
width: 100vw;
max-width: none;
height: 100%;
margin: 0;
.modal-content { // Modal header
// Top section of the modal w/ title and dismiss
.modal-header {
display: flex;
flex-shrink: 0;
align-items: center;
padding: var(--#{$prefix}modal-header-padding);
border-bottom: var(--#{$prefix}modal-header-border-width) solid var(--#{$prefix}modal-header-border-color);
@include border-top-radius(var(--#{$prefix}modal-inner-border-radius));
.btn-close {
padding: calc(var(--#{$prefix}modal-header-padding-y) * .5) calc(var(--#{$prefix}modal-header-padding-x) * .5);
margin: calc(-.5 * var(--#{$prefix}modal-header-padding-y)) calc(-.5 * var(--#{$prefix}modal-header-padding-x)) calc(-.5 * var(--#{$prefix}modal-header-padding-y)) auto;
}
}
// Title text within header
.modal-title {
margin-bottom: 0;
line-height: var(--#{$prefix}modal-title-line-height);
}
// Modal body
// Where all modal content resides (sibling of .modal-header and .modal-footer)
.modal-body {
position: relative;
// Enable `flex-grow: 1` so that the body take up as much space as possible
// when there should be a fixed height on `.modal-dialog`.
flex: 1 1 auto;
padding: var(--#{$prefix}modal-padding);
}
// Footer (for actions)
.modal-footer {
display: flex;
flex-shrink: 0;
flex-wrap: wrap;
align-items: center; // vertically center
justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items
padding: calc(var(--#{$prefix}modal-padding) - var(--#{$prefix}modal-footer-gap) * .5);
background-color: var(--#{$prefix}modal-footer-bg);
border-top: var(--#{$prefix}modal-footer-border-width) solid var(--#{$prefix}modal-footer-border-color);
@include border-bottom-radius(var(--#{$prefix}modal-inner-border-radius));
// Place margin between footer elements
// This solution is far from ideal because of the universal selector usage,
// but is needed to fix https://github.com/twbs/bootstrap/issues/24800
> * {
margin: calc(var(--#{$prefix}modal-footer-gap) * .5); // Todo in v6: replace with gap on parent class
}
}
// Scale up the modal
@include media-breakpoint-up(sm) {
.modal {
--#{$prefix}modal-margin: #{$modal-dialog-margin-y-sm-up};
--#{$prefix}modal-box-shadow: #{$modal-content-box-shadow-sm-up};
}
// Automatically set modal's width for larger viewports
.modal-dialog {
max-width: var(--#{$prefix}modal-width);
margin-right: auto;
margin-left: auto;
}
.modal-sm {
--#{$prefix}modal-width: #{$modal-sm};
}
}
@include media-breakpoint-up(lg) {
.modal-lg,
.modal-xl {
--#{$prefix}modal-width: #{$modal-lg};
}
}
@include media-breakpoint-up(xl) {
.modal-xl {
--#{$prefix}modal-width: #{$modal-xl};
}
}
// scss-docs-start modal-fullscreen-loop
@each $breakpoint in map.keys($grid-breakpoints) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
$postfix: if($infix != "", $infix + "-down", "");
@include media-breakpoint-down($breakpoint) {
.modal-fullscreen#{$postfix} {
width: 100vw;
max-width: none;
height: 100%; height: 100%;
border: 0; margin: 0;
@include border-radius(0);
}
.modal-header, .modal-content {
.modal-footer { height: 100%;
@include border-radius(0); border: 0;
} @include border-radius(0);
}
.modal-body { .modal-header,
overflow-y: auto; .modal-footer {
@include border-radius(0);
}
.modal-body {
overflow-y: auto;
}
} }
} }
} }
// scss-docs-end modal-fullscreen-loop
} }
// scss-docs-end modal-fullscreen-loop

View File

@ -10,195 +10,197 @@
// Kickstart any navigation component with a set of style resets. Works with // Kickstart any navigation component with a set of style resets. Works with
// `<nav>`s, `<ul>`s or `<ol>`s. // `<nav>`s, `<ul>`s or `<ol>`s.
.nav { @layer components {
// scss-docs-start nav-css-vars .nav {
--#{$prefix}nav-link-padding-x: #{$nav-link-padding-x}; // scss-docs-start nav-css-vars
--#{$prefix}nav-link-padding-y: #{$nav-link-padding-y}; --#{$prefix}nav-link-padding-x: #{$nav-link-padding-x};
@include rfs($nav-link-font-size, --#{$prefix}nav-link-font-size); --#{$prefix}nav-link-padding-y: #{$nav-link-padding-y};
--#{$prefix}nav-link-font-weight: #{$nav-link-font-weight}; @include rfs($nav-link-font-size, --#{$prefix}nav-link-font-size);
--#{$prefix}nav-link-color: #{$nav-link-color}; --#{$prefix}nav-link-font-weight: #{$nav-link-font-weight};
--#{$prefix}nav-link-hover-color: #{$nav-link-hover-color}; --#{$prefix}nav-link-color: #{$nav-link-color};
--#{$prefix}nav-link-disabled-color: #{$nav-link-disabled-color}; --#{$prefix}nav-link-hover-color: #{$nav-link-hover-color};
// scss-docs-end nav-css-vars --#{$prefix}nav-link-disabled-color: #{$nav-link-disabled-color};
// scss-docs-end nav-css-vars
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
padding-left: 0; padding-left: 0;
margin-bottom: 0; margin-bottom: 0;
list-style: none; list-style: none;
}
.nav-link {
display: block;
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: if($link-decoration == none, null, none);
background: none;
border: 0;
@include transition($nav-link-transition);
&:hover,
&:focus {
color: var(--#{$prefix}nav-link-hover-color);
text-decoration: if($link-hover-decoration == underline, none, null);
} }
&:focus-visible {
outline: 0;
box-shadow: $nav-link-focus-box-shadow;
}
// Disabled state lightens text
&.disabled,
&:disabled {
color: var(--#{$prefix}nav-link-disabled-color);
pointer-events: none;
cursor: default;
}
}
//
// Tabs
//
.nav-tabs {
// scss-docs-start nav-tabs-css-vars
--#{$prefix}nav-tabs-border-width: #{$nav-tabs-border-width};
--#{$prefix}nav-tabs-border-color: #{$nav-tabs-border-color};
--#{$prefix}nav-tabs-border-radius: #{$nav-tabs-border-radius};
--#{$prefix}nav-tabs-link-hover-border-color: #{$nav-tabs-link-hover-border-color};
--#{$prefix}nav-tabs-link-active-color: #{$nav-tabs-link-active-color};
--#{$prefix}nav-tabs-link-active-bg: #{$nav-tabs-link-active-bg};
--#{$prefix}nav-tabs-link-active-border-color: #{$nav-tabs-link-active-border-color};
// scss-docs-end nav-tabs-css-vars
border-bottom: var(--#{$prefix}nav-tabs-border-width) solid var(--#{$prefix}nav-tabs-border-color);
.nav-link { .nav-link {
margin-bottom: calc(-1 * var(--#{$prefix}nav-tabs-border-width)); // stylelint-disable-line function-disallowed-list display: block;
border: var(--#{$prefix}nav-tabs-border-width) solid transparent; padding: var(--#{$prefix}nav-link-padding-y) var(--#{$prefix}nav-link-padding-x);
@include border-top-radius(var(--#{$prefix}nav-tabs-border-radius)); @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: if($link-decoration == none, null, none);
background: none;
border: 0;
@include transition($nav-link-transition);
&:hover, &:hover,
&:focus { &:focus {
// Prevents active .nav-link tab overlapping focus outline of previous/next .nav-link color: var(--#{$prefix}nav-link-hover-color);
isolation: isolate; text-decoration: if($link-hover-decoration == underline, none, null);
border-color: var(--#{$prefix}nav-tabs-link-hover-border-color); }
&:focus-visible {
outline: 0;
box-shadow: $nav-link-focus-box-shadow;
}
// Disabled state lightens text
&.disabled,
&:disabled {
color: var(--#{$prefix}nav-link-disabled-color);
pointer-events: none;
cursor: default;
} }
} }
.nav-link.active, //
.nav-item.show .nav-link { // Tabs
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); .nav-tabs {
// scss-docs-start nav-tabs-css-vars
--#{$prefix}nav-tabs-border-width: #{$nav-tabs-border-width};
--#{$prefix}nav-tabs-border-color: #{$nav-tabs-border-color};
--#{$prefix}nav-tabs-border-radius: #{$nav-tabs-border-radius};
--#{$prefix}nav-tabs-link-hover-border-color: #{$nav-tabs-link-hover-border-color};
--#{$prefix}nav-tabs-link-active-color: #{$nav-tabs-link-active-color};
--#{$prefix}nav-tabs-link-active-bg: #{$nav-tabs-link-active-bg};
--#{$prefix}nav-tabs-link-active-border-color: #{$nav-tabs-link-active-border-color};
// scss-docs-end nav-tabs-css-vars
border-bottom: var(--#{$prefix}nav-tabs-border-width) solid var(--#{$prefix}nav-tabs-border-color);
.nav-link {
margin-bottom: calc(-1 * var(--#{$prefix}nav-tabs-border-width)); // stylelint-disable-line function-disallowed-list
border: var(--#{$prefix}nav-tabs-border-width) solid transparent;
@include border-top-radius(var(--#{$prefix}nav-tabs-border-radius));
&:hover,
&:focus {
// 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);
}
}
.nav-link.active,
.nav-item.show .nav-link {
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);
}
.dropdown-menu {
// Make dropdown border overlap tab border
margin-top: calc(-1 * var(--#{$prefix}nav-tabs-border-width)); // stylelint-disable-line function-disallowed-list
// Remove the top rounded corners here since there is a hard edge above the menu
@include border-top-radius(0);
}
} }
.dropdown-menu {
// Make dropdown border overlap tab border
margin-top: calc(-1 * var(--#{$prefix}nav-tabs-border-width)); // stylelint-disable-line function-disallowed-list
// Remove the top rounded corners here since there is a hard edge above the menu
@include border-top-radius(0);
}
}
//
// Pills
//
// .nav-pills {
// 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-pills { .nav-link {
// scss-docs-start nav-pills-css-vars @include border-radius(var(--#{$prefix}nav-pills-border-radius));
--#{$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 { .nav-link.active,
@include border-radius(var(--#{$prefix}nav-pills-border-radius)); .show > .nav-link {
color: var(--#{$prefix}nav-pills-link-active-color);
@include gradient-bg(var(--#{$prefix}nav-pills-link-active-bg));
}
} }
.nav-link.active,
.show > .nav-link {
color: var(--#{$prefix}nav-pills-link-active-color);
@include gradient-bg(var(--#{$prefix}nav-pills-link-active-bg));
}
}
//
// Underline
//
// .nav-underline {
// Underline // scss-docs-start nav-underline-css-vars
// --#{$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
.nav-underline { gap: var(--#{$prefix}nav-underline-gap);
// scss-docs-start nav-underline-css-vars
--#{$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-right: 0;
padding-left: 0;
border-bottom: var(--#{$prefix}nav-underline-border-width) solid transparent;
.nav-link { &:hover,
padding-right: 0; &:focus {
padding-left: 0; border-bottom-color: currentcolor;
border-bottom: var(--#{$prefix}nav-underline-border-width) solid transparent; }
}
&:hover, .nav-link.active,
&:focus { .show > .nav-link {
font-weight: $font-weight-bold;
color: var(--#{$prefix}nav-underline-link-active-color);
border-bottom-color: currentcolor; border-bottom-color: currentcolor;
} }
} }
.nav-link.active,
.show > .nav-link { //
font-weight: $font-weight-bold; // Justified variants
color: var(--#{$prefix}nav-underline-link-active-color); //
border-bottom-color: currentcolor;
} .nav-fill {
} > .nav-link,
.nav-item {
flex: 1 1 auto;
// text-align: center;
// Justified variants }
// }
.nav-fill { .nav-justified {
> .nav-link, > .nav-link,
.nav-item { .nav-item {
flex: 1 1 auto; flex-grow: 1;
text-align: center; flex-basis: 0;
} text-align: center;
} }
}
.nav-justified {
> .nav-link, .nav-fill,
.nav-item { .nav-justified {
flex-grow: 1; .nav-item .nav-link {
flex-basis: 0; width: 100%; // Make sure button will grow
text-align: center; }
} }
}
.nav-fill, // Tabbable tabs
.nav-justified { //
.nav-item .nav-link { // Hide tabbable panes to start, show them when `.active`
width: 100%; // Make sure button will grow
} .tab-content {
} > .tab-pane {
display: none;
}
// Tabbable tabs > .active {
// display: block;
// Hide tabbable panes to start, show them when `.active` }
.tab-content {
> .tab-pane {
display: none;
}
> .active {
display: block;
} }
} }

View File

@ -15,287 +15,289 @@
// Provide a static navbar from which we expand to create full-width, fixed, and // Provide a static navbar from which we expand to create full-width, fixed, and
// other navbar variations. // other navbar variations.
.navbar { @layer components {
// scss-docs-start navbar-css-vars .navbar {
--#{$prefix}navbar-padding-x: #{if($navbar-padding-x == null, 0, $navbar-padding-x)}; // scss-docs-start navbar-css-vars
--#{$prefix}navbar-padding-y: #{$navbar-padding-y}; --#{$prefix}navbar-padding-x: #{if($navbar-padding-x == null, 0, $navbar-padding-x)};
--#{$prefix}navbar-color: #{$navbar-light-color}; --#{$prefix}navbar-padding-y: #{$navbar-padding-y};
--#{$prefix}navbar-hover-color: #{$navbar-light-hover-color}; --#{$prefix}navbar-color: #{$navbar-light-color};
--#{$prefix}navbar-disabled-color: #{$navbar-light-disabled-color}; --#{$prefix}navbar-hover-color: #{$navbar-light-hover-color};
--#{$prefix}navbar-active-color: #{$navbar-light-active-color}; --#{$prefix}navbar-disabled-color: #{$navbar-light-disabled-color};
--#{$prefix}navbar-brand-padding-y: #{$navbar-brand-padding-y}; --#{$prefix}navbar-active-color: #{$navbar-light-active-color};
--#{$prefix}navbar-brand-margin-end: #{$navbar-brand-margin-end}; --#{$prefix}navbar-brand-padding-y: #{$navbar-brand-padding-y};
--#{$prefix}navbar-brand-font-size: #{$navbar-brand-font-size}; --#{$prefix}navbar-brand-margin-end: #{$navbar-brand-margin-end};
--#{$prefix}navbar-brand-color: #{$navbar-light-brand-color}; --#{$prefix}navbar-brand-font-size: #{$navbar-brand-font-size};
--#{$prefix}navbar-brand-hover-color: #{$navbar-light-brand-hover-color}; --#{$prefix}navbar-brand-color: #{$navbar-light-brand-color};
--#{$prefix}navbar-nav-link-padding-x: #{$navbar-nav-link-padding-x}; --#{$prefix}navbar-brand-hover-color: #{$navbar-light-brand-hover-color};
--#{$prefix}navbar-toggler-padding-y: #{$navbar-toggler-padding-y}; --#{$prefix}navbar-nav-link-padding-x: #{$navbar-nav-link-padding-x};
--#{$prefix}navbar-toggler-padding-x: #{$navbar-toggler-padding-x}; --#{$prefix}navbar-toggler-padding-y: #{$navbar-toggler-padding-y};
--#{$prefix}navbar-toggler-font-size: #{$navbar-toggler-font-size}; --#{$prefix}navbar-toggler-padding-x: #{$navbar-toggler-padding-x};
--#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-light-toggler-icon-bg)}; --#{$prefix}navbar-toggler-font-size: #{$navbar-toggler-font-size};
--#{$prefix}navbar-toggler-border-color: #{$navbar-light-toggler-border-color}; --#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-light-toggler-icon-bg)};
--#{$prefix}navbar-toggler-border-radius: #{$navbar-toggler-border-radius}; --#{$prefix}navbar-toggler-border-color: #{$navbar-light-toggler-border-color};
--#{$prefix}navbar-toggler-focus-width: #{$navbar-toggler-focus-width}; --#{$prefix}navbar-toggler-border-radius: #{$navbar-toggler-border-radius};
--#{$prefix}navbar-toggler-transition: #{$navbar-toggler-transition}; --#{$prefix}navbar-toggler-focus-width: #{$navbar-toggler-focus-width};
// scss-docs-end navbar-css-vars --#{$prefix}navbar-toggler-transition: #{$navbar-toggler-transition};
// scss-docs-end navbar-css-vars
position: relative; position: relative;
display: flex;
flex-wrap: wrap; // allow us to do the line break for collapsing content
align-items: center;
justify-content: space-between; // space out brand from logo
padding: var(--#{$prefix}navbar-padding-y) var(--#{$prefix}navbar-padding-x);
@include gradient-bg();
// Because flex properties aren't inherited, we need to redeclare these first
// few properties so that content nested within behave properly.
// The `flex-wrap` property is inherited to simplify the expanded navbars
%container-flex-properties {
display: flex; display: flex;
flex-wrap: inherit; flex-wrap: wrap; // allow us to do the line break for collapsing content
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between; // space out brand from logo
} padding: var(--#{$prefix}navbar-padding-y) var(--#{$prefix}navbar-padding-x);
@include gradient-bg();
> .container, // Because flex properties aren't inherited, we need to redeclare these first
> .container-fluid { // few properties so that content nested within behave properly.
@extend %container-flex-properties; // The `flex-wrap` property is inherited to simplify the expanded navbars
} %container-flex-properties {
display: flex;
flex-wrap: inherit;
align-items: center;
justify-content: space-between;
}
@each $breakpoint, $container-max-width in $container-max-widths { > .container,
> .container#{breakpoint-infix($breakpoint, $container-max-widths)} { > .container-fluid {
@extend %container-flex-properties; @extend %container-flex-properties;
} }
@each $breakpoint, $container-max-width in $container-max-widths {
> .container#{breakpoint-infix($breakpoint, $container-max-widths)} {
@extend %container-flex-properties;
}
}
} }
}
// Navbar brand // Navbar brand
// //
// Used for brand, project, or site names. // Used for brand, project, or site names.
.navbar-brand { .navbar-brand {
padding-top: var(--#{$prefix}navbar-brand-padding-y); padding-top: var(--#{$prefix}navbar-brand-padding-y);
padding-bottom: var(--#{$prefix}navbar-brand-padding-y); padding-bottom: var(--#{$prefix}navbar-brand-padding-y);
margin-right: var(--#{$prefix}navbar-brand-margin-end); margin-right: var(--#{$prefix}navbar-brand-margin-end);
@include font-size(var(--#{$prefix}navbar-brand-font-size)); @include font-size(var(--#{$prefix}navbar-brand-font-size));
color: var(--#{$prefix}navbar-brand-color); color: var(--#{$prefix}navbar-brand-color);
text-decoration: if($link-decoration == none, null, none); text-decoration: if($link-decoration == none, null, none);
white-space: nowrap; white-space: nowrap;
&:hover, &:hover,
&:focus { &:focus {
color: var(--#{$prefix}navbar-brand-hover-color); color: var(--#{$prefix}navbar-brand-hover-color);
text-decoration: if($link-hover-decoration == underline, none, null); text-decoration: if($link-hover-decoration == underline, none, null);
}
} }
}
// Navbar nav // Navbar nav
// //
// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`). // Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`).
.navbar-nav { .navbar-nav {
// scss-docs-start navbar-nav-css-vars // scss-docs-start navbar-nav-css-vars
--#{$prefix}nav-link-padding-x: 0; --#{$prefix}nav-link-padding-x: 0;
--#{$prefix}nav-link-padding-y: #{$nav-link-padding-y}; --#{$prefix}nav-link-padding-y: #{$nav-link-padding-y};
@include rfs($nav-link-font-size, --#{$prefix}nav-link-font-size); @include rfs($nav-link-font-size, --#{$prefix}nav-link-font-size);
--#{$prefix}nav-link-font-weight: #{$nav-link-font-weight}; --#{$prefix}nav-link-font-weight: #{$nav-link-font-weight};
--#{$prefix}nav-link-color: var(--#{$prefix}navbar-color); --#{$prefix}nav-link-color: var(--#{$prefix}navbar-color);
--#{$prefix}nav-link-hover-color: var(--#{$prefix}navbar-hover-color); --#{$prefix}nav-link-hover-color: var(--#{$prefix}navbar-hover-color);
--#{$prefix}nav-link-disabled-color: var(--#{$prefix}navbar-disabled-color); --#{$prefix}nav-link-disabled-color: var(--#{$prefix}navbar-disabled-color);
// scss-docs-end navbar-nav-css-vars // scss-docs-end navbar-nav-css-vars
display: flex; display: flex;
flex-direction: column; // cannot use `inherit` to get the `.navbar`s value flex-direction: column; // cannot use `inherit` to get the `.navbar`s value
padding-left: 0; padding-left: 0;
margin-bottom: 0; margin-bottom: 0;
list-style: none; list-style: none;
.nav-link { .nav-link {
&.active, &.active,
&.show { &.show {
color: var(--#{$prefix}navbar-active-color);
}
}
.dropdown-menu {
position: static;
}
}
// Navbar text
//
//
.navbar-text {
padding-top: $nav-link-padding-y;
padding-bottom: $nav-link-padding-y;
color: var(--#{$prefix}navbar-color);
a,
a:hover,
a:focus {
color: var(--#{$prefix}navbar-active-color); color: var(--#{$prefix}navbar-active-color);
} }
} }
.dropdown-menu {
position: static;
}
}
// Responsive navbar
//
// Custom styles for responsive collapsing and toggling of navbar contents.
// Powered by the collapse Bootstrap JavaScript plugin.
// Navbar text // When collapsed, prevent the toggleable navbar contents from appearing in
// // the default flexbox row orientation. Requires the use of `flex-wrap: wrap`
// // on the `.navbar` parent.
.navbar-collapse {
.navbar-text { flex-grow: 1;
padding-top: $nav-link-padding-y; flex-basis: 100%;
padding-bottom: $nav-link-padding-y; // For always expanded or extra full navbars, ensure content aligns itself
color: var(--#{$prefix}navbar-color); // properly vertically. Can be easily overridden with flex utilities.
align-items: center;
a,
a:hover,
a:focus {
color: var(--#{$prefix}navbar-active-color);
}
}
// Responsive navbar
//
// Custom styles for responsive collapsing and toggling of navbar contents.
// Powered by the collapse Bootstrap JavaScript plugin.
// When collapsed, prevent the toggleable navbar contents from appearing in
// the default flexbox row orientation. Requires the use of `flex-wrap: wrap`
// on the `.navbar` parent.
.navbar-collapse {
flex-grow: 1;
flex-basis: 100%;
// For always expanded or extra full navbars, ensure content aligns itself
// properly vertically. Can be easily overridden with flex utilities.
align-items: center;
}
// Button for toggling the navbar when in its collapsed state
.navbar-toggler {
padding: var(--#{$prefix}navbar-toggler-padding-y) var(--#{$prefix}navbar-toggler-padding-x);
@include font-size(var(--#{$prefix}navbar-toggler-font-size));
line-height: 1;
color: var(--#{$prefix}navbar-color);
background-color: transparent; // remove default button style
border: var(--#{$prefix}border-width) solid var(--#{$prefix}navbar-toggler-border-color); // remove default button style
@include border-radius(var(--#{$prefix}navbar-toggler-border-radius));
@include transition(var(--#{$prefix}navbar-toggler-transition));
&:hover {
text-decoration: none;
} }
&:focus { // Button for toggling the navbar when in its collapsed state
text-decoration: none; .navbar-toggler {
outline: 0; padding: var(--#{$prefix}navbar-toggler-padding-y) var(--#{$prefix}navbar-toggler-padding-x);
box-shadow: 0 0 0 var(--#{$prefix}navbar-toggler-focus-width); @include font-size(var(--#{$prefix}navbar-toggler-font-size));
line-height: 1;
color: var(--#{$prefix}navbar-color);
background-color: transparent; // remove default button style
border: var(--#{$prefix}border-width) solid var(--#{$prefix}navbar-toggler-border-color); // remove default button style
@include border-radius(var(--#{$prefix}navbar-toggler-border-radius));
@include transition(var(--#{$prefix}navbar-toggler-transition));
&:hover {
text-decoration: none;
}
&:focus {
text-decoration: none;
outline: 0;
box-shadow: 0 0 0 var(--#{$prefix}navbar-toggler-focus-width);
}
} }
}
// Keep as a separate element so folks can easily override it with another icon // Keep as a separate element so folks can easily override it with another icon
// or image file as needed. // or image file as needed.
.navbar-toggler-icon { .navbar-toggler-icon {
display: inline-block; display: inline-block;
width: 1.5em; width: 1.5em;
height: 1.5em; height: 1.5em;
vertical-align: middle; vertical-align: middle;
background-image: var(--#{$prefix}navbar-toggler-icon-bg); background-image: var(--#{$prefix}navbar-toggler-icon-bg);
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;
background-size: 100%; background-size: 100%;
} }
.navbar-nav-scroll { .navbar-nav-scroll {
max-height: var(--#{$prefix}scroll-height, 75vh); max-height: var(--#{$prefix}scroll-height, 75vh);
overflow-y: auto; overflow-y: auto;
} }
// scss-docs-start navbar-expand-loop // scss-docs-start navbar-expand-loop
// Generate series of `.navbar-expand-*` responsive classes for configuring // Generate series of `.navbar-expand-*` responsive classes for configuring
// where your navbar collapses. // where your navbar collapses.
.navbar-expand { .navbar-expand {
@each $breakpoint in map.keys($grid-breakpoints) { @each $breakpoint in map.keys($grid-breakpoints) {
$next: breakpoint-next($breakpoint, $grid-breakpoints); $next: breakpoint-next($breakpoint, $grid-breakpoints);
$infix: breakpoint-infix($next, $grid-breakpoints); $infix: breakpoint-infix($next, $grid-breakpoints);
// stylelint-disable-next-line scss/selector-no-union-class-name // stylelint-disable-next-line scss/selector-no-union-class-name
&#{$infix} { &#{$infix} {
@include media-breakpoint-up($next) { @include media-breakpoint-up($next) {
flex-wrap: nowrap; flex-wrap: nowrap;
justify-content: flex-start; justify-content: flex-start;
.navbar-nav { .navbar-nav {
flex-direction: row; flex-direction: row;
.dropdown-menu { .dropdown-menu {
position: absolute; position: absolute;
}
.nav-link {
padding-right: var(--#{$prefix}navbar-nav-link-padding-x);
padding-left: var(--#{$prefix}navbar-nav-link-padding-x);
}
} }
.nav-link { .navbar-nav-scroll {
padding-right: var(--#{$prefix}navbar-nav-link-padding-x); overflow: visible;
padding-left: var(--#{$prefix}navbar-nav-link-padding-x);
} }
}
.navbar-nav-scroll { .navbar-collapse {
overflow: visible; display: flex !important; // stylelint-disable-line declaration-no-important
} flex-basis: auto;
}
.navbar-collapse { .navbar-toggler {
display: flex !important; // stylelint-disable-line declaration-no-important
flex-basis: auto;
}
.navbar-toggler {
display: none;
}
.offcanvas {
// stylelint-disable declaration-no-important
position: static;
z-index: auto;
flex-grow: 1;
width: auto !important;
height: auto !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
.offcanvas-header {
display: none; display: none;
} }
.offcanvas-body { .offcanvas {
display: flex; // stylelint-disable declaration-no-important
flex-grow: 0; position: static;
padding: 0; z-index: auto;
overflow-y: visible; flex-grow: 1;
width: auto !important;
height: auto !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
.offcanvas-header {
display: none;
}
.offcanvas-body {
display: flex;
flex-grow: 0;
padding: 0;
overflow-y: visible;
}
} }
} }
} }
} }
} }
} // scss-docs-end navbar-expand-loop
// scss-docs-end navbar-expand-loop
// Navbar themes // Navbar themes
// //
// Styles for switching between navbars with light or dark background. // Styles for switching between navbars with light or dark background.
.navbar-light { .navbar-light {
@include deprecate("`.navbar-light`", "v5.2.0", "v6.0.0", true); @include deprecate("`.navbar-light`", "v5.2.0", "v6.0.0", true);
} }
.navbar-dark, .navbar-dark,
.navbar[data-bs-theme="dark"] { .navbar[data-bs-theme="dark"] {
// scss-docs-start navbar-dark-css-vars // scss-docs-start navbar-dark-css-vars
--#{$prefix}navbar-color: #{$navbar-dark-color}; --#{$prefix}navbar-color: #{$navbar-dark-color};
--#{$prefix}navbar-hover-color: #{$navbar-dark-hover-color}; --#{$prefix}navbar-hover-color: #{$navbar-dark-hover-color};
--#{$prefix}navbar-disabled-color: #{$navbar-dark-disabled-color}; --#{$prefix}navbar-disabled-color: #{$navbar-dark-disabled-color};
--#{$prefix}navbar-active-color: #{$navbar-dark-active-color}; --#{$prefix}navbar-active-color: #{$navbar-dark-active-color};
--#{$prefix}navbar-brand-color: #{$navbar-dark-brand-color}; --#{$prefix}navbar-brand-color: #{$navbar-dark-brand-color};
--#{$prefix}navbar-brand-hover-color: #{$navbar-dark-brand-hover-color}; --#{$prefix}navbar-brand-hover-color: #{$navbar-dark-brand-hover-color};
--#{$prefix}navbar-toggler-border-color: #{$navbar-dark-toggler-border-color}; --#{$prefix}navbar-toggler-border-color: #{$navbar-dark-toggler-border-color};
--#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-dark-toggler-icon-bg)}; --#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-dark-toggler-icon-bg)};
// scss-docs-end navbar-dark-css-vars // scss-docs-end navbar-dark-css-vars
} }
@if $enable-dark-mode { @if $enable-dark-mode {
@include color-mode(dark) { @include color-mode(dark) {
.navbar-toggler-icon { .navbar-toggler-icon {
--#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-dark-toggler-icon-bg)}; --#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-dark-toggler-icon-bg)};
}
} }
} }
} }

View File

@ -8,144 +8,146 @@
// stylelint-disable function-disallowed-list // stylelint-disable function-disallowed-list
%offcanvas-css-vars { @layer components {
// scss-docs-start offcanvas-css-vars %offcanvas-css-vars {
--#{$prefix}offcanvas-zindex: #{$zindex-offcanvas}; // scss-docs-start offcanvas-css-vars
--#{$prefix}offcanvas-width: #{$offcanvas-horizontal-width}; --#{$prefix}offcanvas-zindex: #{$zindex-offcanvas};
--#{$prefix}offcanvas-height: #{$offcanvas-vertical-height}; --#{$prefix}offcanvas-width: #{$offcanvas-horizontal-width};
--#{$prefix}offcanvas-padding-x: #{$offcanvas-padding-x}; --#{$prefix}offcanvas-height: #{$offcanvas-vertical-height};
--#{$prefix}offcanvas-padding-y: #{$offcanvas-padding-y}; --#{$prefix}offcanvas-padding-x: #{$offcanvas-padding-x};
--#{$prefix}offcanvas-color: #{$offcanvas-color}; --#{$prefix}offcanvas-padding-y: #{$offcanvas-padding-y};
--#{$prefix}offcanvas-bg: #{$offcanvas-bg-color}; --#{$prefix}offcanvas-color: #{$offcanvas-color};
--#{$prefix}offcanvas-border-width: #{$offcanvas-border-width}; --#{$prefix}offcanvas-bg: #{$offcanvas-bg-color};
--#{$prefix}offcanvas-border-color: #{$offcanvas-border-color}; --#{$prefix}offcanvas-border-width: #{$offcanvas-border-width};
--#{$prefix}offcanvas-box-shadow: #{$offcanvas-box-shadow}; --#{$prefix}offcanvas-border-color: #{$offcanvas-border-color};
--#{$prefix}offcanvas-transition: #{transform $offcanvas-transition-duration ease-in-out}; --#{$prefix}offcanvas-box-shadow: #{$offcanvas-box-shadow};
--#{$prefix}offcanvas-title-line-height: #{$offcanvas-title-line-height}; --#{$prefix}offcanvas-transition: #{transform $offcanvas-transition-duration ease-in-out};
// scss-docs-end offcanvas-css-vars --#{$prefix}offcanvas-title-line-height: #{$offcanvas-title-line-height};
} // scss-docs-end offcanvas-css-vars
@each $breakpoint in map.keys($grid-breakpoints) {
$next: breakpoint-next($breakpoint, $grid-breakpoints);
$infix: breakpoint-infix($next, $grid-breakpoints);
.offcanvas#{$infix} {
@extend %offcanvas-css-vars;
} }
}
@each $breakpoint in map.keys($grid-breakpoints) { @each $breakpoint in map.keys($grid-breakpoints) {
$next: breakpoint-next($breakpoint, $grid-breakpoints); $next: breakpoint-next($breakpoint, $grid-breakpoints);
$infix: breakpoint-infix($next, $grid-breakpoints); $infix: breakpoint-infix($next, $grid-breakpoints);
.offcanvas#{$infix} { .offcanvas#{$infix} {
@include media-breakpoint-down($next) { @extend %offcanvas-css-vars;
position: fixed;
bottom: 0;
z-index: var(--#{$prefix}offcanvas-zindex);
display: flex;
flex-direction: column;
max-width: 100%;
color: var(--#{$prefix}offcanvas-color);
visibility: hidden;
background-color: var(--#{$prefix}offcanvas-bg);
background-clip: padding-box;
outline: 0;
@include box-shadow(var(--#{$prefix}offcanvas-box-shadow));
@include transition(var(--#{$prefix}offcanvas-transition));
&.offcanvas-start {
top: 0;
left: 0;
width: var(--#{$prefix}offcanvas-width);
border-right: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
transform: translateX(-100%);
}
&.offcanvas-end {
top: 0;
right: 0;
width: var(--#{$prefix}offcanvas-width);
border-left: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
transform: translateX(100%);
}
&.offcanvas-top {
top: 0;
right: 0;
left: 0;
height: var(--#{$prefix}offcanvas-height);
max-height: 100%;
border-bottom: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
transform: translateY(-100%);
}
&.offcanvas-bottom {
right: 0;
left: 0;
height: var(--#{$prefix}offcanvas-height);
max-height: 100%;
border-top: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
transform: translateY(100%);
}
&.showing,
&.show:not(.hiding) {
transform: none;
}
&.showing,
&.hiding,
&.show {
visibility: visible;
}
} }
}
@if not ($infix == "") { @each $breakpoint in map.keys($grid-breakpoints) {
@include media-breakpoint-up($next) { $next: breakpoint-next($breakpoint, $grid-breakpoints);
--#{$prefix}offcanvas-height: auto; $infix: breakpoint-infix($next, $grid-breakpoints);
--#{$prefix}offcanvas-border-width: 0;
background-color: transparent !important; // stylelint-disable-line declaration-no-important
.offcanvas-header { .offcanvas#{$infix} {
display: none; @include media-breakpoint-down($next) {
position: fixed;
bottom: 0;
z-index: var(--#{$prefix}offcanvas-zindex);
display: flex;
flex-direction: column;
max-width: 100%;
color: var(--#{$prefix}offcanvas-color);
visibility: hidden;
background-color: var(--#{$prefix}offcanvas-bg);
background-clip: padding-box;
outline: 0;
@include box-shadow(var(--#{$prefix}offcanvas-box-shadow));
@include transition(var(--#{$prefix}offcanvas-transition));
&.offcanvas-start {
top: 0;
left: 0;
width: var(--#{$prefix}offcanvas-width);
border-right: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
transform: translateX(-100%);
} }
.offcanvas-body { &.offcanvas-end {
display: flex; top: 0;
flex-grow: 0; right: 0;
padding: 0; width: var(--#{$prefix}offcanvas-width);
overflow-y: visible; border-left: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
// Reset `background-color` in case `.bg-*` classes are used in offcanvas transform: translateX(100%);
}
&.offcanvas-top {
top: 0;
right: 0;
left: 0;
height: var(--#{$prefix}offcanvas-height);
max-height: 100%;
border-bottom: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
transform: translateY(-100%);
}
&.offcanvas-bottom {
right: 0;
left: 0;
height: var(--#{$prefix}offcanvas-height);
max-height: 100%;
border-top: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
transform: translateY(100%);
}
&.showing,
&.show:not(.hiding) {
transform: none;
}
&.showing,
&.hiding,
&.show {
visibility: visible;
}
}
@if not ($infix == "") {
@include media-breakpoint-up($next) {
--#{$prefix}offcanvas-height: auto;
--#{$prefix}offcanvas-border-width: 0;
background-color: transparent !important; // stylelint-disable-line declaration-no-important background-color: transparent !important; // stylelint-disable-line declaration-no-important
.offcanvas-header {
display: none;
}
.offcanvas-body {
display: flex;
flex-grow: 0;
padding: 0;
overflow-y: visible;
// Reset `background-color` in case `.bg-*` classes are used in offcanvas
background-color: transparent !important; // stylelint-disable-line declaration-no-important
}
} }
} }
} }
} }
}
.offcanvas-backdrop { .offcanvas-backdrop {
@include overlay-backdrop($zindex-offcanvas-backdrop, $offcanvas-backdrop-bg, $offcanvas-backdrop-opacity); @include overlay-backdrop($zindex-offcanvas-backdrop, $offcanvas-backdrop-bg, $offcanvas-backdrop-opacity);
} }
.offcanvas-header { .offcanvas-header {
display: flex; display: flex;
align-items: center; align-items: center;
padding: var(--#{$prefix}offcanvas-padding-y) var(--#{$prefix}offcanvas-padding-x); padding: var(--#{$prefix}offcanvas-padding-y) var(--#{$prefix}offcanvas-padding-x);
.btn-close { .btn-close {
padding: calc(var(--#{$prefix}offcanvas-padding-y) * .5) calc(var(--#{$prefix}offcanvas-padding-x) * .5); padding: calc(var(--#{$prefix}offcanvas-padding-y) * .5) calc(var(--#{$prefix}offcanvas-padding-x) * .5);
margin: calc(-.5 * var(--#{$prefix}offcanvas-padding-y)) calc(-.5 * var(--#{$prefix}offcanvas-padding-x)) calc(-.5 * var(--#{$prefix}offcanvas-padding-y)) auto; margin: calc(-.5 * var(--#{$prefix}offcanvas-padding-y)) calc(-.5 * var(--#{$prefix}offcanvas-padding-x)) calc(-.5 * var(--#{$prefix}offcanvas-padding-y)) auto;
}
}
.offcanvas-title {
margin-bottom: 0;
line-height: var(--#{$prefix}offcanvas-title-line-height);
}
.offcanvas-body {
flex-grow: 1;
padding: var(--#{$prefix}offcanvas-padding-y) var(--#{$prefix}offcanvas-padding-x);
overflow-y: auto;
} }
} }
.offcanvas-title {
margin-bottom: 0;
line-height: var(--#{$prefix}offcanvas-title-line-height);
}
.offcanvas-body {
flex-grow: 1;
padding: var(--#{$prefix}offcanvas-padding-y) var(--#{$prefix}offcanvas-padding-x);
overflow-y: auto;
}

View File

@ -15,112 +15,114 @@
} }
// scss-docs-end pagination-mixin // scss-docs-end pagination-mixin
.pagination { @layer components {
// scss-docs-start pagination-css-vars .pagination {
--#{$prefix}pagination-padding-x: #{$pagination-padding-x}; // scss-docs-start pagination-css-vars
--#{$prefix}pagination-padding-y: #{$pagination-padding-y}; --#{$prefix}pagination-padding-x: #{$pagination-padding-x};
@include rfs($pagination-font-size, --#{$prefix}pagination-font-size); --#{$prefix}pagination-padding-y: #{$pagination-padding-y};
--#{$prefix}pagination-color: #{$pagination-color}; @include rfs($pagination-font-size, --#{$prefix}pagination-font-size);
--#{$prefix}pagination-bg: #{$pagination-bg}; --#{$prefix}pagination-color: #{$pagination-color};
--#{$prefix}pagination-border-width: #{$pagination-border-width}; --#{$prefix}pagination-bg: #{$pagination-bg};
--#{$prefix}pagination-border-color: #{$pagination-border-color}; --#{$prefix}pagination-border-width: #{$pagination-border-width};
--#{$prefix}pagination-border-radius: #{$pagination-border-radius}; --#{$prefix}pagination-border-color: #{$pagination-border-color};
--#{$prefix}pagination-hover-color: #{$pagination-hover-color}; --#{$prefix}pagination-border-radius: #{$pagination-border-radius};
--#{$prefix}pagination-hover-bg: #{$pagination-hover-bg}; --#{$prefix}pagination-hover-color: #{$pagination-hover-color};
--#{$prefix}pagination-hover-border-color: #{$pagination-hover-border-color}; --#{$prefix}pagination-hover-bg: #{$pagination-hover-bg};
--#{$prefix}pagination-focus-color: #{$pagination-focus-color}; --#{$prefix}pagination-hover-border-color: #{$pagination-hover-border-color};
--#{$prefix}pagination-focus-bg: #{$pagination-focus-bg}; --#{$prefix}pagination-focus-color: #{$pagination-focus-color};
--#{$prefix}pagination-focus-box-shadow: #{$pagination-focus-box-shadow}; --#{$prefix}pagination-focus-bg: #{$pagination-focus-bg};
--#{$prefix}pagination-active-color: #{$pagination-active-color}; --#{$prefix}pagination-focus-box-shadow: #{$pagination-focus-box-shadow};
--#{$prefix}pagination-active-bg: #{$pagination-active-bg}; --#{$prefix}pagination-active-color: #{$pagination-active-color};
--#{$prefix}pagination-active-border-color: #{$pagination-active-border-color}; --#{$prefix}pagination-active-bg: #{$pagination-active-bg};
--#{$prefix}pagination-disabled-color: #{$pagination-disabled-color}; --#{$prefix}pagination-active-border-color: #{$pagination-active-border-color};
--#{$prefix}pagination-disabled-bg: #{$pagination-disabled-bg}; --#{$prefix}pagination-disabled-color: #{$pagination-disabled-color};
--#{$prefix}pagination-disabled-border-color: #{$pagination-disabled-border-color}; --#{$prefix}pagination-disabled-bg: #{$pagination-disabled-bg};
// scss-docs-end pagination-css-vars --#{$prefix}pagination-disabled-border-color: #{$pagination-disabled-border-color};
// scss-docs-end pagination-css-vars
display: flex; display: flex;
@include list-unstyled(); @include list-unstyled();
}
.page-link {
position: relative;
display: block;
padding: var(--#{$prefix}pagination-padding-y) var(--#{$prefix}pagination-padding-x);
@include font-size(var(--#{$prefix}pagination-font-size));
color: var(--#{$prefix}pagination-color);
text-decoration: if($link-decoration == none, null, none);
background-color: var(--#{$prefix}pagination-bg);
border: var(--#{$prefix}pagination-border-width) solid var(--#{$prefix}pagination-border-color);
@include transition($pagination-transition);
&:hover {
z-index: 2;
color: var(--#{$prefix}pagination-hover-color);
text-decoration: if($link-hover-decoration == underline, none, null);
background-color: var(--#{$prefix}pagination-hover-bg);
border-color: var(--#{$prefix}pagination-hover-border-color);
} }
&:focus { .page-link {
z-index: 3; position: relative;
color: var(--#{$prefix}pagination-focus-color); display: block;
background-color: var(--#{$prefix}pagination-focus-bg); padding: var(--#{$prefix}pagination-padding-y) var(--#{$prefix}pagination-padding-x);
outline: $pagination-focus-outline; @include font-size(var(--#{$prefix}pagination-font-size));
box-shadow: var(--#{$prefix}pagination-focus-box-shadow); color: var(--#{$prefix}pagination-color);
text-decoration: if($link-decoration == none, null, none);
background-color: var(--#{$prefix}pagination-bg);
border: var(--#{$prefix}pagination-border-width) solid var(--#{$prefix}pagination-border-color);
@include transition($pagination-transition);
&:hover {
z-index: 2;
color: var(--#{$prefix}pagination-hover-color);
text-decoration: if($link-hover-decoration == underline, none, null);
background-color: var(--#{$prefix}pagination-hover-bg);
border-color: var(--#{$prefix}pagination-hover-border-color);
}
&:focus {
z-index: 3;
color: var(--#{$prefix}pagination-focus-color);
background-color: var(--#{$prefix}pagination-focus-bg);
outline: $pagination-focus-outline;
box-shadow: var(--#{$prefix}pagination-focus-box-shadow);
}
&.active,
.active > & {
z-index: 3;
color: var(--#{$prefix}pagination-active-color);
@include gradient-bg(var(--#{$prefix}pagination-active-bg));
border-color: var(--#{$prefix}pagination-active-border-color);
}
&.disabled,
.disabled > & {
color: var(--#{$prefix}pagination-disabled-color);
pointer-events: none;
background-color: var(--#{$prefix}pagination-disabled-bg);
border-color: var(--#{$prefix}pagination-disabled-border-color);
}
} }
&.active, .page-item {
.active > & { &:not(:first-child) .page-link {
z-index: 3; margin-left: $pagination-margin-start;
color: var(--#{$prefix}pagination-active-color); }
@include gradient-bg(var(--#{$prefix}pagination-active-bg));
border-color: var(--#{$prefix}pagination-active-border-color);
}
&.disabled, @if $pagination-margin-start == calc(-1 * #{$pagination-border-width}) {
.disabled > & { &:first-child {
color: var(--#{$prefix}pagination-disabled-color); .page-link {
pointer-events: none; @include border-start-radius(var(--#{$prefix}pagination-border-radius));
background-color: var(--#{$prefix}pagination-disabled-bg); }
border-color: var(--#{$prefix}pagination-disabled-border-color); }
}
}
.page-item { &:last-child {
&:not(:first-child) .page-link { .page-link {
margin-left: $pagination-margin-start; @include border-end-radius(var(--#{$prefix}pagination-border-radius));
} }
}
@if $pagination-margin-start == calc(-1 * #{$pagination-border-width}) { } @else {
&:first-child { // Add border-radius to all pageLinks in case they have left margin
.page-link { .page-link {
@include border-start-radius(var(--#{$prefix}pagination-border-radius)); @include border-radius(var(--#{$prefix}pagination-border-radius));
} }
} }
}
&:last-child {
.page-link { //
@include border-end-radius(var(--#{$prefix}pagination-border-radius)); // Sizing
} //
}
} @else { .pagination-lg {
// Add border-radius to all pageLinks in case they have left margin @include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $pagination-border-radius-lg);
.page-link { }
@include border-radius(var(--#{$prefix}pagination-border-radius));
} .pagination-sm {
@include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $pagination-border-radius-sm);
} }
} }
//
// Sizing
//
.pagination-lg {
@include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $pagination-border-radius-lg);
}
.pagination-sm {
@include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $pagination-border-radius-sm);
}

View File

@ -2,54 +2,56 @@
@use "colors" as *; @use "colors" as *;
@use "variables" as *; @use "variables" as *;
.placeholder { @layer components {
display: inline-block;
min-height: 1em;
vertical-align: middle;
cursor: wait;
background-color: currentcolor;
opacity: $placeholder-opacity-max;
&.btn::before {
display: inline-block;
content: "";
}
}
// Sizing
.placeholder-xs {
min-height: .6em;
}
.placeholder-sm {
min-height: .8em;
}
.placeholder-lg {
min-height: 1.2em;
}
// Animation
.placeholder-glow {
.placeholder { .placeholder {
animation: placeholder-glow 2s ease-in-out infinite; display: inline-block;
} min-height: 1em;
} vertical-align: middle;
cursor: wait;
@keyframes placeholder-glow { background-color: currentcolor;
50% { opacity: $placeholder-opacity-max;
opacity: $placeholder-opacity-min;
} &.btn::before {
} display: inline-block;
content: "";
.placeholder-wave { }
mask-image: linear-gradient(130deg, $black 55%, rgba(0, 0, 0, (1 - $placeholder-opacity-min)) 75%, $black 95%); }
mask-size: 200% 100%;
animation: placeholder-wave 2s linear infinite; // Sizing
} .placeholder-xs {
min-height: .6em;
@keyframes placeholder-wave { }
100% {
mask-position: -200% 0%; .placeholder-sm {
min-height: .8em;
}
.placeholder-lg {
min-height: 1.2em;
}
// Animation
.placeholder-glow {
.placeholder {
animation: placeholder-glow 2s ease-in-out infinite;
}
}
@keyframes placeholder-glow {
50% {
opacity: $placeholder-opacity-min;
}
}
.placeholder-wave {
mask-image: linear-gradient(130deg, $black 55%, rgba(0, 0, 0, (1 - $placeholder-opacity-min)) 75%, $black 95%);
mask-size: 200% 100%;
animation: placeholder-wave 2s linear infinite;
}
@keyframes placeholder-wave {
100% {
mask-position: -200% 0%;
}
} }
} }

View File

@ -5,199 +5,201 @@
@use "vendor/rfs" as *; @use "vendor/rfs" as *;
@use "mixins/reset-text" as *; @use "mixins/reset-text" as *;
.popover { @layer components {
// scss-docs-start popover-css-vars .popover {
--#{$prefix}popover-zindex: #{$zindex-popover}; // scss-docs-start popover-css-vars
--#{$prefix}popover-max-width: #{$popover-max-width}; --#{$prefix}popover-zindex: #{$zindex-popover};
@include rfs($popover-font-size, --#{$prefix}popover-font-size); --#{$prefix}popover-max-width: #{$popover-max-width};
--#{$prefix}popover-bg: #{$popover-bg}; @include rfs($popover-font-size, --#{$prefix}popover-font-size);
--#{$prefix}popover-border-width: #{$popover-border-width}; --#{$prefix}popover-bg: #{$popover-bg};
--#{$prefix}popover-border-color: #{$popover-border-color}; --#{$prefix}popover-border-width: #{$popover-border-width};
--#{$prefix}popover-border-radius: #{$popover-border-radius}; --#{$prefix}popover-border-color: #{$popover-border-color};
--#{$prefix}popover-inner-border-radius: #{$popover-inner-border-radius}; --#{$prefix}popover-border-radius: #{$popover-border-radius};
--#{$prefix}popover-box-shadow: #{$popover-box-shadow}; --#{$prefix}popover-inner-border-radius: #{$popover-inner-border-radius};
--#{$prefix}popover-header-padding-x: #{$popover-header-padding-x}; --#{$prefix}popover-box-shadow: #{$popover-box-shadow};
--#{$prefix}popover-header-padding-y: #{$popover-header-padding-y}; --#{$prefix}popover-header-padding-x: #{$popover-header-padding-x};
@include rfs($popover-header-font-size, --#{$prefix}popover-header-font-size); --#{$prefix}popover-header-padding-y: #{$popover-header-padding-y};
--#{$prefix}popover-header-color: #{$popover-header-color}; @include rfs($popover-header-font-size, --#{$prefix}popover-header-font-size);
--#{$prefix}popover-header-bg: #{$popover-header-bg}; --#{$prefix}popover-header-color: #{$popover-header-color};
--#{$prefix}popover-body-padding-x: #{$popover-body-padding-x}; --#{$prefix}popover-header-bg: #{$popover-header-bg};
--#{$prefix}popover-body-padding-y: #{$popover-body-padding-y}; --#{$prefix}popover-body-padding-x: #{$popover-body-padding-x};
--#{$prefix}popover-body-color: #{$popover-body-color}; --#{$prefix}popover-body-padding-y: #{$popover-body-padding-y};
--#{$prefix}popover-arrow-width: #{$popover-arrow-width}; --#{$prefix}popover-body-color: #{$popover-body-color};
--#{$prefix}popover-arrow-height: #{$popover-arrow-height}; --#{$prefix}popover-arrow-width: #{$popover-arrow-width};
--#{$prefix}popover-arrow-border: var(--#{$prefix}popover-border-color); --#{$prefix}popover-arrow-height: #{$popover-arrow-height};
// scss-docs-end popover-css-vars --#{$prefix}popover-arrow-border: var(--#{$prefix}popover-border-color);
// scss-docs-end popover-css-vars
z-index: var(--#{$prefix}popover-zindex); z-index: var(--#{$prefix}popover-zindex);
display: block;
max-width: var(--#{$prefix}popover-max-width);
// Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
// So reset our font and text properties to avoid inheriting weird values.
@include reset-text();
@include font-size(var(--#{$prefix}popover-font-size));
// Allow breaking very long words so they don't overflow the popover's bounds
word-wrap: break-word;
background-color: var(--#{$prefix}popover-bg);
background-clip: padding-box;
border: var(--#{$prefix}popover-border-width) solid var(--#{$prefix}popover-border-color);
@include border-radius(var(--#{$prefix}popover-border-radius));
@include box-shadow(var(--#{$prefix}popover-box-shadow));
.popover-arrow {
display: block; display: block;
width: var(--#{$prefix}popover-arrow-width); max-width: var(--#{$prefix}popover-max-width);
height: var(--#{$prefix}popover-arrow-height); // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
// So reset our font and text properties to avoid inheriting weird values.
@include reset-text();
@include font-size(var(--#{$prefix}popover-font-size));
// Allow breaking very long words so they don't overflow the popover's bounds
word-wrap: break-word;
background-color: var(--#{$prefix}popover-bg);
background-clip: padding-box;
border: var(--#{$prefix}popover-border-width) solid var(--#{$prefix}popover-border-color);
@include border-radius(var(--#{$prefix}popover-border-radius));
@include box-shadow(var(--#{$prefix}popover-box-shadow));
&::before, .popover-arrow {
&::after {
position: absolute;
display: block; display: block;
content: ""; width: var(--#{$prefix}popover-arrow-width);
border-color: transparent; height: var(--#{$prefix}popover-arrow-height);
border-style: solid;
border-width: 0; &::before,
&::after {
position: absolute;
display: block;
content: "";
border-color: transparent;
border-style: solid;
border-width: 0;
}
} }
} }
}
.bs-popover-top { .bs-popover-top {
> .popover-arrow { > .popover-arrow {
bottom: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width)); // stylelint-disable-line function-disallowed-list bottom: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width)); // stylelint-disable-line function-disallowed-list
&::before, &::before,
&::after { &::after {
border-width: var(--#{$prefix}popover-arrow-height) calc(var(--#{$prefix}popover-arrow-width) * .5) 0; // stylelint-disable-line function-disallowed-list border-width: var(--#{$prefix}popover-arrow-height) calc(var(--#{$prefix}popover-arrow-width) * .5) 0; // stylelint-disable-line function-disallowed-list
} }
&::before { &::before {
bottom: 0; bottom: 0;
border-top-color: var(--#{$prefix}popover-arrow-border); border-top-color: var(--#{$prefix}popover-arrow-border);
} }
&::after { &::after {
bottom: var(--#{$prefix}popover-border-width); bottom: var(--#{$prefix}popover-border-width);
border-top-color: var(--#{$prefix}popover-bg); border-top-color: var(--#{$prefix}popover-bg);
}
} }
} }
}
/* rtl:begin:ignore */ /* rtl:begin:ignore */
.bs-popover-end { .bs-popover-end {
> .popover-arrow { > .popover-arrow {
left: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width)); // stylelint-disable-line function-disallowed-list left: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width)); // stylelint-disable-line function-disallowed-list
width: var(--#{$prefix}popover-arrow-height); width: var(--#{$prefix}popover-arrow-height);
height: var(--#{$prefix}popover-arrow-width); height: var(--#{$prefix}popover-arrow-width);
&::before, &::before,
&::after { &::after {
border-width: calc(var(--#{$prefix}popover-arrow-width) * .5) var(--#{$prefix}popover-arrow-height) calc(var(--#{$prefix}popover-arrow-width) * .5) 0; // stylelint-disable-line function-disallowed-list border-width: calc(var(--#{$prefix}popover-arrow-width) * .5) var(--#{$prefix}popover-arrow-height) calc(var(--#{$prefix}popover-arrow-width) * .5) 0; // stylelint-disable-line function-disallowed-list
} }
&::before { &::before {
left: 0; left: 0;
border-right-color: var(--#{$prefix}popover-arrow-border); border-right-color: var(--#{$prefix}popover-arrow-border);
} }
&::after { &::after {
left: var(--#{$prefix}popover-border-width); left: var(--#{$prefix}popover-border-width);
border-right-color: var(--#{$prefix}popover-bg); border-right-color: var(--#{$prefix}popover-bg);
}
} }
} }
}
/* rtl:end:ignore */ /* rtl:end:ignore */
.bs-popover-bottom { .bs-popover-bottom {
> .popover-arrow { > .popover-arrow {
top: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width)); // stylelint-disable-line function-disallowed-list top: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width)); // stylelint-disable-line function-disallowed-list
&::before, &::before,
&::after { &::after {
border-width: 0 calc(var(--#{$prefix}popover-arrow-width) * .5) var(--#{$prefix}popover-arrow-height); // stylelint-disable-line function-disallowed-list border-width: 0 calc(var(--#{$prefix}popover-arrow-width) * .5) var(--#{$prefix}popover-arrow-height); // stylelint-disable-line function-disallowed-list
}
&::before {
top: 0;
border-bottom-color: var(--#{$prefix}popover-arrow-border);
}
&::after {
top: var(--#{$prefix}popover-border-width);
border-bottom-color: var(--#{$prefix}popover-bg);
}
} }
&::before { // This will remove the popover-header's border just below the arrow
.popover-header::before {
position: absolute;
top: 0; top: 0;
border-bottom-color: var(--#{$prefix}popover-arrow-border); left: 50%;
} display: block;
width: var(--#{$prefix}popover-arrow-width);
&::after { margin-left: calc(-.5 * var(--#{$prefix}popover-arrow-width)); // stylelint-disable-line function-disallowed-list
top: var(--#{$prefix}popover-border-width); content: "";
border-bottom-color: var(--#{$prefix}popover-bg); border-bottom: var(--#{$prefix}popover-border-width) solid var(--#{$prefix}popover-header-bg);
} }
} }
// This will remove the popover-header's border just below the arrow /* rtl:begin:ignore */
.popover-header::before { .bs-popover-start {
position: absolute; > .popover-arrow {
top: 0; right: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width)); // stylelint-disable-line function-disallowed-list
left: 50%; width: var(--#{$prefix}popover-arrow-height);
display: block; height: var(--#{$prefix}popover-arrow-width);
width: var(--#{$prefix}popover-arrow-width);
margin-left: calc(-.5 * var(--#{$prefix}popover-arrow-width)); // stylelint-disable-line function-disallowed-list
content: "";
border-bottom: var(--#{$prefix}popover-border-width) solid var(--#{$prefix}popover-header-bg);
}
}
/* rtl:begin:ignore */ &::before,
.bs-popover-start { &::after {
> .popover-arrow { border-width: calc(var(--#{$prefix}popover-arrow-width) * .5) 0 calc(var(--#{$prefix}popover-arrow-width) * .5) var(--#{$prefix}popover-arrow-height); // stylelint-disable-line function-disallowed-list
right: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width)); // stylelint-disable-line function-disallowed-list }
width: var(--#{$prefix}popover-arrow-height);
height: var(--#{$prefix}popover-arrow-width);
&::before, &::before {
&::after { right: 0;
border-width: calc(var(--#{$prefix}popover-arrow-width) * .5) 0 calc(var(--#{$prefix}popover-arrow-width) * .5) var(--#{$prefix}popover-arrow-height); // stylelint-disable-line function-disallowed-list border-left-color: var(--#{$prefix}popover-arrow-border);
} }
&::before { &::after {
right: 0; right: var(--#{$prefix}popover-border-width);
border-left-color: var(--#{$prefix}popover-arrow-border); border-left-color: var(--#{$prefix}popover-bg);
} }
&::after {
right: var(--#{$prefix}popover-border-width);
border-left-color: var(--#{$prefix}popover-bg);
} }
} }
}
/* rtl:end:ignore */ /* rtl:end:ignore */
.bs-popover-auto { .bs-popover-auto {
&[data-popper-placement^="top"] { &[data-popper-placement^="top"] {
@extend .bs-popover-top; @extend .bs-popover-top;
}
&[data-popper-placement^="right"] {
@extend .bs-popover-end;
}
&[data-popper-placement^="bottom"] {
@extend .bs-popover-bottom;
}
&[data-popper-placement^="left"] {
@extend .bs-popover-start;
}
} }
&[data-popper-placement^="right"] {
@extend .bs-popover-end; // Offset the popover to account for the popover arrow
.popover-header {
padding: var(--#{$prefix}popover-header-padding-y) var(--#{$prefix}popover-header-padding-x);
margin-bottom: 0; // Reset the default from Reboot
@include font-size(var(--#{$prefix}popover-header-font-size));
color: var(--#{$prefix}popover-header-color);
background-color: var(--#{$prefix}popover-header-bg);
border-bottom: var(--#{$prefix}popover-border-width) solid var(--#{$prefix}popover-border-color);
@include border-top-radius(var(--#{$prefix}popover-inner-border-radius));
&:empty {
display: none;
}
} }
&[data-popper-placement^="bottom"] {
@extend .bs-popover-bottom; .popover-body {
} padding: var(--#{$prefix}popover-body-padding-y) var(--#{$prefix}popover-body-padding-x);
&[data-popper-placement^="left"] { color: var(--#{$prefix}popover-body-color);
@extend .bs-popover-start;
} }
} }
// Offset the popover to account for the popover arrow
.popover-header {
padding: var(--#{$prefix}popover-header-padding-y) var(--#{$prefix}popover-header-padding-x);
margin-bottom: 0; // Reset the default from Reboot
@include font-size(var(--#{$prefix}popover-header-font-size));
color: var(--#{$prefix}popover-header-color);
background-color: var(--#{$prefix}popover-header-bg);
border-bottom: var(--#{$prefix}popover-border-width) solid var(--#{$prefix}popover-border-color);
@include border-top-radius(var(--#{$prefix}popover-inner-border-radius));
&:empty {
display: none;
}
}
.popover-body {
padding: var(--#{$prefix}popover-body-padding-y) var(--#{$prefix}popover-body-padding-x);
color: var(--#{$prefix}popover-body-color);
}

View File

@ -6,70 +6,71 @@
@use "mixins/box-shadow" as *; @use "mixins/box-shadow" as *;
@use "vendor/rfs" as *; @use "vendor/rfs" as *;
// Disable animation if transitions are disabled @layer components {
// Disable animation if transitions are disabled
// scss-docs-start progress-keyframes // scss-docs-start progress-keyframes
@if $enable-transitions { @if $enable-transitions {
@keyframes progress-bar-stripes { @keyframes progress-bar-stripes {
0% { background-position-x: $progress-height; } 0% { background-position-x: $progress-height; }
}
} }
} // scss-docs-end progress-keyframes
// scss-docs-end progress-keyframes
.progress, .progress,
.progress-stacked { .progress-stacked {
// scss-docs-start progress-css-vars // scss-docs-start progress-css-vars
--#{$prefix}progress-height: #{$progress-height}; --#{$prefix}progress-height: #{$progress-height};
@include rfs($progress-font-size, --#{$prefix}progress-font-size); @include rfs($progress-font-size, --#{$prefix}progress-font-size);
--#{$prefix}progress-bg: #{$progress-bg}; --#{$prefix}progress-bg: #{$progress-bg};
--#{$prefix}progress-border-radius: #{$progress-border-radius}; --#{$prefix}progress-border-radius: #{$progress-border-radius};
--#{$prefix}progress-box-shadow: #{$progress-box-shadow}; --#{$prefix}progress-box-shadow: #{$progress-box-shadow};
--#{$prefix}progress-bar-color: #{$progress-bar-color}; --#{$prefix}progress-bar-color: #{$progress-bar-color};
--#{$prefix}progress-bar-bg: #{$progress-bar-bg}; --#{$prefix}progress-bar-bg: #{$progress-bar-bg};
--#{$prefix}progress-bar-transition: #{$progress-bar-transition}; --#{$prefix}progress-bar-transition: #{$progress-bar-transition};
// scss-docs-end progress-css-vars // scss-docs-end progress-css-vars
display: flex; display: flex;
height: var(--#{$prefix}progress-height); height: var(--#{$prefix}progress-height);
overflow: hidden; // force rounded corners by cropping it overflow: hidden; // force rounded corners by cropping it
@include font-size(var(--#{$prefix}progress-font-size)); @include font-size(var(--#{$prefix}progress-font-size));
background-color: var(--#{$prefix}progress-bg); background-color: var(--#{$prefix}progress-bg);
@include border-radius(var(--#{$prefix}progress-border-radius)); @include border-radius(var(--#{$prefix}progress-border-radius));
@include box-shadow(var(--#{$prefix}progress-box-shadow)); @include box-shadow(var(--#{$prefix}progress-box-shadow));
} }
.progress-bar { .progress-bar {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
overflow: hidden; overflow: hidden;
color: var(--#{$prefix}progress-bar-color); color: var(--#{$prefix}progress-bar-color);
text-align: center; text-align: center;
white-space: nowrap; white-space: nowrap;
background-color: var(--#{$prefix}progress-bar-bg); background-color: var(--#{$prefix}progress-bar-bg);
@include transition(var(--#{$prefix}progress-bar-transition)); @include transition(var(--#{$prefix}progress-bar-transition));
} }
.progress-bar-striped { .progress-bar-striped {
@include gradient-striped(); @include gradient-striped();
background-size: var(--#{$prefix}progress-height) var(--#{$prefix}progress-height); background-size: var(--#{$prefix}progress-height) var(--#{$prefix}progress-height);
} }
.progress-stacked > .progress { .progress-stacked > .progress {
overflow: visible; overflow: visible;
} }
.progress-stacked > .progress > .progress-bar { .progress-stacked > .progress > .progress-bar {
width: 100%; width: 100%;
} }
@if $enable-transitions { @if $enable-transitions {
.progress-bar-animated { .progress-bar-animated {
animation: $progress-bar-animation-timing progress-bar-stripes; animation: $progress-bar-animation-timing progress-bar-stripes;
@if $enable-reduced-motion { @if $enable-reduced-motion {
@media (prefers-reduced-motion: reduce) { @media (prefers-reduced-motion: reduce) {
animation: none; animation: none;
}
} }
} }
} }

View File

@ -1,617 +0,0 @@
@use "config" as *;
@use "colors" as *;
@use "variables" as *;
@use "vendor/rfs" as *;
@use "mixins/border-radius" as *;
// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix
// Reboot
//
// Normalization of HTML elements, manually forked from Normalize.css to remove
// styles targeting irrelevant browsers while applying new styles.
//
// Normalize is licensed MIT. https://github.com/necolas/normalize.css
// Document
//
// Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.
*,
*::before,
*::after {
box-sizing: border-box;
}
// Root
//
// Ability to the value of the root font sizes, affecting the value of `rem`.
// null by default, thus nothing is generated.
:root {
@if $font-size-root != null {
@include font-size(var(--#{$prefix}root-font-size));
}
@if $enable-smooth-scroll {
@media (prefers-reduced-motion: no-preference) {
scroll-behavior: smooth;
}
}
}
// Body
//
// 1. Remove the margin in all browsers.
// 2. As a best practice, apply a default `background-color`.
// 3. Prevent adjustments of font size after orientation changes in iOS.
// 4. Change the default tap highlight to be completely transparent in iOS.
// scss-docs-start reboot-body-rules
body {
margin: 0; // 1
font-family: var(--#{$prefix}body-font-family);
@include font-size(var(--#{$prefix}body-font-size));
font-weight: var(--#{$prefix}body-font-weight);
line-height: var(--#{$prefix}body-line-height);
color: var(--#{$prefix}body-color);
text-align: var(--#{$prefix}body-text-align);
background-color: var(--#{$prefix}body-bg); // 2
-webkit-text-size-adjust: 100%; // 3
-webkit-tap-highlight-color: rgba($black, 0); // 4
}
// scss-docs-end reboot-body-rules
// Content grouping
//
// 1. Reset Firefox's gray color
hr {
margin: $hr-margin-y 0;
color: $hr-color; // 1
border: 0;
border-top: $hr-border-width solid $hr-border-color;
opacity: $hr-opacity;
}
// Typography
//
// 1. Remove top margins from headings
// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top
// margin for easier control within type scales as it avoids margin collapsing.
%heading {
margin-top: 0; // 1
margin-bottom: $headings-margin-bottom;
font-family: $headings-font-family;
font-style: $headings-font-style;
font-weight: $headings-font-weight;
line-height: $headings-line-height;
color: var(--#{$prefix}heading-color);
}
h1 {
@extend %heading;
@include font-size($h1-font-size);
}
h2 {
@extend %heading;
@include font-size($h2-font-size);
}
h3 {
@extend %heading;
@include font-size($h3-font-size);
}
h4 {
@extend %heading;
@include font-size($h4-font-size);
}
h5 {
@extend %heading;
@include font-size($h5-font-size);
}
h6 {
@extend %heading;
@include font-size($h6-font-size);
}
// Reset margins on paragraphs
//
// Similarly, the top margin on `<p>`s get reset. However, we also reset the
// bottom margin to use `rem` units instead of `em`.
p {
margin-top: 0;
margin-bottom: $paragraph-margin-bottom;
}
// Abbreviations
//
// 1. Add the correct text decoration in Chrome, Edge, Opera, and Safari.
// 2. Add explicit cursor to indicate changed behavior.
// 3. Prevent the text-decoration to be skipped.
abbr[title] {
text-decoration: underline dotted; // 1
cursor: help; // 2
text-decoration-skip-ink: none; // 3
}
// Address
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
// Lists
ol,
ul {
padding-left: 2rem;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: $dt-font-weight;
}
// 1. Undo browser default
dd {
margin-bottom: .5rem;
margin-left: 0; // 1
}
// Blockquote
blockquote {
margin: 0 0 1rem;
}
// Strong
//
// Add the correct font weight in Chrome, Edge, and Safari
b,
strong {
font-weight: $font-weight-bolder;
}
// Small
//
// Add the correct font size in all browsers
small {
@include font-size($small-font-size);
}
// Mark
mark {
padding: $mark-padding;
color: var(--#{$prefix}highlight-color);
background-color: var(--#{$prefix}highlight-bg);
}
// Sub and Sup
//
// Prevent `sub` and `sup` elements from affecting the line height in
// all browsers.
sub,
sup {
position: relative;
@include font-size($sub-sup-font-size);
line-height: 0;
vertical-align: baseline;
}
sub { bottom: -.25em; }
sup { top: -.5em; }
// Links
a {
color: rgba(var(--#{$prefix}link-color-rgb), var(--#{$prefix}link-opacity, 1));
text-decoration: $link-decoration;
&:hover {
--#{$prefix}link-color-rgb: var(--#{$prefix}link-hover-color-rgb);
text-decoration: $link-hover-decoration;
}
}
// And undo these styles for placeholder links/named anchors (without href).
// It would be more straightforward to just use a[href] in previous block, but that
// causes specificity issues in many other styles that are too complex to fix.
// See https://github.com/twbs/bootstrap/issues/19402
a:not([href]):not([class]) {
&,
&:hover {
color: inherit;
text-decoration: none;
}
}
// Code
pre,
code,
kbd,
samp {
font-family: $font-family-code;
@include font-size(1em); // Correct the odd `em` font sizing in all browsers.
}
// 1. Remove browser default top margin
// 2. Reset browser default of `1em` to use `rem`s
// 3. Don't allow content to break outside
pre {
display: block;
margin-top: 0; // 1
margin-bottom: 1rem; // 2
overflow: auto; // 3
@include font-size($code-font-size);
color: $pre-color;
// Account for some code outputs that place code tags in pre tags
code {
@include font-size(inherit);
color: inherit;
word-break: normal;
}
}
code {
@include font-size($code-font-size);
color: var(--#{$prefix}code-color);
word-wrap: break-word;
// Streamline the style when inside anchors to avoid broken underline and more
a > & {
color: inherit;
}
}
kbd {
padding: $kbd-padding-y $kbd-padding-x;
@include font-size($kbd-font-size);
color: $kbd-color;
background-color: $kbd-bg;
@include border-radius($border-radius-sm);
kbd {
padding: 0;
@include font-size(1em);
font-weight: $nested-kbd-font-weight;
}
}
// Figures
//
// Apply a consistent margin strategy (matches our type styles).
figure {
margin: 0 0 1rem;
}
// Images and content
img,
svg {
vertical-align: middle;
}
// Tables
//
// Prevent double borders
table {
caption-side: bottom;
border-collapse: collapse;
}
caption {
padding-top: $table-cell-padding-y;
padding-bottom: $table-cell-padding-y;
color: $table-caption-color;
text-align: left;
}
// 1. Removes font-weight bold by inheriting
// 2. Matches default `<td>` alignment by inheriting `text-align`.
// 3. Fix alignment for Safari
th {
font-weight: $table-th-font-weight; // 1
text-align: inherit; // 2
text-align: -webkit-match-parent; // 3
}
thead,
tbody,
tfoot,
tr,
td,
th {
border-color: inherit;
border-style: solid;
border-width: 0;
}
// Forms
//
// 1. Allow labels to use `margin` for spacing.
label {
display: inline-block; // 1
}
// Remove the default `border-radius` that macOS Chrome adds.
// See https://github.com/twbs/bootstrap/issues/24093
button {
// stylelint-disable-next-line property-disallowed-list
border-radius: 0;
}
// Explicitly remove focus outline in Chromium when it shouldn't be
// visible (e.g. as result of mouse click or touch tap). It already
// should be doing this automatically, but seems to currently be
// confused and applies its very visible two-tone outline anyway.
button:focus:not(:focus-visible) {
outline: 0;
}
// 1. Remove the margin in Firefox and Safari
input,
button,
select,
optgroup,
textarea {
margin: 0; // 1
font-family: inherit;
@include font-size(inherit);
line-height: inherit;
}
// Remove the inheritance of text transform in Firefox
button,
select {
text-transform: none;
}
// Set the cursor for non-`<button>` buttons
//
// Details at https://github.com/twbs/bootstrap/pull/30562
[role="button"] {
cursor: pointer;
}
select {
// Remove the inheritance of word-wrap in Safari.
// See https://github.com/twbs/bootstrap/issues/24990
word-wrap: normal;
// Undo the opacity change from Chrome
&:disabled {
opacity: 1;
}
}
// Remove the dropdown arrow only from text type inputs built with datalists in Chrome.
// See https://stackoverflow.com/a/54997118
[list]:not([type="date"]):not([type="datetime-local"]):not([type="month"]):not([type="week"]):not([type="time"])::-webkit-calendar-picker-indicator {
display: none !important;
}
// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
// controls in Android 4.
// 2. Correct the inability to style clickable types in iOS and Safari.
// 3. Opinionated: add "hand" cursor to non-disabled button elements.
button,
[type="button"], // 1
[type="reset"],
[type="submit"] {
-webkit-appearance: button; // 2
@if $enable-button-pointers {
&:not(:disabled) {
cursor: pointer; // 3
}
}
}
// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.
::-moz-focus-inner {
padding: 0;
border-style: none;
}
// 1. Textareas should really only resize vertically so they don't break their (horizontal) containers.
textarea {
resize: vertical; // 1
}
// 1. Browsers set a default `min-width: min-content;` on fieldsets,
// unlike e.g. `<div>`s, which have `min-width: 0;` by default.
// So we reset that to ensure fieldsets behave more like a standard block element.
// See https://github.com/twbs/bootstrap/issues/12359
// and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements
// 2. Reset the default outline behavior of fieldsets so they don't affect page layout.
fieldset {
min-width: 0; // 1
padding: 0; // 2
margin: 0; // 2
border: 0; // 2
}
// 1. By using `float: left`, the legend will behave like a block element.
// This way the border of a fieldset wraps around the legend if present.
// 2. Fix wrapping bug.
// See https://github.com/twbs/bootstrap/issues/29712
legend {
float: left; // 1
width: 100%;
padding: 0;
margin-bottom: $legend-margin-bottom;
font-weight: $legend-font-weight;
line-height: inherit;
@include font-size($legend-font-size);
+ * {
clear: left; // 2
}
}
// Fix height of inputs with a type of datetime-local, date, month, week, or time
// See https://github.com/twbs/bootstrap/issues/18842
::-webkit-datetime-edit-fields-wrapper,
::-webkit-datetime-edit-text,
::-webkit-datetime-edit-minute,
::-webkit-datetime-edit-hour-field,
::-webkit-datetime-edit-day-field,
::-webkit-datetime-edit-month-field,
::-webkit-datetime-edit-year-field {
padding: 0;
}
::-webkit-inner-spin-button {
height: auto;
}
// 1. This overrides the extra rounded corners on search inputs in iOS so that our
// `.form-control` class can properly style them. Note that this cannot simply
// be added to `.form-control` as it's not specific enough. For details, see
// https://github.com/twbs/bootstrap/issues/11586.
// 2. Correct the outline style in Safari.
[type="search"] {
-webkit-appearance: textfield; // 1
outline-offset: -2px; // 2
}
// 1. A few input types should stay LTR
// See https://rtlstyling.com/posts/rtl-styling#form-inputs
// 2. RTL only output
// See https://rtlcss.com/learn/usage-guide/control-directives/#raw
/* rtl:raw:
[type="tel"],
[type="url"],
[type="email"],
[type="number"] {
direction: ltr;
}
*/
// Remove the inner padding in Chrome and Safari on macOS.
::-webkit-search-decoration {
-webkit-appearance: none;
}
// Remove padding around color pickers in webkit browsers
::-webkit-color-swatch-wrapper {
padding: 0;
}
// 1. Inherit font family and line height for file input buttons
// 2. Correct the inability to style clickable types in iOS and Safari.
::file-selector-button {
font: inherit; // 1
-webkit-appearance: button; // 2
}
// Correct element displays
output {
display: inline-block;
}
// Remove border from iframe
iframe {
border: 0;
}
// Summary
//
// 1. Add the correct display in all browsers
summary {
display: list-item; // 1
cursor: pointer;
}
// Progress
//
// Add the correct vertical alignment in Chrome, Firefox, and Opera.
progress {
vertical-align: baseline;
}
// Hidden attribute
//
// Always hide an element with the `hidden` HTML attribute.
[hidden] {
display: none !important;
}

View File

@ -5,6 +5,24 @@
@use "vendor/rfs" as *; @use "vendor/rfs" as *;
@use "mixins/color-mode" as *; @use "mixins/color-mode" as *;
// mdo-do: do we need theme?
@layer colors, theme, config, root, reboot, layout, content, forms, components, helpers, custom, utilities;
@layer colors {
:root,
[data-bs-theme="light"] {
@each $color-group-name, $color-group in $all-colors {
@each $color-name, $color-value in $color-group {
--#{$prefix}#{$color-name}: #{$color-value};
}
}
@each $color, $value in $theme-colors {
--#{$prefix}#{$color}: #{$value};
}
}
}
:root, :root,
[data-bs-theme="light"] { [data-bs-theme="light"] {
// Note: Custom variable values only support SassScript inside `#{}`. // Note: Custom variable values only support SassScript inside `#{}`.
@ -13,11 +31,11 @@
// //
// Generate palettes for full colors, grays, and theme colors. // Generate palettes for full colors, grays, and theme colors.
@each $color-group-name, $color-group in $all-colors { // @each $color-group-name, $color-group in $all-colors {
@each $color-name, $color-value in $color-group { // @each $color-name, $color-value in $color-group {
--#{$prefix}#{$color-name}: #{$color-value}; // --#{$prefix}#{$color-name}: #{$color-value};
} // }
} // }
// @each $color, $value in $colors { // @each $color, $value in $colors {
// --#{$prefix}#{$color}: #{$value}; // --#{$prefix}#{$color}: #{$value};
@ -27,9 +45,9 @@
// --#{$prefix}gray-#{$color}: #{$value}; // --#{$prefix}gray-#{$color}: #{$value};
// } // }
@each $color, $value in $theme-colors { // @each $color, $value in $theme-colors {
--#{$prefix}#{$color}: #{$value}; // --#{$prefix}#{$color}: #{$value};
} // }
@each $color, $value in $theme-colors-rgb { @each $color, $value in $theme-colors-rgb {
--#{$prefix}#{$color}-rgb: #{$value}; --#{$prefix}#{$color}-rgb: #{$value};

View File

@ -1,88 +1,90 @@
@use "config" as *; @use "config" as *;
@use "variables" as *; @use "variables" as *;
// @layer components {
// Rotating border //
// // Rotating border
//
.spinner-grow, .spinner-grow,
.spinner-border { .spinner-border {
display: inline-block; display: inline-block;
width: var(--#{$prefix}spinner-width); width: var(--#{$prefix}spinner-width);
height: var(--#{$prefix}spinner-height); height: var(--#{$prefix}spinner-height);
vertical-align: var(--#{$prefix}spinner-vertical-align); vertical-align: var(--#{$prefix}spinner-vertical-align);
// stylelint-disable-next-line property-disallowed-list // stylelint-disable-next-line property-disallowed-list
border-radius: 50%; border-radius: 50%;
animation: var(--#{$prefix}spinner-animation-speed) linear infinite var(--#{$prefix}spinner-animation-name); animation: var(--#{$prefix}spinner-animation-speed) linear infinite var(--#{$prefix}spinner-animation-name);
}
// scss-docs-start spinner-border-keyframes
@keyframes spinner-border {
to { transform: rotate(360deg) #{"/* rtl:ignore */"}; }
}
// scss-docs-end spinner-border-keyframes
.spinner-border {
// scss-docs-start spinner-border-css-vars
--#{$prefix}spinner-width: #{$spinner-width};
--#{$prefix}spinner-height: #{$spinner-height};
--#{$prefix}spinner-vertical-align: #{$spinner-vertical-align};
--#{$prefix}spinner-border-width: #{$spinner-border-width};
--#{$prefix}spinner-animation-speed: #{$spinner-animation-speed};
--#{$prefix}spinner-animation-name: spinner-border;
// scss-docs-end spinner-border-css-vars
border: var(--#{$prefix}spinner-border-width) solid currentcolor;
border-right-color: transparent;
}
.spinner-border-sm {
// scss-docs-start spinner-border-sm-css-vars
--#{$prefix}spinner-width: #{$spinner-width-sm};
--#{$prefix}spinner-height: #{$spinner-height-sm};
--#{$prefix}spinner-border-width: #{$spinner-border-width-sm};
// scss-docs-end spinner-border-sm-css-vars
}
//
// Growing circle
//
// scss-docs-start spinner-grow-keyframes
@keyframes spinner-grow {
0% {
transform: scale(0);
} }
50% {
opacity: 1; // scss-docs-start spinner-border-keyframes
transform: none; @keyframes spinner-border {
to { transform: rotate(360deg) #{"/* rtl:ignore */"}; }
} }
} // scss-docs-end spinner-border-keyframes
// scss-docs-end spinner-grow-keyframes
.spinner-grow { .spinner-border {
// scss-docs-start spinner-grow-css-vars // scss-docs-start spinner-border-css-vars
--#{$prefix}spinner-width: #{$spinner-width}; --#{$prefix}spinner-width: #{$spinner-width};
--#{$prefix}spinner-height: #{$spinner-height}; --#{$prefix}spinner-height: #{$spinner-height};
--#{$prefix}spinner-vertical-align: #{$spinner-vertical-align}; --#{$prefix}spinner-vertical-align: #{$spinner-vertical-align};
--#{$prefix}spinner-animation-speed: #{$spinner-animation-speed}; --#{$prefix}spinner-border-width: #{$spinner-border-width};
--#{$prefix}spinner-animation-name: spinner-grow; --#{$prefix}spinner-animation-speed: #{$spinner-animation-speed};
// scss-docs-end spinner-grow-css-vars --#{$prefix}spinner-animation-name: spinner-border;
// scss-docs-end spinner-border-css-vars
background-color: currentcolor; border: var(--#{$prefix}spinner-border-width) solid currentcolor;
opacity: 0; border-right-color: transparent;
} }
.spinner-grow-sm { .spinner-border-sm {
--#{$prefix}spinner-width: #{$spinner-width-sm}; // scss-docs-start spinner-border-sm-css-vars
--#{$prefix}spinner-height: #{$spinner-height-sm}; --#{$prefix}spinner-width: #{$spinner-width-sm};
} --#{$prefix}spinner-height: #{$spinner-height-sm};
--#{$prefix}spinner-border-width: #{$spinner-border-width-sm};
// scss-docs-end spinner-border-sm-css-vars
}
@if $enable-reduced-motion { //
@media (prefers-reduced-motion: reduce) { // Growing circle
.spinner-border, //
.spinner-grow {
--#{$prefix}spinner-animation-speed: #{$spinner-animation-speed * 2}; // scss-docs-start spinner-grow-keyframes
@keyframes spinner-grow {
0% {
transform: scale(0);
}
50% {
opacity: 1;
transform: none;
}
}
// scss-docs-end spinner-grow-keyframes
.spinner-grow {
// scss-docs-start spinner-grow-css-vars
--#{$prefix}spinner-width: #{$spinner-width};
--#{$prefix}spinner-height: #{$spinner-height};
--#{$prefix}spinner-vertical-align: #{$spinner-vertical-align};
--#{$prefix}spinner-animation-speed: #{$spinner-animation-speed};
--#{$prefix}spinner-animation-name: spinner-grow;
// scss-docs-end spinner-grow-css-vars
background-color: currentcolor;
opacity: 0;
}
.spinner-grow-sm {
--#{$prefix}spinner-width: #{$spinner-width-sm};
--#{$prefix}spinner-height: #{$spinner-height-sm};
}
@if $enable-reduced-motion {
@media (prefers-reduced-motion: reduce) {
.spinner-border,
.spinner-grow {
--#{$prefix}spinner-animation-speed: #{$spinner-animation-speed * 2};
}
} }
} }
} }

View File

@ -1,203 +0,0 @@
@use "sass:map";
@use "config" as *;
@use "colors" as *;
@use "variables" as *;
@use "functions" as *;
@use "layout/breakpoints" as *;
// scss-docs-start table-variant
@mixin table-variant($state, $background) {
.table-#{$state} {
$color: color-contrast(opaque($body-bg, $background));
$hover-bg: mix($color, $background, percentage($table-hover-bg-factor));
$striped-bg: mix($color, $background, percentage($table-striped-bg-factor));
$active-bg: mix($color, $background, percentage($table-active-bg-factor));
$table-border-color: mix($color, $background, percentage($table-border-factor));
--#{$prefix}table-color: #{$color};
--#{$prefix}table-bg: #{$background};
--#{$prefix}table-border-color: #{$table-border-color};
--#{$prefix}table-striped-bg: #{$striped-bg};
--#{$prefix}table-striped-color: #{color-contrast($striped-bg)};
--#{$prefix}table-active-bg: #{$active-bg};
--#{$prefix}table-active-color: #{color-contrast($active-bg)};
--#{$prefix}table-hover-bg: #{$hover-bg};
--#{$prefix}table-hover-color: #{color-contrast($hover-bg)};
color: var(--#{$prefix}table-color);
border-color: var(--#{$prefix}table-border-color);
}
}
// scss-docs-end table-variant
//
// Basic Bootstrap table
//
.table {
// Reset needed for nesting tables
--#{$prefix}table-color-type: initial;
--#{$prefix}table-bg-type: initial;
--#{$prefix}table-color-state: initial;
--#{$prefix}table-bg-state: initial;
// End of reset
--#{$prefix}table-color: #{$table-color};
--#{$prefix}table-bg: #{$table-bg};
--#{$prefix}table-border-color: #{$table-border-color};
--#{$prefix}table-accent-bg: #{$table-accent-bg};
--#{$prefix}table-striped-color: #{$table-striped-color};
--#{$prefix}table-striped-bg: #{$table-striped-bg};
--#{$prefix}table-active-color: #{$table-active-color};
--#{$prefix}table-active-bg: #{$table-active-bg};
--#{$prefix}table-hover-color: #{$table-hover-color};
--#{$prefix}table-hover-bg: #{$table-hover-bg};
width: 100%;
margin-bottom: $spacer;
vertical-align: $table-cell-vertical-align;
border-color: var(--#{$prefix}table-border-color);
// Target th & td
// We need the child combinator to prevent styles leaking to nested tables which doesn't have a `.table` class.
// We use the universal selectors here to simplify the selector (else we would need 6 different selectors).
// Another advantage is that this generates less code and makes the selector less specific making it easier to override.
// stylelint-disable-next-line selector-max-universal
> :not(caption) > * > * {
padding: $table-cell-padding-y $table-cell-padding-x;
// Following the precept of cascades: https://codepen.io/miriamsuzanne/full/vYNgodb
color: var(--#{$prefix}table-color-state, var(--#{$prefix}table-color-type, var(--#{$prefix}table-color)));
background-color: var(--#{$prefix}table-bg);
border-bottom-width: $table-border-width;
box-shadow: inset 0 0 0 9999px var(--#{$prefix}table-bg-state, var(--#{$prefix}table-bg-type, var(--#{$prefix}table-accent-bg)));
}
> tbody {
vertical-align: inherit;
}
> thead {
vertical-align: bottom;
}
}
.table-group-divider {
border-top: calc(#{$table-border-width} * 2) solid $table-group-separator-color; // stylelint-disable-line function-disallowed-list
}
//
// Change placement of captions with a class
//
.caption-top {
caption-side: top;
}
//
// Condensed table w/ half padding
//
.table-sm {
// stylelint-disable-next-line selector-max-universal
> :not(caption) > * > * {
padding: $table-cell-padding-y-sm $table-cell-padding-x-sm;
}
}
// Border versions
//
// Add or remove borders all around the table and between all the columns.
//
// When borders are added on all sides of the cells, the corners can render odd when
// these borders do not have the same color or if they are semi-transparent.
// Therefore we add top and border bottoms to the `tr`s and left and right borders
// to the `td`s or `th`s
.table-bordered {
> :not(caption) > * {
border-width: $table-border-width 0;
// stylelint-disable-next-line selector-max-universal
> * {
border-width: 0 $table-border-width;
}
}
}
.table-borderless {
// stylelint-disable-next-line selector-max-universal
> :not(caption) > * > * {
border-bottom-width: 0;
}
> :not(:first-child) {
border-top-width: 0;
}
}
// Zebra-striping
//
// Default zebra-stripe styles (alternating gray and transparent backgrounds)
// For rows
.table-striped {
> tbody > tr:nth-of-type(#{$table-striped-order}) > * {
--#{$prefix}table-color-type: var(--#{$prefix}table-striped-color);
--#{$prefix}table-bg-type: var(--#{$prefix}table-striped-bg);
}
}
// For columns
.table-striped-columns {
> :not(caption) > tr > :nth-child(#{$table-striped-columns-order}) {
--#{$prefix}table-color-type: var(--#{$prefix}table-striped-color);
--#{$prefix}table-bg-type: var(--#{$prefix}table-striped-bg);
}
}
// Active table
//
// The `.table-active` class can be added to highlight rows or cells
.table-active {
--#{$prefix}table-color-state: var(--#{$prefix}table-active-color);
--#{$prefix}table-bg-state: var(--#{$prefix}table-active-bg);
}
// Hover effect
//
// Placed here since it has to come after the potential zebra striping
.table-hover {
> tbody > tr:hover > * {
--#{$prefix}table-color-state: var(--#{$prefix}table-hover-color);
--#{$prefix}table-bg-state: var(--#{$prefix}table-hover-bg);
}
}
// Table variants
//
// Table variants set the table cell backgrounds, border colors
// and the colors of the striped, hovered & active tables
@each $color, $value in $table-variants {
@include table-variant($color, $value);
}
// Responsive tables
//
// Generate series of `.table-responsive-*` classes for configuring the screen
// size of where your table will overflow.
@each $breakpoint in map.keys($grid-breakpoints) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
@include media-breakpoint-down($breakpoint) {
.table-responsive#{$infix} {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
}
}

View File

@ -3,76 +3,78 @@
@use "mixins/border-radius" as *; @use "mixins/border-radius" as *;
@use "vendor/rfs" as *; @use "vendor/rfs" as *;
.toast { @layer components {
// scss-docs-start toast-css-vars .toast {
--#{$prefix}toast-zindex: #{$zindex-toast}; // scss-docs-start toast-css-vars
--#{$prefix}toast-padding-x: #{$toast-padding-x}; --#{$prefix}toast-zindex: #{$zindex-toast};
--#{$prefix}toast-padding-y: #{$toast-padding-y}; --#{$prefix}toast-padding-x: #{$toast-padding-x};
--#{$prefix}toast-spacing: #{$toast-spacing}; --#{$prefix}toast-padding-y: #{$toast-padding-y};
--#{$prefix}toast-max-width: #{$toast-max-width}; --#{$prefix}toast-spacing: #{$toast-spacing};
@include rfs($toast-font-size, --#{$prefix}toast-font-size); --#{$prefix}toast-max-width: #{$toast-max-width};
--#{$prefix}toast-color: #{$toast-color}; @include rfs($toast-font-size, --#{$prefix}toast-font-size);
--#{$prefix}toast-bg: #{$toast-background-color}; --#{$prefix}toast-color: #{$toast-color};
--#{$prefix}toast-border-width: #{$toast-border-width}; --#{$prefix}toast-bg: #{$toast-background-color};
--#{$prefix}toast-border-color: #{$toast-border-color}; --#{$prefix}toast-border-width: #{$toast-border-width};
--#{$prefix}toast-border-radius: #{$toast-border-radius}; --#{$prefix}toast-border-color: #{$toast-border-color};
--#{$prefix}toast-box-shadow: #{$toast-box-shadow}; --#{$prefix}toast-border-radius: #{$toast-border-radius};
--#{$prefix}toast-header-color: #{$toast-header-color}; --#{$prefix}toast-box-shadow: #{$toast-box-shadow};
--#{$prefix}toast-header-bg: #{$toast-header-background-color}; --#{$prefix}toast-header-color: #{$toast-header-color};
--#{$prefix}toast-header-border-color: #{$toast-header-border-color}; --#{$prefix}toast-header-bg: #{$toast-header-background-color};
// scss-docs-end toast-css-vars --#{$prefix}toast-header-border-color: #{$toast-header-border-color};
// scss-docs-end toast-css-vars
width: var(--#{$prefix}toast-max-width); width: var(--#{$prefix}toast-max-width);
max-width: 100%; max-width: 100%;
@include font-size(var(--#{$prefix}toast-font-size)); @include font-size(var(--#{$prefix}toast-font-size));
color: var(--#{$prefix}toast-color); color: var(--#{$prefix}toast-color);
pointer-events: auto; pointer-events: auto;
background-color: var(--#{$prefix}toast-bg); background-color: var(--#{$prefix}toast-bg);
background-clip: padding-box; background-clip: padding-box;
border: var(--#{$prefix}toast-border-width) solid var(--#{$prefix}toast-border-color); border: var(--#{$prefix}toast-border-width) solid var(--#{$prefix}toast-border-color);
box-shadow: var(--#{$prefix}toast-box-shadow); box-shadow: var(--#{$prefix}toast-box-shadow);
@include border-radius(var(--#{$prefix}toast-border-radius)); @include border-radius(var(--#{$prefix}toast-border-radius));
&.showing { &.showing {
opacity: 0; opacity: 0;
}
&:not(.show) {
display: none;
}
} }
&:not(.show) { .toast-container {
display: none; --#{$prefix}toast-zindex: #{$zindex-toast};
position: absolute;
z-index: var(--#{$prefix}toast-zindex);
width: max-content;
max-width: 100%;
pointer-events: none;
> :not(:last-child) {
margin-bottom: var(--#{$prefix}toast-spacing);
}
}
.toast-header {
display: flex;
align-items: center;
padding: var(--#{$prefix}toast-padding-y) var(--#{$prefix}toast-padding-x);
color: var(--#{$prefix}toast-header-color);
background-color: var(--#{$prefix}toast-header-bg);
background-clip: padding-box;
border-bottom: var(--#{$prefix}toast-border-width) solid var(--#{$prefix}toast-header-border-color);
@include border-top-radius(calc(var(--#{$prefix}toast-border-radius) - var(--#{$prefix}toast-border-width)));
.btn-close {
margin-right: calc(-.5 * var(--#{$prefix}toast-padding-x)); // stylelint-disable-line function-disallowed-list
margin-left: var(--#{$prefix}toast-padding-x);
}
}
.toast-body {
padding: var(--#{$prefix}toast-padding-x);
word-wrap: break-word;
} }
} }
.toast-container {
--#{$prefix}toast-zindex: #{$zindex-toast};
position: absolute;
z-index: var(--#{$prefix}toast-zindex);
width: max-content;
max-width: 100%;
pointer-events: none;
> :not(:last-child) {
margin-bottom: var(--#{$prefix}toast-spacing);
}
}
.toast-header {
display: flex;
align-items: center;
padding: var(--#{$prefix}toast-padding-y) var(--#{$prefix}toast-padding-x);
color: var(--#{$prefix}toast-header-color);
background-color: var(--#{$prefix}toast-header-bg);
background-clip: padding-box;
border-bottom: var(--#{$prefix}toast-border-width) solid var(--#{$prefix}toast-header-border-color);
@include border-top-radius(calc(var(--#{$prefix}toast-border-radius) - var(--#{$prefix}toast-border-width)));
.btn-close {
margin-right: calc(-.5 * var(--#{$prefix}toast-padding-x)); // stylelint-disable-line function-disallowed-list
margin-left: var(--#{$prefix}toast-padding-x);
}
}
.toast-body {
padding: var(--#{$prefix}toast-padding-x);
word-wrap: break-word;
}

View File

@ -5,122 +5,124 @@
@use "vendor/rfs" as *; @use "vendor/rfs" as *;
@use "mixins/reset-text" as *; @use "mixins/reset-text" as *;
// Base class @layer components {
.tooltip { // Base class
// scss-docs-start tooltip-css-vars .tooltip {
--#{$prefix}tooltip-zindex: #{$zindex-tooltip}; // scss-docs-start tooltip-css-vars
--#{$prefix}tooltip-max-width: #{$tooltip-max-width}; --#{$prefix}tooltip-zindex: #{$zindex-tooltip};
--#{$prefix}tooltip-padding-x: #{$tooltip-padding-x}; --#{$prefix}tooltip-max-width: #{$tooltip-max-width};
--#{$prefix}tooltip-padding-y: #{$tooltip-padding-y}; --#{$prefix}tooltip-padding-x: #{$tooltip-padding-x};
--#{$prefix}tooltip-margin: #{$tooltip-margin}; --#{$prefix}tooltip-padding-y: #{$tooltip-padding-y};
@include rfs($tooltip-font-size, --#{$prefix}tooltip-font-size); --#{$prefix}tooltip-margin: #{$tooltip-margin};
--#{$prefix}tooltip-color: #{$tooltip-color}; @include rfs($tooltip-font-size, --#{$prefix}tooltip-font-size);
--#{$prefix}tooltip-bg: #{$tooltip-bg}; --#{$prefix}tooltip-color: #{$tooltip-color};
--#{$prefix}tooltip-border-radius: #{$tooltip-border-radius}; --#{$prefix}tooltip-bg: #{$tooltip-bg};
--#{$prefix}tooltip-opacity: #{$tooltip-opacity}; --#{$prefix}tooltip-border-radius: #{$tooltip-border-radius};
--#{$prefix}tooltip-arrow-width: #{$tooltip-arrow-width}; --#{$prefix}tooltip-opacity: #{$tooltip-opacity};
--#{$prefix}tooltip-arrow-height: #{$tooltip-arrow-height}; --#{$prefix}tooltip-arrow-width: #{$tooltip-arrow-width};
// scss-docs-end tooltip-css-vars --#{$prefix}tooltip-arrow-height: #{$tooltip-arrow-height};
// scss-docs-end tooltip-css-vars
z-index: var(--#{$prefix}tooltip-zindex); z-index: var(--#{$prefix}tooltip-zindex);
display: block;
margin: var(--#{$prefix}tooltip-margin);
@include deprecate("`$tooltip-margin`", "v5", "v5.x", true);
// Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
// So reset our font and text properties to avoid inheriting weird values.
@include reset-text();
@include font-size(var(--#{$prefix}tooltip-font-size));
// Allow breaking very long words so they don't overflow the tooltip's bounds
word-wrap: break-word;
opacity: 0;
&.show { opacity: var(--#{$prefix}tooltip-opacity); }
.tooltip-arrow {
display: block; display: block;
width: var(--#{$prefix}tooltip-arrow-width); margin: var(--#{$prefix}tooltip-margin);
height: var(--#{$prefix}tooltip-arrow-height); @include deprecate("`$tooltip-margin`", "v5", "v5.x", true);
// Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
// So reset our font and text properties to avoid inheriting weird values.
@include reset-text();
@include font-size(var(--#{$prefix}tooltip-font-size));
// Allow breaking very long words so they don't overflow the tooltip's bounds
word-wrap: break-word;
opacity: 0;
&::before { &.show { opacity: var(--#{$prefix}tooltip-opacity); }
position: absolute;
content: ""; .tooltip-arrow {
border-color: transparent; display: block;
border-style: solid; width: var(--#{$prefix}tooltip-arrow-width);
height: var(--#{$prefix}tooltip-arrow-height);
&::before {
position: absolute;
content: "";
border-color: transparent;
border-style: solid;
}
} }
} }
}
.bs-tooltip-top .tooltip-arrow { .bs-tooltip-top .tooltip-arrow {
bottom: calc(-1 * var(--#{$prefix}tooltip-arrow-height)); // stylelint-disable-line function-disallowed-list bottom: calc(-1 * var(--#{$prefix}tooltip-arrow-height)); // stylelint-disable-line function-disallowed-list
&::before { &::before {
top: -1px; top: -1px;
border-width: var(--#{$prefix}tooltip-arrow-height) calc(var(--#{$prefix}tooltip-arrow-width) * .5) 0; // stylelint-disable-line function-disallowed-list border-width: var(--#{$prefix}tooltip-arrow-height) calc(var(--#{$prefix}tooltip-arrow-width) * .5) 0; // stylelint-disable-line function-disallowed-list
border-top-color: var(--#{$prefix}tooltip-bg); border-top-color: var(--#{$prefix}tooltip-bg);
}
}
/* rtl:begin:ignore */
.bs-tooltip-end .tooltip-arrow {
left: calc(-1 * var(--#{$prefix}tooltip-arrow-height)); // stylelint-disable-line function-disallowed-list
width: var(--#{$prefix}tooltip-arrow-height);
height: var(--#{$prefix}tooltip-arrow-width);
&::before {
right: -1px;
border-width: calc(var(--#{$prefix}tooltip-arrow-width) * .5) var(--#{$prefix}tooltip-arrow-height) calc(var(--#{$prefix}tooltip-arrow-width) * .5) 0; // stylelint-disable-line function-disallowed-list
border-right-color: var(--#{$prefix}tooltip-bg);
}
}
/* rtl:end:ignore */
.bs-tooltip-bottom .tooltip-arrow {
top: calc(-1 * var(--#{$prefix}tooltip-arrow-height)); // stylelint-disable-line function-disallowed-list
&::before {
bottom: -1px;
border-width: 0 calc(var(--#{$prefix}tooltip-arrow-width) * .5) var(--#{$prefix}tooltip-arrow-height); // stylelint-disable-line function-disallowed-list
border-bottom-color: var(--#{$prefix}tooltip-bg);
}
}
/* rtl:begin:ignore */
.bs-tooltip-start .tooltip-arrow {
right: calc(-1 * var(--#{$prefix}tooltip-arrow-height)); // stylelint-disable-line function-disallowed-list
width: var(--#{$prefix}tooltip-arrow-height);
height: var(--#{$prefix}tooltip-arrow-width);
&::before {
left: -1px;
border-width: calc(var(--#{$prefix}tooltip-arrow-width) * .5) 0 calc(var(--#{$prefix}tooltip-arrow-width) * .5) var(--#{$prefix}tooltip-arrow-height); // stylelint-disable-line function-disallowed-list
border-left-color: var(--#{$prefix}tooltip-bg);
}
}
/* rtl:end:ignore */
.bs-tooltip-auto {
&[data-popper-placement^="top"] {
@extend .bs-tooltip-top;
}
&[data-popper-placement^="right"] {
@extend .bs-tooltip-end;
}
&[data-popper-placement^="bottom"] {
@extend .bs-tooltip-bottom;
}
&[data-popper-placement^="left"] {
@extend .bs-tooltip-start;
}
}
// Wrapper for the tooltip content
.tooltip-inner {
max-width: var(--#{$prefix}tooltip-max-width);
padding: var(--#{$prefix}tooltip-padding-y) var(--#{$prefix}tooltip-padding-x);
color: var(--#{$prefix}tooltip-color);
text-align: center;
background-color: var(--#{$prefix}tooltip-bg);
@include border-radius(var(--#{$prefix}tooltip-border-radius));
} }
} }
/* rtl:begin:ignore */
.bs-tooltip-end .tooltip-arrow {
left: calc(-1 * var(--#{$prefix}tooltip-arrow-height)); // stylelint-disable-line function-disallowed-list
width: var(--#{$prefix}tooltip-arrow-height);
height: var(--#{$prefix}tooltip-arrow-width);
&::before {
right: -1px;
border-width: calc(var(--#{$prefix}tooltip-arrow-width) * .5) var(--#{$prefix}tooltip-arrow-height) calc(var(--#{$prefix}tooltip-arrow-width) * .5) 0; // stylelint-disable-line function-disallowed-list
border-right-color: var(--#{$prefix}tooltip-bg);
}
}
/* rtl:end:ignore */
.bs-tooltip-bottom .tooltip-arrow {
top: calc(-1 * var(--#{$prefix}tooltip-arrow-height)); // stylelint-disable-line function-disallowed-list
&::before {
bottom: -1px;
border-width: 0 calc(var(--#{$prefix}tooltip-arrow-width) * .5) var(--#{$prefix}tooltip-arrow-height); // stylelint-disable-line function-disallowed-list
border-bottom-color: var(--#{$prefix}tooltip-bg);
}
}
/* rtl:begin:ignore */
.bs-tooltip-start .tooltip-arrow {
right: calc(-1 * var(--#{$prefix}tooltip-arrow-height)); // stylelint-disable-line function-disallowed-list
width: var(--#{$prefix}tooltip-arrow-height);
height: var(--#{$prefix}tooltip-arrow-width);
&::before {
left: -1px;
border-width: calc(var(--#{$prefix}tooltip-arrow-width) * .5) 0 calc(var(--#{$prefix}tooltip-arrow-width) * .5) var(--#{$prefix}tooltip-arrow-height); // stylelint-disable-line function-disallowed-list
border-left-color: var(--#{$prefix}tooltip-bg);
}
}
/* rtl:end:ignore */
.bs-tooltip-auto {
&[data-popper-placement^="top"] {
@extend .bs-tooltip-top;
}
&[data-popper-placement^="right"] {
@extend .bs-tooltip-end;
}
&[data-popper-placement^="bottom"] {
@extend .bs-tooltip-bottom;
}
&[data-popper-placement^="left"] {
@extend .bs-tooltip-start;
}
}
// Wrapper for the tooltip content
.tooltip-inner {
max-width: var(--#{$prefix}tooltip-max-width);
padding: var(--#{$prefix}tooltip-padding-y) var(--#{$prefix}tooltip-padding-x);
color: var(--#{$prefix}tooltip-color);
text-align: center;
background-color: var(--#{$prefix}tooltip-bg);
@include border-radius(var(--#{$prefix}tooltip-border-radius));
}

View File

@ -1,112 +0,0 @@
@use "config" as *;
@use "variables" as *;
@use "mixins/lists" as *;
@use "vendor/rfs" as *;
//
// Headings
//
// mdo-do: remove extend
// .h1 {
// @extend h1;
// }
// .h2 {
// @extend h2;
// }
// .h3 {
// @extend h3;
// }
// .h4 {
// @extend h4;
// }
// .h5 {
// @extend h5;
// }
// .h6 {
// @extend h6;
// }
.lead {
@include font-size($lead-font-size);
font-weight: $lead-font-weight;
}
// Type display classes
@each $display, $font-size in $display-font-sizes {
.display-#{$display} {
font-family: $display-font-family;
font-style: $display-font-style;
font-weight: $display-font-weight;
line-height: $display-line-height;
@include font-size($font-size);
}
}
//
// Emphasis
//
.small {
// @extend small;
}
.mark {
// @extend mark;
}
//
// Lists
//
.list-unstyled {
@include list-unstyled();
}
// Inline turns list items into inline-block
.list-inline {
@include list-unstyled();
}
.list-inline-item {
display: inline-block;
&:not(:last-child) {
margin-right: $list-inline-padding;
}
}
//
// Misc
//
// Builds on `abbr`
.initialism {
@include font-size($initialism-font-size);
text-transform: uppercase;
}
// Blockquotes
.blockquote {
margin-bottom: $blockquote-margin-y;
@include font-size($blockquote-font-size);
> :last-child {
margin-bottom: 0;
}
}
.blockquote-footer {
margin-top: -$blockquote-margin-y;
margin-bottom: $blockquote-margin-y;
@include font-size($blockquote-footer-font-size);
color: $blockquote-footer-color;
&::before {
content: "\2014\00A0"; // em dash, nbsp
}
}

View File

@ -5,8 +5,6 @@
@use "functions" as *; @use "functions" as *;
@use "maps" as *; @use "maps" as *;
// Utilities
$utilities: () !default; $utilities: () !default;
// stylelint-disable-next-line scss/dollar-variable-default // stylelint-disable-next-line scss/dollar-variable-default
$utilities: map.merge( $utilities: map.merge(

70
scss/bootstrap.scss vendored
View File

@ -1,52 +1,46 @@
// @import "mixins/banner"; /*!
// @include bsBanner(""); * Bootstrap v6.0.0-dev (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
// scss-docs-start import-stack // scss-docs-start import-stack
// Configuration // Global CSS variables, layer definitions, and configuration
// @use "config" as *;
// @import "functions";
// @import "colors";
// @import "variables";
// @import "variables-dark";
@use "maps";
@use "mixins";
// @use "utilities";
// Layout & components
@use "root"; @use "root";
@use "reboot";
@use "type"; // Reboot & Content
@use "images"; @use "content";
// @import "containers";
// @import "grid"; // Layout
@use "layout"; @use "layout";
@use "tables";
// Forms
@use "forms"; @use "forms";
// Components
@use "accordion";
@use "alert";
@use "badge";
@use "breadcrumb";
@use "buttons"; @use "buttons";
@use "transitions";
@use "dropdown";
@use "button-group"; @use "button-group";
@use "card";
@use "carousel";
@use "close";
@use "dropdown";
@use "list-group";
@use "modal";
@use "nav"; @use "nav";
@use "navbar"; @use "navbar";
@use "card";
@use "accordion";
@use "breadcrumb";
@use "pagination";
@use "badge";
@use "alert";
@use "progress";
@use "list-group";
@use "close";
@use "toasts";
@use "modal";
@use "tooltip";
@use "popover";
@use "carousel";
@use "spinners";
@use "offcanvas"; @use "offcanvas";
@use "pagination";
@use "placeholders"; @use "placeholders";
@use "popover";
@use "progress";
@use "spinners";
@use "toasts";
@use "tooltip";
@use "transitions";
// Helpers // Helpers
@use "helpers"; @use "helpers";

51
scss/content/_images.scss Normal file
View File

@ -0,0 +1,51 @@
@use "../config" as *;
@use "../variables" as *;
@use "../vendor/rfs" as *;
@use "../mixins/image" as *;
@use "../mixins/border-radius" as *;
@use "../mixins/box-shadow" as *;
@layer content {
// Responsive images (ensure images don't scale beyond their parents)
//
// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.
// We previously tried the "images are responsive by default" approach in Bootstrap v2,
// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)
// which weren't expecting the images within themselves to be involuntarily resized.
// See also https://github.com/twbs/bootstrap/issues/18178
.img-fluid {
@include img-fluid();
}
// Image thumbnails
.img-thumbnail {
padding: $thumbnail-padding;
background-color: $thumbnail-bg;
border: $thumbnail-border-width solid $thumbnail-border-color;
@include border-radius($thumbnail-border-radius);
@include box-shadow($thumbnail-box-shadow);
// Keep them at most 100% wide
@include img-fluid();
}
//
// Figures
//
.figure {
// Ensures the caption's text aligns with the image.
display: inline-block;
}
.figure-img {
margin-bottom: $spacer * .5;
line-height: 1;
}
.figure-caption {
@include font-size($figure-caption-font-size);
color: $figure-caption-color;
}
}

618
scss/content/_reboot.scss Normal file
View File

@ -0,0 +1,618 @@
@use "../config" as *;
@use "../colors" as *;
@use "../variables" as *;
@use "../vendor/rfs" as *;
@use "../mixins/border-radius" as *;
// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix
@layer reboot {
// Reboot
//
// Normalization of HTML elements, manually forked from Normalize.css to remove
// styles targeting irrelevant browsers while applying new styles.
//
// Normalize is licensed MIT. https://github.com/necolas/normalize.css
// Document
//
// Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.
*,
*::before,
*::after {
box-sizing: border-box;
}
// Root
//
// Ability to the value of the root font sizes, affecting the value of `rem`.
// null by default, thus nothing is generated.
:root {
@if $font-size-root != null {
@include font-size(var(--#{$prefix}root-font-size));
}
@if $enable-smooth-scroll {
@media (prefers-reduced-motion: no-preference) {
scroll-behavior: smooth;
}
}
}
// Body
//
// 1. Remove the margin in all browsers.
// 2. As a best practice, apply a default `background-color`.
// 3. Prevent adjustments of font size after orientation changes in iOS.
// 4. Change the default tap highlight to be completely transparent in iOS.
// scss-docs-start reboot-body-rules
body {
margin: 0; // 1
font-family: var(--#{$prefix}body-font-family);
@include font-size(var(--#{$prefix}body-font-size));
font-weight: var(--#{$prefix}body-font-weight);
line-height: var(--#{$prefix}body-line-height);
color: var(--#{$prefix}body-color);
text-align: var(--#{$prefix}body-text-align);
background-color: var(--#{$prefix}body-bg); // 2
-webkit-text-size-adjust: 100%; // 3
-webkit-tap-highlight-color: rgba($black, 0); // 4
}
// scss-docs-end reboot-body-rules
// Content grouping
//
// 1. Reset Firefox's gray color
hr {
margin: $hr-margin-y 0;
color: $hr-color; // 1
border: 0;
border-top: $hr-border-width solid $hr-border-color;
opacity: $hr-opacity;
}
// Typography
//
// 1. Remove top margins from headings
// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top
// margin for easier control within type scales as it avoids margin collapsing.
%heading {
margin-top: 0; // 1
margin-bottom: $headings-margin-bottom;
font-family: $headings-font-family;
font-style: $headings-font-style;
font-weight: $headings-font-weight;
line-height: $headings-line-height;
color: var(--#{$prefix}heading-color);
}
h1 {
@extend %heading;
@include font-size($h1-font-size);
}
h2 {
@extend %heading;
@include font-size($h2-font-size);
}
h3 {
@extend %heading;
@include font-size($h3-font-size);
}
h4 {
@extend %heading;
@include font-size($h4-font-size);
}
h5 {
@extend %heading;
@include font-size($h5-font-size);
}
h6 {
@extend %heading;
@include font-size($h6-font-size);
}
// Reset margins on paragraphs
//
// Similarly, the top margin on `<p>`s get reset. However, we also reset the
// bottom margin to use `rem` units instead of `em`.
p {
margin-top: 0;
margin-bottom: $paragraph-margin-bottom;
}
// Abbreviations
//
// 1. Add the correct text decoration in Chrome, Edge, Opera, and Safari.
// 2. Add explicit cursor to indicate changed behavior.
// 3. Prevent the text-decoration to be skipped.
abbr[title] {
text-decoration: underline dotted; // 1
cursor: help; // 2
text-decoration-skip-ink: none; // 3
}
// Address
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
// Lists
ol,
ul {
padding-left: 2rem;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: $dt-font-weight;
}
// 1. Undo browser default
dd {
margin-bottom: .5rem;
margin-left: 0; // 1
}
// Blockquote
blockquote {
margin: 0 0 1rem;
}
// Strong
//
// Add the correct font weight in Chrome, Edge, and Safari
b,
strong {
font-weight: $font-weight-bolder;
}
// Small
//
// Add the correct font size in all browsers
small {
@include font-size($small-font-size);
}
// Mark
mark {
padding: $mark-padding;
color: var(--#{$prefix}highlight-color);
background-color: var(--#{$prefix}highlight-bg);
}
// Sub and Sup
//
// Prevent `sub` and `sup` elements from affecting the line height in
// all browsers.
sub,
sup {
position: relative;
@include font-size($sub-sup-font-size);
line-height: 0;
vertical-align: baseline;
}
sub { bottom: -.25em; }
sup { top: -.5em; }
// Links
a {
color: rgba(var(--#{$prefix}link-color-rgb), var(--#{$prefix}link-opacity, 1));
text-decoration: $link-decoration;
&:hover {
--#{$prefix}link-color-rgb: var(--#{$prefix}link-hover-color-rgb);
text-decoration: $link-hover-decoration;
}
}
// And undo these styles for placeholder links/named anchors (without href).
// It would be more straightforward to just use a[href] in previous block, but that
// causes specificity issues in many other styles that are too complex to fix.
// See https://github.com/twbs/bootstrap/issues/19402
a:not([href]):not([class]) {
&,
&:hover {
color: inherit;
text-decoration: none;
}
}
// Code
pre,
code,
kbd,
samp {
font-family: $font-family-code;
@include font-size(1em); // Correct the odd `em` font sizing in all browsers.
}
// 1. Remove browser default top margin
// 2. Reset browser default of `1em` to use `rem`s
// 3. Don't allow content to break outside
pre {
display: block;
margin-top: 0; // 1
margin-bottom: 1rem; // 2
overflow: auto; // 3
@include font-size($code-font-size);
color: $pre-color;
// Account for some code outputs that place code tags in pre tags
code {
@include font-size(inherit);
color: inherit;
word-break: normal;
}
}
code {
@include font-size($code-font-size);
color: var(--#{$prefix}code-color);
word-wrap: break-word;
// Streamline the style when inside anchors to avoid broken underline and more
a > & {
color: inherit;
}
}
kbd {
padding: $kbd-padding-y $kbd-padding-x;
@include font-size($kbd-font-size);
color: $kbd-color;
background-color: $kbd-bg;
@include border-radius($border-radius-sm);
kbd {
padding: 0;
@include font-size(1em);
font-weight: $nested-kbd-font-weight;
}
}
// Figures
//
// Apply a consistent margin strategy (matches our type styles).
figure {
margin: 0 0 1rem;
}
// Images and content
img,
svg {
vertical-align: middle;
}
// Tables
//
// Prevent double borders
table {
caption-side: bottom;
border-collapse: collapse;
}
caption {
padding-top: $table-cell-padding-y;
padding-bottom: $table-cell-padding-y;
color: $table-caption-color;
text-align: left;
}
// 1. Removes font-weight bold by inheriting
// 2. Matches default `<td>` alignment by inheriting `text-align`.
// 3. Fix alignment for Safari
th {
font-weight: $table-th-font-weight; // 1
text-align: inherit; // 2
text-align: -webkit-match-parent; // 3
}
thead,
tbody,
tfoot,
tr,
td,
th {
border-color: inherit;
border-style: solid;
border-width: 0;
}
// Forms
//
// 1. Allow labels to use `margin` for spacing.
label {
display: inline-block; // 1
}
// Remove the default `border-radius` that macOS Chrome adds.
// See https://github.com/twbs/bootstrap/issues/24093
button {
// stylelint-disable-next-line property-disallowed-list
border-radius: 0;
}
// Explicitly remove focus outline in Chromium when it shouldn't be
// visible (e.g. as result of mouse click or touch tap). It already
// should be doing this automatically, but seems to currently be
// confused and applies its very visible two-tone outline anyway.
button:focus:not(:focus-visible) {
outline: 0;
}
// 1. Remove the margin in Firefox and Safari
input,
button,
select,
optgroup,
textarea {
margin: 0; // 1
font-family: inherit;
@include font-size(inherit);
line-height: inherit;
}
// Remove the inheritance of text transform in Firefox
button,
select {
text-transform: none;
}
// Set the cursor for non-`<button>` buttons
//
// Details at https://github.com/twbs/bootstrap/pull/30562
[role="button"] {
cursor: pointer;
}
select {
// Remove the inheritance of word-wrap in Safari.
// See https://github.com/twbs/bootstrap/issues/24990
word-wrap: normal;
// Undo the opacity change from Chrome
&:disabled {
opacity: 1;
}
}
// Remove the dropdown arrow only from text type inputs built with datalists in Chrome.
// See https://stackoverflow.com/a/54997118
[list]:not([type="date"]):not([type="datetime-local"]):not([type="month"]):not([type="week"]):not([type="time"])::-webkit-calendar-picker-indicator {
display: none !important;
}
// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
// controls in Android 4.
// 2. Correct the inability to style clickable types in iOS and Safari.
// 3. Opinionated: add "hand" cursor to non-disabled button elements.
button,
[type="button"], // 1
[type="reset"],
[type="submit"] {
-webkit-appearance: button; // 2
@if $enable-button-pointers {
&:not(:disabled) {
cursor: pointer; // 3
}
}
}
// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.
::-moz-focus-inner {
padding: 0;
border-style: none;
}
// 1. Textareas should really only resize vertically so they don't break their (horizontal) containers.
textarea {
resize: vertical; // 1
}
// 1. Browsers set a default `min-width: min-content;` on fieldsets,
// unlike e.g. `<div>`s, which have `min-width: 0;` by default.
// So we reset that to ensure fieldsets behave more like a standard block element.
// See https://github.com/twbs/bootstrap/issues/12359
// and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements
// 2. Reset the default outline behavior of fieldsets so they don't affect page layout.
fieldset {
min-width: 0; // 1
padding: 0; // 2
margin: 0; // 2
border: 0; // 2
}
// 1. By using `float: left`, the legend will behave like a block element.
// This way the border of a fieldset wraps around the legend if present.
// 2. Fix wrapping bug.
// See https://github.com/twbs/bootstrap/issues/29712
legend {
float: left; // 1
width: 100%;
padding: 0;
margin-bottom: $legend-margin-bottom;
font-weight: $legend-font-weight;
line-height: inherit;
@include font-size($legend-font-size);
+ * {
clear: left; // 2
}
}
// Fix height of inputs with a type of datetime-local, date, month, week, or time
// See https://github.com/twbs/bootstrap/issues/18842
::-webkit-datetime-edit-fields-wrapper,
::-webkit-datetime-edit-text,
::-webkit-datetime-edit-minute,
::-webkit-datetime-edit-hour-field,
::-webkit-datetime-edit-day-field,
::-webkit-datetime-edit-month-field,
::-webkit-datetime-edit-year-field {
padding: 0;
}
::-webkit-inner-spin-button {
height: auto;
}
// 1. This overrides the extra rounded corners on search inputs in iOS so that our
// `.form-control` class can properly style them. Note that this cannot simply
// be added to `.form-control` as it's not specific enough. For details, see
// https://github.com/twbs/bootstrap/issues/11586.
// 2. Correct the outline style in Safari.
[type="search"] {
-webkit-appearance: textfield; // 1
outline-offset: -2px; // 2
}
// 1. A few input types should stay LTR
// See https://rtlstyling.com/posts/rtl-styling#form-inputs
// 2. RTL only output
// See https://rtlcss.com/learn/usage-guide/control-directives/#raw
/* rtl:raw:
[type="tel"],
[type="url"],
[type="email"],
[type="number"] {
direction: ltr;
}
*/
// Remove the inner padding in Chrome and Safari on macOS.
::-webkit-search-decoration {
-webkit-appearance: none;
}
// Remove padding around color pickers in webkit browsers
::-webkit-color-swatch-wrapper {
padding: 0;
}
// 1. Inherit font family and line height for file input buttons
// 2. Correct the inability to style clickable types in iOS and Safari.
::file-selector-button {
font: inherit; // 1
-webkit-appearance: button; // 2
}
// Correct element displays
output {
display: inline-block;
}
// Remove border from iframe
iframe {
border: 0;
}
// Summary
//
// 1. Add the correct display in all browsers
summary {
display: list-item; // 1
cursor: pointer;
}
// Progress
//
// Add the correct vertical alignment in Chrome, Firefox, and Opera.
progress {
vertical-align: baseline;
}
// Hidden attribute
//
// Always hide an element with the `hidden` HTML attribute.
[hidden] {
display: none !important;
}
}

205
scss/content/_tables.scss Normal file
View File

@ -0,0 +1,205 @@
@use "sass:map";
@use "../config" as *;
@use "../colors" as *;
@use "../variables" as *;
@use "../functions" as *;
@use "../layout/breakpoints" as *;
@layer content {
// scss-docs-start table-variant
@mixin table-variant($state, $background) {
.table-#{$state} {
$color: color-contrast(opaque($body-bg, $background));
$hover-bg: mix($color, $background, percentage($table-hover-bg-factor));
$striped-bg: mix($color, $background, percentage($table-striped-bg-factor));
$active-bg: mix($color, $background, percentage($table-active-bg-factor));
$table-border-color: mix($color, $background, percentage($table-border-factor));
--#{$prefix}table-color: #{$color};
--#{$prefix}table-bg: #{$background};
--#{$prefix}table-border-color: #{$table-border-color};
--#{$prefix}table-striped-bg: #{$striped-bg};
--#{$prefix}table-striped-color: #{color-contrast($striped-bg)};
--#{$prefix}table-active-bg: #{$active-bg};
--#{$prefix}table-active-color: #{color-contrast($active-bg)};
--#{$prefix}table-hover-bg: #{$hover-bg};
--#{$prefix}table-hover-color: #{color-contrast($hover-bg)};
color: var(--#{$prefix}table-color);
border-color: var(--#{$prefix}table-border-color);
}
}
// scss-docs-end table-variant
//
// Basic Bootstrap table
//
.table {
// Reset needed for nesting tables
--#{$prefix}table-color-type: initial;
--#{$prefix}table-bg-type: initial;
--#{$prefix}table-color-state: initial;
--#{$prefix}table-bg-state: initial;
// End of reset
--#{$prefix}table-color: #{$table-color};
--#{$prefix}table-bg: #{$table-bg};
--#{$prefix}table-border-color: #{$table-border-color};
--#{$prefix}table-accent-bg: #{$table-accent-bg};
--#{$prefix}table-striped-color: #{$table-striped-color};
--#{$prefix}table-striped-bg: #{$table-striped-bg};
--#{$prefix}table-active-color: #{$table-active-color};
--#{$prefix}table-active-bg: #{$table-active-bg};
--#{$prefix}table-hover-color: #{$table-hover-color};
--#{$prefix}table-hover-bg: #{$table-hover-bg};
width: 100%;
margin-bottom: $spacer;
vertical-align: $table-cell-vertical-align;
border-color: var(--#{$prefix}table-border-color);
// Target th & td
// We need the child combinator to prevent styles leaking to nested tables which doesn't have a `.table` class.
// We use the universal selectors here to simplify the selector (else we would need 6 different selectors).
// Another advantage is that this generates less code and makes the selector less specific making it easier to override.
// stylelint-disable-next-line selector-max-universal
> :not(caption) > * > * {
padding: $table-cell-padding-y $table-cell-padding-x;
// Following the precept of cascades: https://codepen.io/miriamsuzanne/full/vYNgodb
color: var(--#{$prefix}table-color-state, var(--#{$prefix}table-color-type, var(--#{$prefix}table-color)));
background-color: var(--#{$prefix}table-bg);
border-bottom-width: $table-border-width;
box-shadow: inset 0 0 0 9999px var(--#{$prefix}table-bg-state, var(--#{$prefix}table-bg-type, var(--#{$prefix}table-accent-bg)));
}
> tbody {
vertical-align: inherit;
}
> thead {
vertical-align: bottom;
}
}
.table-group-divider {
border-top: calc(#{$table-border-width} * 2) solid $table-group-separator-color; // stylelint-disable-line function-disallowed-list
}
//
// Change placement of captions with a class
//
.caption-top {
caption-side: top;
}
//
// Condensed table w/ half padding
//
.table-sm {
// stylelint-disable-next-line selector-max-universal
> :not(caption) > * > * {
padding: $table-cell-padding-y-sm $table-cell-padding-x-sm;
}
}
// Border versions
//
// Add or remove borders all around the table and between all the columns.
//
// When borders are added on all sides of the cells, the corners can render odd when
// these borders do not have the same color or if they are semi-transparent.
// Therefore we add top and border bottoms to the `tr`s and left and right borders
// to the `td`s or `th`s
.table-bordered {
> :not(caption) > * {
border-width: $table-border-width 0;
// stylelint-disable-next-line selector-max-universal
> * {
border-width: 0 $table-border-width;
}
}
}
.table-borderless {
// stylelint-disable-next-line selector-max-universal
> :not(caption) > * > * {
border-bottom-width: 0;
}
> :not(:first-child) {
border-top-width: 0;
}
}
// Zebra-striping
//
// Default zebra-stripe styles (alternating gray and transparent backgrounds)
// For rows
.table-striped {
> tbody > tr:nth-of-type(#{$table-striped-order}) > * {
--#{$prefix}table-color-type: var(--#{$prefix}table-striped-color);
--#{$prefix}table-bg-type: var(--#{$prefix}table-striped-bg);
}
}
// For columns
.table-striped-columns {
> :not(caption) > tr > :nth-child(#{$table-striped-columns-order}) {
--#{$prefix}table-color-type: var(--#{$prefix}table-striped-color);
--#{$prefix}table-bg-type: var(--#{$prefix}table-striped-bg);
}
}
// Active table
//
// The `.table-active` class can be added to highlight rows or cells
.table-active {
--#{$prefix}table-color-state: var(--#{$prefix}table-active-color);
--#{$prefix}table-bg-state: var(--#{$prefix}table-active-bg);
}
// Hover effect
//
// Placed here since it has to come after the potential zebra striping
.table-hover {
> tbody > tr:hover > * {
--#{$prefix}table-color-state: var(--#{$prefix}table-hover-color);
--#{$prefix}table-bg-state: var(--#{$prefix}table-hover-bg);
}
}
// Table variants
//
// Table variants set the table cell backgrounds, border colors
// and the colors of the striped, hovered & active tables
@each $color, $value in $table-variants {
@include table-variant($color, $value);
}
// Responsive tables
//
// Generate series of `.table-responsive-*` classes for configuring the screen
// size of where your table will overflow.
@each $breakpoint in map.keys($grid-breakpoints) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
@include media-breakpoint-down($breakpoint) {
.table-responsive#{$infix} {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
}
}
}

114
scss/content/_type.scss Normal file
View File

@ -0,0 +1,114 @@
@use "../config" as *;
@use "../variables" as *;
@use "../mixins/lists" as *;
@use "../vendor/rfs" as *;
@layer content {
//
// Headings
//
// mdo-do: remove extend
// .h1 {
// @extend h1;
// }
// .h2 {
// @extend h2;
// }
// .h3 {
// @extend h3;
// }
// .h4 {
// @extend h4;
// }
// .h5 {
// @extend h5;
// }
// .h6 {
// @extend h6;
// }
.lead {
@include font-size($lead-font-size);
font-weight: $lead-font-weight;
}
// Type display classes
@each $display, $font-size in $display-font-sizes {
.display-#{$display} {
font-family: $display-font-family;
font-style: $display-font-style;
font-weight: $display-font-weight;
line-height: $display-line-height;
@include font-size($font-size);
}
}
//
// Emphasis
//
.small {
// @extend small;
}
.mark {
// @extend mark;
}
//
// Lists
//
.list-unstyled {
@include list-unstyled();
}
// Inline turns list items into inline-block
.list-inline {
@include list-unstyled();
}
.list-inline-item {
display: inline-block;
&:not(:last-child) {
margin-right: $list-inline-padding;
}
}
//
// Misc
//
// Builds on `abbr`
.initialism {
@include font-size($initialism-font-size);
text-transform: uppercase;
}
// Blockquotes
.blockquote {
margin-bottom: $blockquote-margin-y;
@include font-size($blockquote-font-size);
> :last-child {
margin-bottom: 0;
}
}
.blockquote-footer {
margin-top: -$blockquote-margin-y;
margin-bottom: $blockquote-margin-y;
@include font-size($blockquote-footer-font-size);
color: $blockquote-footer-color;
&::before {
content: "\2014\00A0"; // em dash, nbsp
}
}
}

4
scss/content/index.scss Normal file
View File

@ -0,0 +1,4 @@
@forward "reboot";
@forward "type";
@forward "tables";
@forward "images";

View File

@ -3,100 +3,102 @@
@use "../mixins/border-radius" as *; @use "../mixins/border-radius" as *;
@use "../mixins/transition" as *; @use "../mixins/transition" as *;
.form-floating { @layer forms {
position: relative; .form-floating {
position: relative;
> .form-control, > .form-control,
> .form-control-plaintext, > .form-control-plaintext,
> .form-select { > .form-select {
height: $form-floating-height; height: $form-floating-height;
min-height: $form-floating-height; min-height: $form-floating-height;
line-height: $form-floating-line-height; line-height: $form-floating-line-height;
}
> label {
position: absolute;
top: 0;
left: 0;
z-index: 2;
max-width: 100%;
height: 100%; // allow textareas
padding: $form-floating-padding-y $form-floating-padding-x;
overflow: hidden;
color: rgba(var(--#{$prefix}body-color-rgb), #{$form-floating-label-opacity});
text-align: start;
text-overflow: ellipsis;
white-space: nowrap;
pointer-events: none;
border: $input-border-width solid transparent; // Required for aligning label's text with the input as it affects inner box model
transform-origin: 0 0;
@include transition($form-floating-transition);
}
> .form-control,
> .form-control-plaintext {
padding: $form-floating-padding-y $form-floating-padding-x;
&::placeholder {
color: transparent;
} }
&:focus, > label {
&:not(:placeholder-shown) { position: absolute;
top: 0;
left: 0;
z-index: 2;
max-width: 100%;
height: 100%; // allow textareas
padding: $form-floating-padding-y $form-floating-padding-x;
overflow: hidden;
color: rgba(var(--#{$prefix}body-color-rgb), #{$form-floating-label-opacity});
text-align: start;
text-overflow: ellipsis;
white-space: nowrap;
pointer-events: none;
border: $input-border-width solid transparent; // Required for aligning label's text with the input as it affects inner box model
transform-origin: 0 0;
@include transition($form-floating-transition);
}
> .form-control,
> .form-control-plaintext {
padding: $form-floating-padding-y $form-floating-padding-x;
&::placeholder {
color: transparent;
}
&:focus,
&:not(:placeholder-shown) {
padding-top: $form-floating-input-padding-t;
padding-bottom: $form-floating-input-padding-b;
}
// Duplicated because `:-webkit-autofill` invalidates other selectors when grouped
&:-webkit-autofill {
padding-top: $form-floating-input-padding-t;
padding-bottom: $form-floating-input-padding-b;
}
}
> .form-select {
padding-top: $form-floating-input-padding-t; padding-top: $form-floating-input-padding-t;
padding-bottom: $form-floating-input-padding-b; padding-bottom: $form-floating-input-padding-b;
padding-left: $form-floating-padding-x;
}
> .form-control:focus,
> .form-control:not(:placeholder-shown),
> .form-control-plaintext,
> .form-select {
~ label {
transform: $form-floating-label-transform;
}
} }
// Duplicated because `:-webkit-autofill` invalidates other selectors when grouped // Duplicated because `:-webkit-autofill` invalidates other selectors when grouped
&:-webkit-autofill { > .form-control:-webkit-autofill {
padding-top: $form-floating-input-padding-t; ~ label {
padding-bottom: $form-floating-input-padding-b; transform: $form-floating-label-transform;
}
}
> textarea:focus,
> textarea:not(:placeholder-shown) {
~ label::after {
position: absolute;
inset: $form-floating-padding-y ($form-floating-padding-x * .5);
z-index: -1;
height: $form-floating-label-height;
content: "";
background-color: $input-bg;
@include border-radius($input-border-radius);
}
}
> textarea:disabled ~ label::after {
background-color: $input-disabled-bg;
} }
}
> .form-select { > .form-control-plaintext {
padding-top: $form-floating-input-padding-t; ~ label {
padding-bottom: $form-floating-input-padding-b; border-width: $input-border-width 0; // Required to properly position label text - as explained above
padding-left: $form-floating-padding-x; }
} }
> .form-control:focus, > :disabled ~ label,
> .form-control:not(:placeholder-shown), > .form-control:disabled ~ label { // Required for `.form-control`s because of specificity
> .form-control-plaintext, color: $form-floating-label-disabled-color;
> .form-select {
~ label {
transform: $form-floating-label-transform;
} }
} }
// Duplicated because `:-webkit-autofill` invalidates other selectors when grouped
> .form-control:-webkit-autofill {
~ label {
transform: $form-floating-label-transform;
}
}
> textarea:focus,
> textarea:not(:placeholder-shown) {
~ label::after {
position: absolute;
inset: $form-floating-padding-y ($form-floating-padding-x * .5);
z-index: -1;
height: $form-floating-label-height;
content: "";
background-color: $input-bg;
@include border-radius($input-border-radius);
}
}
> textarea:disabled ~ label::after {
background-color: $input-disabled-bg;
}
> .form-control-plaintext {
~ label {
border-width: $input-border-width 0; // Required to properly position label text - as explained above
}
}
> :disabled ~ label,
> .form-control:disabled ~ label { // Required for `.form-control`s because of specificity
color: $form-floating-label-disabled-color;
}
} }

View File

@ -7,192 +7,194 @@
@use "../mixins/transition" as *; @use "../mixins/transition" as *;
@use "../mixins/color-mode" as *; @use "../mixins/color-mode" as *;
// @layer forms {
// Check/radio //
// // Check/radio
//
.form-check { .form-check {
display: block; display: block;
min-height: $form-check-min-height; min-height: $form-check-min-height;
padding-left: $form-check-padding-start; padding-left: $form-check-padding-start;
margin-bottom: $form-check-margin-bottom; margin-bottom: $form-check-margin-bottom;
.form-check-input {
float: left;
margin-left: $form-check-padding-start * -1;
}
}
.form-check-reverse {
padding-right: $form-check-padding-start;
padding-left: 0;
text-align: right;
.form-check-input {
float: right;
margin-right: $form-check-padding-start * -1;
margin-left: 0;
}
}
.form-check-input {
--#{$prefix}form-check-bg: #{$form-check-input-bg};
flex-shrink: 0;
width: $form-check-input-width;
height: $form-check-input-width;
margin-top: ($line-height-base - $form-check-input-width) * .5; // line-height minus check height
vertical-align: top;
appearance: none;
background-color: var(--#{$prefix}form-check-bg);
background-image: var(--#{$prefix}form-check-bg-image);
background-repeat: no-repeat;
background-position: center;
background-size: contain;
border: $form-check-input-border;
print-color-adjust: exact; // Keep themed appearance for print
@include transition($form-check-transition);
&[type="checkbox"] {
@include border-radius($form-check-input-border-radius);
}
&[type="radio"] {
// stylelint-disable-next-line property-disallowed-list
border-radius: $form-check-radio-border-radius;
}
&:active {
filter: $form-check-input-active-filter;
}
&:focus {
border-color: $form-check-input-focus-border;
outline: 0;
box-shadow: $form-check-input-focus-box-shadow;
}
&:checked {
background-color: $form-check-input-checked-bg-color;
border-color: $form-check-input-checked-border-color;
&[type="checkbox"] {
@if $enable-gradients {
--#{$prefix}form-check-bg-image: #{escape-svg($form-check-input-checked-bg-image)}, var(--#{$prefix}gradient);
} @else {
--#{$prefix}form-check-bg-image: #{escape-svg($form-check-input-checked-bg-image)};
}
}
&[type="radio"] {
@if $enable-gradients {
--#{$prefix}form-check-bg-image: #{escape-svg($form-check-radio-checked-bg-image)}, var(--#{$prefix}gradient);
} @else {
--#{$prefix}form-check-bg-image: #{escape-svg($form-check-radio-checked-bg-image)};
}
}
}
&[type="checkbox"]:indeterminate {
background-color: $form-check-input-indeterminate-bg-color;
border-color: $form-check-input-indeterminate-border-color;
@if $enable-gradients {
--#{$prefix}form-check-bg-image: #{escape-svg($form-check-input-indeterminate-bg-image)}, var(--#{$prefix}gradient);
} @else {
--#{$prefix}form-check-bg-image: #{escape-svg($form-check-input-indeterminate-bg-image)};
}
}
&:disabled {
pointer-events: none;
filter: none;
opacity: $form-check-input-disabled-opacity;
}
// Use disabled attribute in addition of :disabled pseudo-class
// See: https://github.com/twbs/bootstrap/issues/28247
&[disabled],
&:disabled {
~ .form-check-label {
cursor: default;
opacity: $form-check-label-disabled-opacity;
}
}
}
.form-check-label {
color: $form-check-label-color;
cursor: $form-check-label-cursor;
}
//
// Switch
//
.form-switch {
padding-left: $form-switch-padding-start;
.form-check-input {
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-bg-image)};
width: $form-switch-width;
margin-left: $form-switch-padding-start * -1;
background-image: var(--#{$prefix}form-switch-bg);
background-position: left center;
@include border-radius($form-switch-border-radius, 0);
@include transition($form-switch-transition);
&:focus {
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-focus-bg-image)};
}
&:checked {
background-position: $form-switch-checked-bg-position;
@if $enable-gradients {
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-checked-bg-image)}, var(--#{$prefix}gradient);
} @else {
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-checked-bg-image)};
}
}
}
&.form-check-reverse {
padding-right: $form-switch-padding-start;
padding-left: 0;
.form-check-input { .form-check-input {
margin-right: $form-switch-padding-start * -1; float: left;
margin-left: $form-check-padding-start * -1;
}
}
.form-check-reverse {
padding-right: $form-check-padding-start;
padding-left: 0;
text-align: right;
.form-check-input {
float: right;
margin-right: $form-check-padding-start * -1;
margin-left: 0; margin-left: 0;
} }
} }
}
.form-check-inline { .form-check-input {
display: inline-block; --#{$prefix}form-check-bg: #{$form-check-input-bg};
margin-right: $form-check-inline-margin-end;
}
.btn-check { flex-shrink: 0;
position: absolute; width: $form-check-input-width;
clip: rect(0, 0, 0, 0); height: $form-check-input-width;
pointer-events: none; margin-top: ($line-height-base - $form-check-input-width) * .5; // line-height minus check height
vertical-align: top;
appearance: none;
background-color: var(--#{$prefix}form-check-bg);
background-image: var(--#{$prefix}form-check-bg-image);
background-repeat: no-repeat;
background-position: center;
background-size: contain;
border: $form-check-input-border;
print-color-adjust: exact; // Keep themed appearance for print
@include transition($form-check-transition);
&[disabled], &[type="checkbox"] {
&:disabled { @include border-radius($form-check-input-border-radius);
+ .btn { }
&[type="radio"] {
// stylelint-disable-next-line property-disallowed-list
border-radius: $form-check-radio-border-radius;
}
&:active {
filter: $form-check-input-active-filter;
}
&:focus {
border-color: $form-check-input-focus-border;
outline: 0;
box-shadow: $form-check-input-focus-box-shadow;
}
&:checked {
background-color: $form-check-input-checked-bg-color;
border-color: $form-check-input-checked-border-color;
&[type="checkbox"] {
@if $enable-gradients {
--#{$prefix}form-check-bg-image: #{escape-svg($form-check-input-checked-bg-image)}, var(--#{$prefix}gradient);
} @else {
--#{$prefix}form-check-bg-image: #{escape-svg($form-check-input-checked-bg-image)};
}
}
&[type="radio"] {
@if $enable-gradients {
--#{$prefix}form-check-bg-image: #{escape-svg($form-check-radio-checked-bg-image)}, var(--#{$prefix}gradient);
} @else {
--#{$prefix}form-check-bg-image: #{escape-svg($form-check-radio-checked-bg-image)};
}
}
}
&[type="checkbox"]:indeterminate {
background-color: $form-check-input-indeterminate-bg-color;
border-color: $form-check-input-indeterminate-border-color;
@if $enable-gradients {
--#{$prefix}form-check-bg-image: #{escape-svg($form-check-input-indeterminate-bg-image)}, var(--#{$prefix}gradient);
} @else {
--#{$prefix}form-check-bg-image: #{escape-svg($form-check-input-indeterminate-bg-image)};
}
}
&:disabled {
pointer-events: none; pointer-events: none;
filter: none; filter: none;
opacity: $form-check-btn-check-disabled-opacity; opacity: $form-check-input-disabled-opacity;
} }
}
}
@if $enable-dark-mode { // Use disabled attribute in addition of :disabled pseudo-class
@include color-mode(dark) { // See: https://github.com/twbs/bootstrap/issues/28247
.form-switch .form-check-input:not(:checked):not(:focus) { &[disabled],
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-bg-image-dark)}; &:disabled {
~ .form-check-label {
cursor: default;
opacity: $form-check-label-disabled-opacity;
}
}
}
.form-check-label {
color: $form-check-label-color;
cursor: $form-check-label-cursor;
}
//
// Switch
//
.form-switch {
padding-left: $form-switch-padding-start;
.form-check-input {
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-bg-image)};
width: $form-switch-width;
margin-left: $form-switch-padding-start * -1;
background-image: var(--#{$prefix}form-switch-bg);
background-position: left center;
@include border-radius($form-switch-border-radius, 0);
@include transition($form-switch-transition);
&:focus {
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-focus-bg-image)};
}
&:checked {
background-position: $form-switch-checked-bg-position;
@if $enable-gradients {
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-checked-bg-image)}, var(--#{$prefix}gradient);
} @else {
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-checked-bg-image)};
}
}
}
&.form-check-reverse {
padding-right: $form-switch-padding-start;
padding-left: 0;
.form-check-input {
margin-right: $form-switch-padding-start * -1;
margin-left: 0;
}
}
}
.form-check-inline {
display: inline-block;
margin-right: $form-check-inline-margin-end;
}
.btn-check {
position: absolute;
clip: rect(0, 0, 0, 0);
pointer-events: none;
&[disabled],
&:disabled {
+ .btn {
pointer-events: none;
filter: none;
opacity: $form-check-btn-check-disabled-opacity;
}
}
}
@if $enable-dark-mode {
@include color-mode(dark) {
.form-switch .form-check-input:not(:checked):not(:focus) {
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-bg-image-dark)};
}
} }
} }
} }

View File

@ -5,217 +5,220 @@
@use "../mixins/box-shadow" as *; @use "../mixins/box-shadow" as *;
@use "../mixins/transition" as *; @use "../mixins/transition" as *;
@use "../mixins/gradients" as *; @use "../mixins/gradients" as *;
// //
// General form controls (plus a few specific high-level interventions) // General form controls (plus a few specific high-level interventions)
// //
.form-control { @layer forms {
display: block; .form-control {
width: 100%; display: block;
padding: $input-padding-y $input-padding-x; width: 100%;
font-family: $input-font-family; padding: $input-padding-y $input-padding-x;
@include font-size($input-font-size); font-family: $input-font-family;
font-weight: $input-font-weight; @include font-size($input-font-size);
line-height: $input-line-height; font-weight: $input-font-weight;
color: $input-color; line-height: $input-line-height;
appearance: none; // Fix appearance for date inputs in Safari color: $input-color;
background-color: $input-bg; appearance: none; // Fix appearance for date inputs in Safari
background-clip: padding-box; background-color: $input-bg;
border: $input-border-width solid $input-border-color; background-clip: padding-box;
border: $input-border-width solid $input-border-color;
// Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS. // Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.
@include border-radius($input-border-radius, 0); @include border-radius($input-border-radius, 0);
@include box-shadow($input-box-shadow); @include box-shadow($input-box-shadow);
@include transition($input-transition); @include transition($input-transition);
&[type="file"] { &[type="file"] {
overflow: hidden; // prevent pseudo element button overlap overflow: hidden; // prevent pseudo element button overlap
&:not(:disabled):not([readonly]) {
cursor: pointer;
}
}
// Customize the `:focus` state to imitate native WebKit styles.
&:focus {
color: $input-focus-color;
background-color: $input-focus-bg;
border-color: $input-focus-border-color;
outline: 0;
@if $enable-shadows {
@include box-shadow($input-box-shadow, $input-focus-box-shadow);
} @else {
// Avoid using mixin so we can pass custom focus shadow properly
box-shadow: $input-focus-box-shadow;
}
}
&::-webkit-date-and-time-value {
// On Android Chrome, form-control's "width: 100%" makes the input width too small
// Tested under Android 11 / Chrome 89, Android 12 / Chrome 100, Android 13 / Chrome 109
//
// On iOS Safari, form-control's "appearance: none" + "width: 100%" makes the input width too small
// Tested under iOS 16.2 / Safari 16.2
min-width: 85px; // Seems to be a good minimum safe width
// Add some height to date inputs on iOS
// https://github.com/twbs/bootstrap/issues/23307
// TODO: we can remove this workaround once https://bugs.webkit.org/show_bug.cgi?id=198959 is resolved
// Multiply line-height by 1em if it has no unit
height: if(unit($input-line-height) == "", $input-line-height * 1em, $input-line-height);
// Android Chrome type="date" is taller than the other inputs
// because of "margin: 1px 24px 1px 4px" inside the shadow DOM
// Tested under Android 11 / Chrome 89, Android 12 / Chrome 100, Android 13 / Chrome 109
margin: 0;
}
// Prevent excessive date input height in Webkit
// https://github.com/twbs/bootstrap/issues/34433
&::-webkit-datetime-edit {
display: block;
padding: 0;
}
// Placeholder
&::placeholder {
color: $input-placeholder-color;
// Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.
opacity: 1;
}
// Disabled inputs
//
// HTML5 says that controls under a fieldset > legend:first-child won't be
// disabled if the fieldset is disabled. Due to implementation difficulty, we
// don't honor that edge case; we style them as disabled anyway.
&:disabled {
color: $input-disabled-color;
background-color: $input-disabled-bg;
border-color: $input-disabled-border-color;
// iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.
opacity: 1;
}
// File input buttons theming
&::file-selector-button {
padding: $input-padding-y $input-padding-x;
margin: (-$input-padding-y) (-$input-padding-x);
margin-inline-end: $input-padding-x;
color: $form-file-button-color;
@include gradient-bg($form-file-button-bg);
pointer-events: none;
border-color: inherit;
border-style: solid;
border-width: 0;
border-inline-end-width: $input-border-width;
border-radius: 0; // stylelint-disable-line property-disallowed-list
@include transition($btn-transition);
}
&:hover:not(:disabled):not([readonly])::file-selector-button {
background-color: $form-file-button-hover-bg;
}
}
// Readonly controls as plain text
//
// Apply class to a readonly input to make it appear like regular plain
// text (without any border, background color, focus indicator)
.form-control-plaintext {
display: block;
width: 100%;
padding: $input-padding-y 0;
margin-bottom: 0; // match inputs if this class comes on inputs with default margins
line-height: $input-line-height;
color: $input-plaintext-color;
background-color: transparent;
border: solid transparent;
border-width: $input-border-width 0;
&:focus {
outline: 0;
}
&.form-control-sm,
&.form-control-lg {
padding-right: 0;
padding-left: 0;
}
}
// Form control sizing
//
// Build on `.form-control` with modifier classes to decrease or increase the
// height and font-size of form controls.
//
// Repeated in `_input_group.scss` to avoid Sass extend issues.
.form-control-sm {
min-height: $input-height-sm;
padding: $input-padding-y-sm $input-padding-x-sm;
@include font-size($input-font-size-sm);
@include border-radius($input-border-radius-sm);
&::file-selector-button {
padding: $input-padding-y-sm $input-padding-x-sm;
margin: (-$input-padding-y-sm) (-$input-padding-x-sm);
margin-inline-end: $input-padding-x-sm;
}
}
.form-control-lg {
min-height: $input-height-lg;
padding: $input-padding-y-lg $input-padding-x-lg;
@include font-size($input-font-size-lg);
@include border-radius($input-border-radius-lg);
&::file-selector-button {
padding: $input-padding-y-lg $input-padding-x-lg;
margin: (-$input-padding-y-lg) (-$input-padding-x-lg);
margin-inline-end: $input-padding-x-lg;
}
}
// Make sure textareas don't shrink too much when resized
// https://github.com/twbs/bootstrap/pull/29124
// stylelint-disable selector-no-qualifying-type
textarea {
&.form-control {
min-height: $input-height;
}
&.form-control-sm {
min-height: $input-height-sm;
}
&.form-control-lg {
min-height: $input-height-lg;
}
}
// stylelint-enable selector-no-qualifying-type
.form-control-color {
width: $form-color-width;
height: $input-height;
padding: $input-padding-y;
&:not(:disabled):not([readonly]) { &:not(:disabled):not([readonly]) {
cursor: pointer; cursor: pointer;
} }
}
// Customize the `:focus` state to imitate native WebKit styles. &::-moz-color-swatch {
&:focus { border: 0 !important; // stylelint-disable-line declaration-no-important
color: $input-focus-color; @include border-radius($input-border-radius);
background-color: $input-focus-bg;
border-color: $input-focus-border-color;
outline: 0;
@if $enable-shadows {
@include box-shadow($input-box-shadow, $input-focus-box-shadow);
} @else {
// Avoid using mixin so we can pass custom focus shadow properly
box-shadow: $input-focus-box-shadow;
} }
}
&::-webkit-date-and-time-value { &::-webkit-color-swatch {
// On Android Chrome, form-control's "width: 100%" makes the input width too small border: 0 !important; // stylelint-disable-line declaration-no-important
// Tested under Android 11 / Chrome 89, Android 12 / Chrome 100, Android 13 / Chrome 109 @include border-radius($input-border-radius);
// }
// On iOS Safari, form-control's "appearance: none" + "width: 100%" makes the input width too small
// Tested under iOS 16.2 / Safari 16.2
min-width: 85px; // Seems to be a good minimum safe width
// Add some height to date inputs on iOS &.form-control-sm { height: $input-height-sm; }
// https://github.com/twbs/bootstrap/issues/23307 &.form-control-lg { height: $input-height-lg; }
// TODO: we can remove this workaround once https://bugs.webkit.org/show_bug.cgi?id=198959 is resolved
// Multiply line-height by 1em if it has no unit
height: if(unit($input-line-height) == "", $input-line-height * 1em, $input-line-height);
// Android Chrome type="date" is taller than the other inputs
// because of "margin: 1px 24px 1px 4px" inside the shadow DOM
// Tested under Android 11 / Chrome 89, Android 12 / Chrome 100, Android 13 / Chrome 109
margin: 0;
}
// Prevent excessive date input height in Webkit
// https://github.com/twbs/bootstrap/issues/34433
&::-webkit-datetime-edit {
display: block;
padding: 0;
}
// Placeholder
&::placeholder {
color: $input-placeholder-color;
// Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.
opacity: 1;
}
// Disabled inputs
//
// HTML5 says that controls under a fieldset > legend:first-child won't be
// disabled if the fieldset is disabled. Due to implementation difficulty, we
// don't honor that edge case; we style them as disabled anyway.
&:disabled {
color: $input-disabled-color;
background-color: $input-disabled-bg;
border-color: $input-disabled-border-color;
// iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.
opacity: 1;
}
// File input buttons theming
&::file-selector-button {
padding: $input-padding-y $input-padding-x;
margin: (-$input-padding-y) (-$input-padding-x);
margin-inline-end: $input-padding-x;
color: $form-file-button-color;
@include gradient-bg($form-file-button-bg);
pointer-events: none;
border-color: inherit;
border-style: solid;
border-width: 0;
border-inline-end-width: $input-border-width;
border-radius: 0; // stylelint-disable-line property-disallowed-list
@include transition($btn-transition);
}
&:hover:not(:disabled):not([readonly])::file-selector-button {
background-color: $form-file-button-hover-bg;
} }
} }
// Readonly controls as plain text
//
// Apply class to a readonly input to make it appear like regular plain
// text (without any border, background color, focus indicator)
.form-control-plaintext {
display: block;
width: 100%;
padding: $input-padding-y 0;
margin-bottom: 0; // match inputs if this class comes on inputs with default margins
line-height: $input-line-height;
color: $input-plaintext-color;
background-color: transparent;
border: solid transparent;
border-width: $input-border-width 0;
&:focus {
outline: 0;
}
&.form-control-sm,
&.form-control-lg {
padding-right: 0;
padding-left: 0;
}
}
// Form control sizing
//
// Build on `.form-control` with modifier classes to decrease or increase the
// height and font-size of form controls.
//
// Repeated in `_input_group.scss` to avoid Sass extend issues.
.form-control-sm {
min-height: $input-height-sm;
padding: $input-padding-y-sm $input-padding-x-sm;
@include font-size($input-font-size-sm);
@include border-radius($input-border-radius-sm);
&::file-selector-button {
padding: $input-padding-y-sm $input-padding-x-sm;
margin: (-$input-padding-y-sm) (-$input-padding-x-sm);
margin-inline-end: $input-padding-x-sm;
}
}
.form-control-lg {
min-height: $input-height-lg;
padding: $input-padding-y-lg $input-padding-x-lg;
@include font-size($input-font-size-lg);
@include border-radius($input-border-radius-lg);
&::file-selector-button {
padding: $input-padding-y-lg $input-padding-x-lg;
margin: (-$input-padding-y-lg) (-$input-padding-x-lg);
margin-inline-end: $input-padding-x-lg;
}
}
// Make sure textareas don't shrink too much when resized
// https://github.com/twbs/bootstrap/pull/29124
// stylelint-disable selector-no-qualifying-type
textarea {
&.form-control {
min-height: $input-height;
}
&.form-control-sm {
min-height: $input-height-sm;
}
&.form-control-lg {
min-height: $input-height-lg;
}
}
// stylelint-enable selector-no-qualifying-type
.form-control-color {
width: $form-color-width;
height: $input-height;
padding: $input-padding-y;
&:not(:disabled):not([readonly]) {
cursor: pointer;
}
&::-moz-color-swatch {
border: 0 !important; // stylelint-disable-line declaration-no-important
@include border-radius($input-border-radius);
}
&::-webkit-color-swatch {
border: 0 !important; // stylelint-disable-line declaration-no-important
@include border-radius($input-border-radius);
}
&.form-control-sm { height: $input-height-sm; }
&.form-control-lg { height: $input-height-lg; }
}

View File

@ -11,88 +11,90 @@
// elements cannot be mixed. As such, there are no shared styles for focus or // elements cannot be mixed. As such, there are no shared styles for focus or
// active states on prefixed selectors. // active states on prefixed selectors.
.form-range { @layer forms {
width: 100%; .form-range {
height: add($form-range-thumb-height, $form-range-thumb-focus-box-shadow-width * 2); width: 100%;
padding: 0; // Need to reset padding height: add($form-range-thumb-height, $form-range-thumb-focus-box-shadow-width * 2);
appearance: none; padding: 0; // Need to reset padding
background-color: transparent;
&:focus {
outline: 0;
// Pseudo-elements must be split across multiple rulesets to have an effect.
// No box-shadow() mixin for focus accessibility.
&::-webkit-slider-thumb { box-shadow: $form-range-thumb-focus-box-shadow; }
&::-moz-range-thumb { box-shadow: $form-range-thumb-focus-box-shadow; }
}
&::-moz-focus-outer {
border: 0;
}
&::-webkit-slider-thumb {
width: $form-range-thumb-width;
height: $form-range-thumb-height;
margin-top: ($form-range-track-height - $form-range-thumb-height) * .5; // Webkit specific
appearance: none; appearance: none;
@include gradient-bg($form-range-thumb-bg); background-color: transparent;
border: $form-range-thumb-border;
@include border-radius($form-range-thumb-border-radius);
@include box-shadow($form-range-thumb-box-shadow);
@include transition($form-range-thumb-transition);
&:active { &:focus {
@include gradient-bg($form-range-thumb-active-bg); outline: 0;
// Pseudo-elements must be split across multiple rulesets to have an effect.
// No box-shadow() mixin for focus accessibility.
&::-webkit-slider-thumb { box-shadow: $form-range-thumb-focus-box-shadow; }
&::-moz-range-thumb { box-shadow: $form-range-thumb-focus-box-shadow; }
} }
}
&::-webkit-slider-runnable-track { &::-moz-focus-outer {
width: $form-range-track-width; border: 0;
height: $form-range-track-height;
color: transparent; // Why?
cursor: $form-range-track-cursor;
background-color: $form-range-track-bg;
border-color: transparent;
@include border-radius($form-range-track-border-radius);
@include box-shadow($form-range-track-box-shadow);
}
&::-moz-range-thumb {
width: $form-range-thumb-width;
height: $form-range-thumb-height;
appearance: none;
@include gradient-bg($form-range-thumb-bg);
border: $form-range-thumb-border;
@include border-radius($form-range-thumb-border-radius);
@include box-shadow($form-range-thumb-box-shadow);
@include transition($form-range-thumb-transition);
&:active {
@include gradient-bg($form-range-thumb-active-bg);
} }
}
&::-moz-range-track {
width: $form-range-track-width;
height: $form-range-track-height;
color: transparent;
cursor: $form-range-track-cursor;
background-color: $form-range-track-bg;
border-color: transparent; // Firefox specific?
@include border-radius($form-range-track-border-radius);
@include box-shadow($form-range-track-box-shadow);
}
&:disabled {
pointer-events: none;
&::-webkit-slider-thumb { &::-webkit-slider-thumb {
background-color: $form-range-thumb-disabled-bg; width: $form-range-thumb-width;
height: $form-range-thumb-height;
margin-top: ($form-range-track-height - $form-range-thumb-height) * .5; // Webkit specific
appearance: none;
@include gradient-bg($form-range-thumb-bg);
border: $form-range-thumb-border;
@include border-radius($form-range-thumb-border-radius);
@include box-shadow($form-range-thumb-box-shadow);
@include transition($form-range-thumb-transition);
&:active {
@include gradient-bg($form-range-thumb-active-bg);
}
}
&::-webkit-slider-runnable-track {
width: $form-range-track-width;
height: $form-range-track-height;
color: transparent; // Why?
cursor: $form-range-track-cursor;
background-color: $form-range-track-bg;
border-color: transparent;
@include border-radius($form-range-track-border-radius);
@include box-shadow($form-range-track-box-shadow);
} }
&::-moz-range-thumb { &::-moz-range-thumb {
background-color: $form-range-thumb-disabled-bg; width: $form-range-thumb-width;
height: $form-range-thumb-height;
appearance: none;
@include gradient-bg($form-range-thumb-bg);
border: $form-range-thumb-border;
@include border-radius($form-range-thumb-border-radius);
@include box-shadow($form-range-thumb-box-shadow);
@include transition($form-range-thumb-transition);
&:active {
@include gradient-bg($form-range-thumb-active-bg);
}
}
&::-moz-range-track {
width: $form-range-track-width;
height: $form-range-track-height;
color: transparent;
cursor: $form-range-track-cursor;
background-color: $form-range-track-bg;
border-color: transparent; // Firefox specific?
@include border-radius($form-range-track-border-radius);
@include box-shadow($form-range-track-box-shadow);
}
&:disabled {
pointer-events: none;
&::-webkit-slider-thumb {
background-color: $form-range-thumb-disabled-bg;
}
&::-moz-range-thumb {
background-color: $form-range-thumb-disabled-bg;
}
} }
} }
} }

View File

@ -11,78 +11,80 @@
// Replaces the browser default select with a custom one, mostly pulled from // Replaces the browser default select with a custom one, mostly pulled from
// https://primer.github.io/. // https://primer.github.io/.
.form-select { @layer forms {
--#{$prefix}form-select-bg-img: #{escape-svg($form-select-indicator)}; .form-select {
--#{$prefix}form-select-bg-img: #{escape-svg($form-select-indicator)};
display: block; display: block;
width: 100%; width: 100%;
padding: $form-select-padding-y $form-select-indicator-padding $form-select-padding-y $form-select-padding-x; padding: $form-select-padding-y $form-select-indicator-padding $form-select-padding-y $form-select-padding-x;
font-family: $form-select-font-family; font-family: $form-select-font-family;
@include font-size($form-select-font-size); @include font-size($form-select-font-size);
font-weight: $form-select-font-weight; font-weight: $form-select-font-weight;
line-height: $form-select-line-height; line-height: $form-select-line-height;
color: $form-select-color; color: $form-select-color;
appearance: none; appearance: none;
background-color: $form-select-bg; background-color: $form-select-bg;
background-image: var(--#{$prefix}form-select-bg-img), var(--#{$prefix}form-select-bg-icon, none); background-image: var(--#{$prefix}form-select-bg-img), var(--#{$prefix}form-select-bg-icon, none);
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: $form-select-bg-position; background-position: $form-select-bg-position;
background-size: $form-select-bg-size; background-size: $form-select-bg-size;
border: $form-select-border-width solid $form-select-border-color; border: $form-select-border-width solid $form-select-border-color;
@include border-radius($form-select-border-radius, 0); @include border-radius($form-select-border-radius, 0);
@include box-shadow($form-select-box-shadow); @include box-shadow($form-select-box-shadow);
@include transition($form-select-transition); @include transition($form-select-transition);
&:focus { &:focus {
border-color: $form-select-focus-border-color; border-color: $form-select-focus-border-color;
outline: 0; outline: 0;
@if $enable-shadows { @if $enable-shadows {
@include box-shadow($form-select-box-shadow, $form-select-focus-box-shadow); @include box-shadow($form-select-box-shadow, $form-select-focus-box-shadow);
} @else { } @else {
// Avoid using mixin so we can pass custom focus shadow properly // Avoid using mixin so we can pass custom focus shadow properly
box-shadow: $form-select-focus-box-shadow; box-shadow: $form-select-focus-box-shadow;
}
}
&[multiple],
&[size]:not([size="1"]) {
padding-right: $form-select-padding-x;
background-image: none;
}
&:disabled {
color: $form-select-disabled-color;
background-color: $form-select-disabled-bg;
border-color: $form-select-disabled-border-color;
}
// Remove outline from select box in FF
&:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 $form-select-color;
} }
} }
&[multiple], .form-select-sm {
&[size]:not([size="1"]) { padding-top: $form-select-padding-y-sm;
padding-right: $form-select-padding-x; padding-bottom: $form-select-padding-y-sm;
background-image: none; padding-left: $form-select-padding-x-sm;
@include font-size($form-select-font-size-sm);
@include border-radius($form-select-border-radius-sm);
} }
&:disabled { .form-select-lg {
color: $form-select-disabled-color; padding-top: $form-select-padding-y-lg;
background-color: $form-select-disabled-bg; padding-bottom: $form-select-padding-y-lg;
border-color: $form-select-disabled-border-color; padding-left: $form-select-padding-x-lg;
@include font-size($form-select-font-size-lg);
@include border-radius($form-select-border-radius-lg);
} }
// Remove outline from select box in FF @if $enable-dark-mode {
&:-moz-focusring { @include color-mode(dark) {
color: transparent; .form-select {
text-shadow: 0 0 0 $form-select-color; --#{$prefix}form-select-bg-img: #{escape-svg($form-select-indicator-dark)};
} }
}
.form-select-sm {
padding-top: $form-select-padding-y-sm;
padding-bottom: $form-select-padding-y-sm;
padding-left: $form-select-padding-x-sm;
@include font-size($form-select-font-size-sm);
@include border-radius($form-select-border-radius-sm);
}
.form-select-lg {
padding-top: $form-select-padding-y-lg;
padding-bottom: $form-select-padding-y-lg;
padding-left: $form-select-padding-x-lg;
@include font-size($form-select-font-size-lg);
@include border-radius($form-select-border-radius-lg);
}
@if $enable-dark-mode {
@include color-mode(dark) {
.form-select {
--#{$prefix}form-select-bg-img: #{escape-svg($form-select-indicator-dark)};
} }
} }
} }

View File

@ -1,13 +1,16 @@
@use "../variables" as *; @use "../variables" as *;
@use "../vendor/rfs" as *; @use "../vendor/rfs" as *;
// //
// Form text // Form text
// //
.form-text { @layer forms {
margin-top: $form-text-margin-top; .form-text {
@include font-size($form-text-font-size); margin-top: $form-text-margin-top;
font-style: $form-text-font-style; @include font-size($form-text-font-size);
font-weight: $form-text-font-weight; font-style: $form-text-font-style;
color: $form-text-color; font-weight: $form-text-font-weight;
color: $form-text-color;
}
} }

View File

@ -8,131 +8,133 @@
// Base styles // Base styles
// //
.input-group { @layer forms {
position: relative; .input-group {
display: flex;
flex-wrap: wrap; // For form validation feedback
align-items: stretch;
width: 100%;
> .form-control,
> .form-select,
> .form-floating {
position: relative; // For focus state's z-index
flex: 1 1 auto;
width: 1%;
min-width: 0; // https://stackoverflow.com/questions/36247140/why-dont-flex-items-shrink-past-content-size
}
// Bring the "active" form control to the top of surrounding elements
> .form-control:focus,
> .form-select:focus,
> .form-floating:focus-within {
z-index: 5;
}
// Ensure buttons are always above inputs for more visually pleasing borders.
// This isn't needed for `.input-group-text` since it shares the same border-color
// as our inputs.
.btn {
position: relative; position: relative;
z-index: 2; display: flex;
flex-wrap: wrap; // For form validation feedback
align-items: stretch;
width: 100%;
&:focus { > .form-control,
> .form-select,
> .form-floating {
position: relative; // For focus state's z-index
flex: 1 1 auto;
width: 1%;
min-width: 0; // https://stackoverflow.com/questions/36247140/why-dont-flex-items-shrink-past-content-size
}
// Bring the "active" form control to the top of surrounding elements
> .form-control:focus,
> .form-select:focus,
> .form-floating:focus-within {
z-index: 5; z-index: 5;
} }
}
}
// Ensure buttons are always above inputs for more visually pleasing borders.
// This isn't needed for `.input-group-text` since it shares the same border-color
// as our inputs.
.btn {
position: relative;
z-index: 2;
// Textual addons &:focus {
// z-index: 5;
// Serves as a catch-all element for any text or radio/checkbox input you wish }
// to prepend or append to an input.
.input-group-text {
display: flex;
align-items: center;
padding: $input-group-addon-padding-y $input-group-addon-padding-x;
@include font-size($input-font-size); // Match inputs
font-weight: $input-group-addon-font-weight;
line-height: $input-line-height;
color: $input-group-addon-color;
text-align: center;
white-space: nowrap;
background-color: $input-group-addon-bg;
border: $input-border-width solid $input-group-addon-border-color;
@include border-radius($input-border-radius);
}
// Sizing
//
// Remix the default form control sizing classes into new ones for easier
// manipulation.
.input-group-lg > .form-control,
.input-group-lg > .form-select,
.input-group-lg > .input-group-text,
.input-group-lg > .btn {
padding: $input-padding-y-lg $input-padding-x-lg;
@include font-size($input-font-size-lg);
@include border-radius($input-border-radius-lg);
}
.input-group-sm > .form-control,
.input-group-sm > .form-select,
.input-group-sm > .input-group-text,
.input-group-sm > .btn {
padding: $input-padding-y-sm $input-padding-x-sm;
@include font-size($input-font-size-sm);
@include border-radius($input-border-radius-sm);
}
.input-group-lg > .form-select,
.input-group-sm > .form-select {
padding-right: $form-select-padding-x + $form-select-indicator-padding;
}
// Rounded corners
//
// These rulesets must come after the sizing ones to properly override sm and lg
// border-radius values when extending. They're more specific than we'd like
// with the `.input-group >` part, but without it, we cannot override the sizing.
// stylelint-disable-next-line no-duplicate-selectors
.input-group {
&:not(.has-validation) {
> :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),
> .dropdown-toggle:nth-last-child(n + 3),
> .form-floating:not(:last-child) > .form-control,
> .form-floating:not(:last-child) > .form-select {
@include border-end-radius(0);
} }
} }
&.has-validation {
> :nth-last-child(n + 3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating), // Textual addons
> .dropdown-toggle:nth-last-child(n + 4), //
> .form-floating:nth-last-child(n + 3) > .form-control, // Serves as a catch-all element for any text or radio/checkbox input you wish
> .form-floating:nth-last-child(n + 3) > .form-select { // to prepend or append to an input.
@include border-end-radius(0);
.input-group-text {
display: flex;
align-items: center;
padding: $input-group-addon-padding-y $input-group-addon-padding-x;
@include font-size($input-font-size); // Match inputs
font-weight: $input-group-addon-font-weight;
line-height: $input-line-height;
color: $input-group-addon-color;
text-align: center;
white-space: nowrap;
background-color: $input-group-addon-bg;
border: $input-border-width solid $input-group-addon-border-color;
@include border-radius($input-border-radius);
}
// Sizing
//
// Remix the default form control sizing classes into new ones for easier
// manipulation.
.input-group-lg > .form-control,
.input-group-lg > .form-select,
.input-group-lg > .input-group-text,
.input-group-lg > .btn {
padding: $input-padding-y-lg $input-padding-x-lg;
@include font-size($input-font-size-lg);
@include border-radius($input-border-radius-lg);
}
.input-group-sm > .form-control,
.input-group-sm > .form-select,
.input-group-sm > .input-group-text,
.input-group-sm > .btn {
padding: $input-padding-y-sm $input-padding-x-sm;
@include font-size($input-font-size-sm);
@include border-radius($input-border-radius-sm);
}
.input-group-lg > .form-select,
.input-group-sm > .form-select {
padding-right: $form-select-padding-x + $form-select-indicator-padding;
}
// Rounded corners
//
// These rulesets must come after the sizing ones to properly override sm and lg
// border-radius values when extending. They're more specific than we'd like
// with the `.input-group >` part, but without it, we cannot override the sizing.
// stylelint-disable-next-line no-duplicate-selectors
.input-group {
&:not(.has-validation) {
> :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),
> .dropdown-toggle:nth-last-child(n + 3),
> .form-floating:not(:last-child) > .form-control,
> .form-floating:not(:last-child) > .form-select {
@include border-end-radius(0);
}
}
&.has-validation {
> :nth-last-child(n + 3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),
> .dropdown-toggle:nth-last-child(n + 4),
> .form-floating:nth-last-child(n + 3) > .form-control,
> .form-floating:nth-last-child(n + 3) > .form-select {
@include border-end-radius(0);
}
}
$validation-messages: "";
@each $state in map.keys($form-validation-states) {
$validation-messages: $validation-messages + ":not(." + unquote($state) + "-tooltip)" + ":not(." + unquote($state) + "-feedback)";
}
> :not(:first-child):not(.dropdown-menu)#{$validation-messages} {
margin-left: calc(-1 * #{$input-border-width}); // stylelint-disable-line function-disallowed-list
@include border-start-radius(0);
}
> .form-floating:not(:first-child) > .form-control,
> .form-floating:not(:first-child) > .form-select {
@include border-start-radius(0);
} }
} }
$validation-messages: "";
@each $state in map.keys($form-validation-states) {
$validation-messages: $validation-messages + ":not(." + unquote($state) + "-tooltip)" + ":not(." + unquote($state) + "-feedback)";
}
> :not(:first-child):not(.dropdown-menu)#{$validation-messages} {
margin-left: calc(-1 * #{$input-border-width}); // stylelint-disable-line function-disallowed-list
@include border-start-radius(0);
}
> .form-floating:not(:first-child) > .form-control,
> .form-floating:not(:first-child) > .form-select {
@include border-start-radius(0);
}
} }

View File

@ -1,38 +1,41 @@
@use "../variables" as *; @use "../variables" as *;
@use "../vendor/rfs" as *; @use "../vendor/rfs" as *;
// //
// Labels // Labels
// //
.form-label { @layer forms {
margin-bottom: $form-label-margin-bottom; .form-label {
@include font-size($form-label-font-size); margin-bottom: $form-label-margin-bottom;
font-style: $form-label-font-style; @include font-size($form-label-font-size);
font-weight: $form-label-font-weight; font-style: $form-label-font-style;
color: $form-label-color; font-weight: $form-label-font-weight;
} color: $form-label-color;
}
// For use with horizontal and inline forms, when you need the label (or legend) // For use with horizontal and inline forms, when you need the label (or legend)
// text to align with the form controls. // text to align with the form controls.
.col-form-label { .col-form-label {
padding-top: add($input-padding-y, $input-border-width); padding-top: add($input-padding-y, $input-border-width);
padding-bottom: add($input-padding-y, $input-border-width); padding-bottom: add($input-padding-y, $input-border-width);
margin-bottom: 0; // Override the `<legend>` default margin-bottom: 0; // Override the `<legend>` default
@include font-size(inherit); // Override the `<legend>` default @include font-size(inherit); // Override the `<legend>` default
font-style: $form-label-font-style; font-style: $form-label-font-style;
font-weight: $form-label-font-weight; font-weight: $form-label-font-weight;
line-height: $input-line-height; line-height: $input-line-height;
color: $form-label-color; color: $form-label-color;
} }
.col-form-label-lg { .col-form-label-lg {
padding-top: add($input-padding-y-lg, $input-border-width); padding-top: add($input-padding-y-lg, $input-border-width);
padding-bottom: add($input-padding-y-lg, $input-border-width); padding-bottom: add($input-padding-y-lg, $input-border-width);
@include font-size($input-font-size-lg); @include font-size($input-font-size-lg);
} }
.col-form-label-sm { .col-form-label-sm {
padding-top: add($input-padding-y-sm, $input-border-width); padding-top: add($input-padding-y-sm, $input-border-width);
padding-bottom: add($input-padding-y-sm, $input-border-width); padding-bottom: add($input-padding-y-sm, $input-border-width);
@include font-size($input-font-size-sm); @include font-size($input-font-size-sm);
}
} }

View File

@ -14,170 +14,172 @@
// This mixin uses an `if()` technique to be compatible with Dart Sass // This mixin uses an `if()` technique to be compatible with Dart Sass
// See https://github.com/sass/sass/issues/1873#issuecomment-152293725 for more details // See https://github.com/sass/sass/issues/1873#issuecomment-152293725 for more details
// scss-docs-start form-validation-mixins @layer forms {
@mixin form-validation-state-selector($state) { // scss-docs-start form-validation-mixins
@if ($state == "valid" or $state == "invalid") { @mixin form-validation-state-selector($state) {
.was-validated #{if(&, "&", "")}:#{$state}, @if ($state == "valid" or $state == "invalid") {
#{if(&, "&", "")}.is-#{$state} { .was-validated #{if(&, "&", "")}:#{$state},
@content; #{if(&, "&", "")}.is-#{$state} {
} @content;
} @else { }
#{if(&, "&", "")}.is-#{$state} { } @else {
@content; #{if(&, "&", "")}.is-#{$state} {
} @content;
} }
}
@mixin form-validation-state(
$state,
$color,
$icon,
$tooltip-color: color-contrast($color),
$tooltip-bg-color: rgba($color, $form-feedback-tooltip-opacity),
$focus-box-shadow: 0 0 $input-btn-focus-blur $input-focus-width rgba($color, $input-btn-focus-color-opacity),
$border-color: $color
) {
.#{$state}-feedback {
display: none;
width: 100%;
margin-top: $form-feedback-margin-top;
@include font-size($form-feedback-font-size);
font-style: $form-feedback-font-style;
color: $color;
}
.#{$state}-tooltip {
position: absolute;
top: 100%;
z-index: 5;
display: none;
max-width: 100%; // Contain to parent when possible
padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x;
margin-top: .1rem;
@include font-size($form-feedback-tooltip-font-size);
line-height: $form-feedback-tooltip-line-height;
color: $tooltip-color;
background-color: $tooltip-bg-color;
@include border-radius($form-feedback-tooltip-border-radius);
}
@include form-validation-state-selector($state) {
~ .#{$state}-feedback,
~ .#{$state}-tooltip {
display: block;
} }
} }
.form-control { @mixin form-validation-state(
$state,
$color,
$icon,
$tooltip-color: color-contrast($color),
$tooltip-bg-color: rgba($color, $form-feedback-tooltip-opacity),
$focus-box-shadow: 0 0 $input-btn-focus-blur $input-focus-width rgba($color, $input-btn-focus-color-opacity),
$border-color: $color
) {
.#{$state}-feedback {
display: none;
width: 100%;
margin-top: $form-feedback-margin-top;
@include font-size($form-feedback-font-size);
font-style: $form-feedback-font-style;
color: $color;
}
.#{$state}-tooltip {
position: absolute;
top: 100%;
z-index: 5;
display: none;
max-width: 100%; // Contain to parent when possible
padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x;
margin-top: .1rem;
@include font-size($form-feedback-tooltip-font-size);
line-height: $form-feedback-tooltip-line-height;
color: $tooltip-color;
background-color: $tooltip-bg-color;
@include border-radius($form-feedback-tooltip-border-radius);
}
@include form-validation-state-selector($state) { @include form-validation-state-selector($state) {
border-color: $border-color; ~ .#{$state}-feedback,
~ .#{$state}-tooltip {
@if $enable-validation-icons { display: block;
padding-right: $input-height-inner;
background-image: escape-svg($icon);
background-repeat: no-repeat;
background-position: right $input-height-inner-quarter center;
background-size: $input-height-inner-half $input-height-inner-half;
}
&:focus {
border-color: $border-color;
@if $enable-shadows {
@include box-shadow($input-box-shadow, $focus-box-shadow);
} @else {
// Avoid using mixin so we can pass custom focus shadow properly
box-shadow: $focus-box-shadow;
}
} }
} }
}
// stylelint-disable-next-line selector-no-qualifying-type .form-control {
textarea.form-control {
@include form-validation-state-selector($state) {
@if $enable-validation-icons {
padding-right: $input-height-inner;
background-position: top $input-height-inner-quarter right $input-height-inner-quarter;
}
}
}
.form-select {
@include form-validation-state-selector($state) {
border-color: $border-color;
@if $enable-validation-icons {
&:not([multiple]):not([size]),
&:not([multiple])[size="1"] {
--#{$prefix}form-select-bg-icon: #{escape-svg($icon)};
padding-right: $form-select-feedback-icon-padding-end;
background-position: $form-select-bg-position, $form-select-feedback-icon-position;
background-size: $form-select-bg-size, $form-select-feedback-icon-size;
}
}
&:focus {
border-color: $border-color;
@if $enable-shadows {
@include box-shadow($form-select-box-shadow, $focus-box-shadow);
} @else {
// Avoid using mixin so we can pass custom focus shadow properly
box-shadow: $focus-box-shadow;
}
}
}
}
.form-control-color {
@include form-validation-state-selector($state) {
@if $enable-validation-icons {
width: add($form-color-width, $input-height-inner);
}
}
}
.form-check-input {
@include form-validation-state-selector($state) {
border-color: $border-color;
&:checked {
background-color: $color;
}
&:focus {
box-shadow: $focus-box-shadow;
}
~ .form-check-label {
color: $color;
}
}
}
.form-check-inline .form-check-input {
~ .#{$state}-feedback {
margin-left: .5em;
}
}
.input-group {
> .form-control:not(:focus),
> .form-select:not(:focus),
> .form-floating:not(:focus-within) {
@include form-validation-state-selector($state) { @include form-validation-state-selector($state) {
@if $state == "valid" { border-color: $border-color;
z-index: 3;
} @else if $state == "invalid" { @if $enable-validation-icons {
z-index: 4; padding-right: $input-height-inner;
background-image: escape-svg($icon);
background-repeat: no-repeat;
background-position: right $input-height-inner-quarter center;
background-size: $input-height-inner-half $input-height-inner-half;
}
&:focus {
border-color: $border-color;
@if $enable-shadows {
@include box-shadow($input-box-shadow, $focus-box-shadow);
} @else {
// Avoid using mixin so we can pass custom focus shadow properly
box-shadow: $focus-box-shadow;
}
}
}
}
// stylelint-disable-next-line selector-no-qualifying-type
textarea.form-control {
@include form-validation-state-selector($state) {
@if $enable-validation-icons {
padding-right: $input-height-inner;
background-position: top $input-height-inner-quarter right $input-height-inner-quarter;
}
}
}
.form-select {
@include form-validation-state-selector($state) {
border-color: $border-color;
@if $enable-validation-icons {
&:not([multiple]):not([size]),
&:not([multiple])[size="1"] {
--#{$prefix}form-select-bg-icon: #{escape-svg($icon)};
padding-right: $form-select-feedback-icon-padding-end;
background-position: $form-select-bg-position, $form-select-feedback-icon-position;
background-size: $form-select-bg-size, $form-select-feedback-icon-size;
}
}
&:focus {
border-color: $border-color;
@if $enable-shadows {
@include box-shadow($form-select-box-shadow, $focus-box-shadow);
} @else {
// Avoid using mixin so we can pass custom focus shadow properly
box-shadow: $focus-box-shadow;
}
}
}
}
.form-control-color {
@include form-validation-state-selector($state) {
@if $enable-validation-icons {
width: add($form-color-width, $input-height-inner);
}
}
}
.form-check-input {
@include form-validation-state-selector($state) {
border-color: $border-color;
&:checked {
background-color: $color;
}
&:focus {
box-shadow: $focus-box-shadow;
}
~ .form-check-label {
color: $color;
}
}
}
.form-check-inline .form-check-input {
~ .#{$state}-feedback {
margin-left: .5em;
}
}
.input-group {
> .form-control:not(:focus),
> .form-select:not(:focus),
> .form-floating:not(:focus-within) {
@include form-validation-state-selector($state) {
@if $state == "valid" {
z-index: 3;
} @else if $state == "invalid" {
z-index: 4;
}
} }
} }
} }
} }
} // scss-docs-end form-validation-mixins
// scss-docs-end form-validation-mixins
// scss-docs-start form-validation-states-loop // scss-docs-start form-validation-states-loop
@each $state, $data in $form-validation-states { @each $state, $data in $form-validation-states {
@include form-validation-state($state, $data...); @include form-validation-state($state, $data...);
}
// scss-docs-end form-validation-states-loop
} }
// scss-docs-end form-validation-states-loop

View File

@ -1,5 +1,7 @@
@use "../mixins/clearfix" as *; @use "../mixins/clearfix" as *;
.clearfix { @layer helpers {
@include clearfix(); .clearfix {
@include clearfix();
}
} }

View File

@ -3,9 +3,11 @@
@use "../variables" as *; @use "../variables" as *;
// All-caps `RGBA()` function used because of this Sass bug: https://github.com/sass/node-sass/issues/2251 // All-caps `RGBA()` function used because of this Sass bug: https://github.com/sass/node-sass/issues/2251
@each $color, $value in $theme-colors { @layer helpers {
.text-bg-#{$color} { @each $color, $value in $theme-colors {
color: color-contrast($value) if($enable-important-utilities, !important, null); .text-bg-#{$color} {
background-color: RGBA(var(--#{$prefix}#{$color}-rgb), var(--#{$prefix}bg-opacity, 1)) if($enable-important-utilities, !important, null); color: color-contrast($value) if($enable-important-utilities, !important, null);
background-color: RGBA(var(--#{$prefix}#{$color}-rgb), var(--#{$prefix}bg-opacity, 1)) if($enable-important-utilities, !important, null);
}
} }
} }

View File

@ -3,32 +3,34 @@
@use "../variables" as *; @use "../variables" as *;
// All-caps `RGBA()` function used because of this Sass bug: https://github.com/sass/node-sass/issues/2251 // All-caps `RGBA()` function used because of this Sass bug: https://github.com/sass/node-sass/issues/2251
@each $color, $value in $theme-colors { @layer helpers {
.link-#{$color} { @each $color, $value in $theme-colors {
color: RGBA(var(--#{$prefix}#{$color}-rgb), var(--#{$prefix}link-opacity, 1)) if($enable-important-utilities, !important, null); .link-#{$color} {
text-decoration-color: RGBA(var(--#{$prefix}#{$color}-rgb), var(--#{$prefix}link-underline-opacity, 1)) if($enable-important-utilities, !important, null); color: RGBA(var(--#{$prefix}#{$color}-rgb), var(--#{$prefix}link-opacity, 1)) if($enable-important-utilities, !important, null);
text-decoration-color: RGBA(var(--#{$prefix}#{$color}-rgb), var(--#{$prefix}link-underline-opacity, 1)) if($enable-important-utilities, !important, null);
@if $link-shade-percentage != 0 {
&:hover,
&:focus {
$hover-color: if(color-contrast($value) == $color-contrast-light, shade-color($value, $link-shade-percentage), tint-color($value, $link-shade-percentage));
color: RGBA(#{to-rgb($hover-color)}, var(--#{$prefix}link-opacity, 1)) if($enable-important-utilities, !important, null);
text-decoration-color: RGBA(to-rgb($hover-color), var(--#{$prefix}link-underline-opacity, 1)) if($enable-important-utilities, !important, null);
}
}
}
}
// One-off special link helper as a bridge until v6
.link-body-emphasis {
color: RGBA(var(--#{$prefix}emphasis-color-rgb), var(--#{$prefix}link-opacity, 1)) if($enable-important-utilities, !important, null);
text-decoration-color: RGBA(var(--#{$prefix}emphasis-color-rgb), var(--#{$prefix}link-underline-opacity, 1)) if($enable-important-utilities, !important, null);
@if $link-shade-percentage != 0 { @if $link-shade-percentage != 0 {
&:hover, &:hover,
&:focus { &:focus {
$hover-color: if(color-contrast($value) == $color-contrast-light, shade-color($value, $link-shade-percentage), tint-color($value, $link-shade-percentage)); color: RGBA(var(--#{$prefix}emphasis-color-rgb), var(--#{$prefix}link-opacity, .75)) if($enable-important-utilities, !important, null);
color: RGBA(#{to-rgb($hover-color)}, var(--#{$prefix}link-opacity, 1)) if($enable-important-utilities, !important, null); text-decoration-color: RGBA(var(--#{$prefix}emphasis-color-rgb), var(--#{$prefix}link-underline-opacity, .75)) if($enable-important-utilities, !important, null);
text-decoration-color: RGBA(to-rgb($hover-color), var(--#{$prefix}link-underline-opacity, 1)) if($enable-important-utilities, !important, null);
} }
} }
} }
} }
// One-off special link helper as a bridge until v6
.link-body-emphasis {
color: RGBA(var(--#{$prefix}emphasis-color-rgb), var(--#{$prefix}link-opacity, 1)) if($enable-important-utilities, !important, null);
text-decoration-color: RGBA(var(--#{$prefix}emphasis-color-rgb), var(--#{$prefix}link-underline-opacity, 1)) if($enable-important-utilities, !important, null);
@if $link-shade-percentage != 0 {
&:hover,
&:focus {
color: RGBA(var(--#{$prefix}emphasis-color-rgb), var(--#{$prefix}link-opacity, .75)) if($enable-important-utilities, !important, null);
text-decoration-color: RGBA(var(--#{$prefix}emphasis-color-rgb), var(--#{$prefix}link-underline-opacity, .75)) if($enable-important-utilities, !important, null);
}
}
}

View File

@ -1,7 +1,9 @@
@use "../config" as *; @use "../config" as *;
.focus-ring:focus { @layer helpers {
outline: 0; .focus-ring:focus {
// By default, there is no `--bs-focus-ring-x`, `--bs-focus-ring-y`, or `--bs-focus-ring-blur`, but we provide CSS variables with fallbacks to initial `0` values outline: 0;
box-shadow: var(--#{$prefix}focus-ring-x, 0) var(--#{$prefix}focus-ring-y, 0) var(--#{$prefix}focus-ring-blur, 0) var(--#{$prefix}focus-ring-width) var(--#{$prefix}focus-ring-color); // By default, there is no `--bs-focus-ring-x`, `--bs-focus-ring-y`, or `--bs-focus-ring-blur`, but we provide CSS variables with fallbacks to initial `0` values
box-shadow: var(--#{$prefix}focus-ring-x, 0) var(--#{$prefix}focus-ring-y, 0) var(--#{$prefix}focus-ring-blur, 0) var(--#{$prefix}focus-ring-width) var(--#{$prefix}focus-ring-color);
}
} }

View File

@ -1,28 +1,31 @@
@use "../config" as *; @use "../config" as *;
@use "../variables" as *; @use "../variables" as *;
@use "../mixins/transition" as *; @use "../mixins/transition" as *;
.icon-link {
display: inline-flex;
gap: $icon-link-gap;
align-items: center;
text-decoration-color: rgba(var(--#{$prefix}link-color-rgb), var(--#{$prefix}link-opacity, .5));
text-underline-offset: $icon-link-underline-offset;
backface-visibility: hidden;
> .bi { @layer helpers {
flex-shrink: 0; .icon-link {
width: $icon-link-icon-size; display: inline-flex;
height: $icon-link-icon-size; gap: $icon-link-gap;
fill: currentcolor; align-items: center;
@include transition($icon-link-icon-transition); text-decoration-color: rgba(var(--#{$prefix}link-color-rgb), var(--#{$prefix}link-opacity, .5));
} text-underline-offset: $icon-link-underline-offset;
} backface-visibility: hidden;
.icon-link-hover {
&:hover,
&:focus-visible {
> .bi { > .bi {
transform: var(--#{$prefix}icon-link-transform, $icon-link-icon-transform); flex-shrink: 0;
width: $icon-link-icon-size;
height: $icon-link-icon-size;
fill: currentcolor;
@include transition($icon-link-icon-transition);
}
}
.icon-link-hover {
&:hover,
&:focus-visible {
> .bi {
transform: var(--#{$prefix}icon-link-transform, $icon-link-icon-transform);
}
} }
} }
} }

View File

@ -5,37 +5,39 @@
// Shorthand // Shorthand
.fixed-top { @layer helpers {
position: fixed; .fixed-top {
top: 0; position: fixed;
right: 0; top: 0;
left: 0; right: 0;
z-index: $zindex-fixed; left: 0;
} z-index: $zindex-fixed;
}
.fixed-bottom { .fixed-bottom {
position: fixed; position: fixed;
right: 0; right: 0;
bottom: 0; bottom: 0;
left: 0; left: 0;
z-index: $zindex-fixed; z-index: $zindex-fixed;
} }
// Responsive sticky top and bottom // Responsive sticky top and bottom
@each $breakpoint in map.keys($grid-breakpoints) { @each $breakpoint in map.keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) { @include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints); $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
.sticky#{$infix}-top { .sticky#{$infix}-top {
position: sticky; position: sticky;
top: 0; top: 0;
z-index: $zindex-sticky; z-index: $zindex-sticky;
} }
.sticky#{$infix}-bottom { .sticky#{$infix}-bottom {
position: sticky; position: sticky;
bottom: 0; bottom: 0;
z-index: $zindex-sticky; z-index: $zindex-sticky;
}
} }
} }
} }

View File

@ -1,15 +1,17 @@
// scss-docs-start stacks @layer helpers {
.hstack { // scss-docs-start stacks
display: flex; .hstack {
flex-direction: row; display: flex;
align-items: center; flex-direction: row;
align-self: stretch; align-items: center;
} align-self: stretch;
}
.vstack { .vstack {
display: flex; display: flex;
flex: 1 1 auto; flex: 1 1 auto;
flex-direction: column; flex-direction: column;
align-self: stretch; align-self: stretch;
}
// scss-docs-end stacks
} }
// scss-docs-end stacks

View File

@ -4,14 +4,16 @@
// Stretched link // Stretched link
// //
.stretched-link { @layer helpers {
&::#{$stretched-link-pseudo-element} { .stretched-link {
position: absolute; &::#{$stretched-link-pseudo-element} {
top: 0; position: absolute;
right: 0; top: 0;
bottom: 0; right: 0;
left: 0; bottom: 0;
z-index: $stretched-link-z-index; left: 0;
content: ""; z-index: $stretched-link-z-index;
content: "";
}
} }
} }

View File

@ -1,7 +1,11 @@
@use "../mixins/text-truncate" as *; @use "../mixins/text-truncate" as *;
//
// Text truncation // Text truncation
// //
.text-truncate { @layer helpers {
@include text-truncate(); .text-truncate {
@include text-truncate();
}
} }

View File

@ -4,7 +4,9 @@
// Visually hidden // Visually hidden
// //
.visually-hidden, @layer helpers {
.visually-hidden-focusable:not(:focus):not(:focus-within) { .visually-hidden,
@include visually-hidden(); .visually-hidden-focusable:not(:focus):not(:focus-within) {
@include visually-hidden();
}
} }

View File

@ -1,10 +1,12 @@
@use "../variables" as *; @use "../variables" as *;
.vr { @layer helpers {
display: inline-block; .vr {
align-self: stretch; display: inline-block;
width: $vr-border-width; align-self: stretch;
min-height: 1em; width: $vr-border-width;
background-color: currentcolor; min-height: 1em;
opacity: $hr-opacity; background-color: currentcolor;
opacity: $hr-opacity;
}
} }

View File

@ -1,11 +1,11 @@
@import "clearfix"; @forward "clearfix";
@import "color-bg"; @forward "color-bg";
@import "colored-links"; @forward "colored-links";
@import "focus-ring"; @forward "focus-ring";
@import "icon-link"; @forward "icon-link";
@import "position"; @forward "position";
@import "stacks"; @forward "stacks";
@import "visually-hidden"; @forward "visually-hidden";
@import "stretched-link"; @forward "stretched-link";
@import "text-truncation"; @forward "text-truncation";
@import "vr"; @forward "vr";

View File

@ -16,37 +16,39 @@
margin-left: auto; margin-left: auto;
} }
@if $enable-container-classes { @layer layout {
// Single container class with breakpoint max-widths @if $enable-container-classes {
.container, // Single container class with breakpoint max-widths
// 100% wide container at all breakpoints .container,
.container-fluid { // 100% wide container at all breakpoints
@include make-container(); .container-fluid {
} @include make-container();
// Responsive containers that are 100% wide until a breakpoint
@each $breakpoint, $container-max-width in $container-max-widths {
.container-#{$breakpoint} {
@extend .container-fluid;
} }
@include media-breakpoint-up($breakpoint, $grid-breakpoints) { // Responsive containers that are 100% wide until a breakpoint
%responsive-container-#{$breakpoint} { @each $breakpoint, $container-max-width in $container-max-widths {
max-width: $container-max-width; .container-#{$breakpoint} {
@extend .container-fluid;
} }
// Extend each breakpoint which is smaller or equal to the current breakpoint @include media-breakpoint-up($breakpoint, $grid-breakpoints) {
$extend-breakpoint: true; %responsive-container-#{$breakpoint} {
max-width: $container-max-width;
}
@each $name, $width in $grid-breakpoints { // Extend each breakpoint which is smaller or equal to the current breakpoint
@if ($extend-breakpoint) { $extend-breakpoint: true;
.container#{breakpoint-infix($name, $grid-breakpoints)} {
@extend %responsive-container-#{$breakpoint};
}
// Once the current breakpoint is reached, stop extending @each $name, $width in $grid-breakpoints {
@if ($breakpoint == $name) { @if ($extend-breakpoint) {
$extend-breakpoint: false; .container#{breakpoint-infix($name, $grid-breakpoints)} {
@extend %responsive-container-#{$breakpoint};
}
// Once the current breakpoint is reached, stop extending
@if ($breakpoint == $name) {
$extend-breakpoint: false;
}
} }
} }
} }

View File

@ -6,50 +6,52 @@
@use "../mixins/utilities" as *; @use "../mixins/utilities" as *;
@use "../utilities" as *; @use "../utilities" as *;
// Loop over each breakpoint @layer utilities {
@each $breakpoint in map.keys($grid-breakpoints) { // Loop over each breakpoint
// Generate media query if needed
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
// Loop over each utility property
@each $key, $utility in $utilities {
// The utility can be disabled with `false`, thus check if the utility is a map first
// Only proceed if responsive media queries are enabled or if it's the base media query
@if type-of($utility) == "map" and (map.get($utility, responsive) or $infix == "") {
@include generate-utility($utility, $infix);
}
}
}
}
// RFS rescaling
@media (min-width: $rfs-mq-value) {
@each $breakpoint in map.keys($grid-breakpoints) { @each $breakpoint in map.keys($grid-breakpoints) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
@if (map.get($grid-breakpoints, $breakpoint) < $rfs-breakpoint) { // Generate media query if needed
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
// Loop over each utility property // Loop over each utility property
@each $key, $utility in $utilities { @each $key, $utility in $utilities {
// The utility can be disabled with `false`, thus check if the utility is a map first // The utility can be disabled with `false`, thus check if the utility is a map first
// Only proceed if responsive media queries are enabled or if it's the base media query // Only proceed if responsive media queries are enabled or if it's the base media query
@if type-of($utility) == "map" and map.get($utility, rfs) and (map.get($utility, responsive) or $infix == "") { @if type-of($utility) == "map" and (map.get($utility, responsive) or $infix == "") {
@include generate-utility($utility, $infix, true); @include generate-utility($utility, $infix);
}
}
}
}
// RFS rescaling
@media (min-width: $rfs-mq-value) {
@each $breakpoint in map.keys($grid-breakpoints) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
@if (map.get($grid-breakpoints, $breakpoint) < $rfs-breakpoint) {
// Loop over each utility property
@each $key, $utility in $utilities {
// The utility can be disabled with `false`, thus check if the utility is a map first
// Only proceed if responsive media queries are enabled or if it's the base media query
@if type-of($utility) == "map" and map.get($utility, rfs) and (map.get($utility, responsive) or $infix == "") {
@include generate-utility($utility, $infix, true);
}
} }
} }
} }
} }
}
// Print utilities // Print utilities
@media print { @media print {
@each $key, $utility in $utilities { @each $key, $utility in $utilities {
// The utility can be disabled with `false`, thus check if the utility is a map first // The utility can be disabled with `false`, thus check if the utility is a map first
// Then check if the utility needs print styles // Then check if the utility needs print styles
@if type-of($utility) == "map" and map.get($utility, print) == true { @if type-of($utility) == "map" and map.get($utility, print) == true {
@include generate-utility($utility, "-print"); @include generate-utility($utility, "-print");
}
} }
} }
} }