diff options
| author | XhmikosR <[email protected]> | 2021-08-18 07:29:56 +0300 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-08-18 07:29:56 +0300 |
| commit | 433a148c9e61aa942801fd8101dfa5c4045fdaed (patch) | |
| tree | f41db59fd06019169df5ea0338213ec0e298f226 /scss | |
| parent | b97cfa163b5098db70e03b27c91fca5dde9c267e (diff) | |
| parent | 18b3e1ac71f73d006756684a285c5a818e2d1454 (diff) | |
| download | bootstrap-global-focus-vars.tar.xz bootstrap-global-focus-vars.zip | |
Merge branch 'main' into global-focus-varsglobal-focus-vars
Diffstat (limited to 'scss')
43 files changed, 916 insertions, 231 deletions
diff --git a/scss/_accordion.scss b/scss/_accordion.scss index 298a553e0..fc62ceb88 100644 --- a/scss/_accordion.scss +++ b/scss/_accordion.scss @@ -12,18 +12,15 @@ color: $accordion-button-color; text-align: left; // Reset button style background-color: $accordion-button-bg; - border: $accordion-border-width solid $accordion-border-color; + border: 0; @include border-radius(0); overflow-anchor: none; @include transition($accordion-transition); - &.collapsed { - border-bottom-width: 0; - } - &:not(.collapsed) { color: $accordion-button-active-color; background-color: $accordion-button-active-bg; + box-shadow: inset 0 ($accordion-border-width * -1) 0 $accordion-border-color; &::after { background-image: escape-svg($accordion-button-active-icon); @@ -61,33 +58,37 @@ } .accordion-item { + background-color: $accordion-bg; + border: $accordion-border-width solid $accordion-border-color; + &:first-of-type { + @include border-top-radius($accordion-border-radius); + .accordion-button { - @include border-top-radius($accordion-border-radius); + @include border-top-radius($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($accordion-border-radius); + .accordion-button { - // Only set a border-radius on the last item if the accordion is collapsed &.collapsed { - border-bottom-width: $accordion-border-width; - @include border-bottom-radius($accordion-border-radius); + @include border-bottom-radius($accordion-inner-border-radius); } } .accordion-collapse { - border-bottom-width: $accordion-border-width; @include border-bottom-radius($accordion-border-radius); } } } -.accordion-collapse { - border: solid $accordion-border-color; - border-width: 0 $accordion-border-width; -} - .accordion-body { padding: $accordion-body-padding-y $accordion-body-padding-x; } @@ -98,29 +99,20 @@ // Remove borders and border-radius to keep accordion items edge-to-edge. .accordion-flush { - .accordion-button { - border-right: 0; - border-left: 0; - @include border-radius(0); - } - .accordion-collapse { border-width: 0; } .accordion-item { - &:first-of-type { - .accordion-button { - border-top-width: 0; - @include border-top-radius(0); - } - } + border-right: 0; + border-left: 0; + @include border-radius(0); - &:last-of-type { - .accordion-button.collapsed { - border-bottom-width: 0; - @include border-bottom-radius(0); - } + &:first-child { border-top: 0; } + &:last-child { border-bottom: 0; } + + .accordion-button { + @include border-radius(0); } } } diff --git a/scss/_card.scss b/scss/_card.scss index 4b2eebf13..22890f5c9 100644 --- a/scss/_card.scss +++ b/scss/_card.scss @@ -13,6 +13,7 @@ background-clip: border-box; border: $card-border-width solid $card-border-color; @include border-radius($card-border-radius); + @include box-shadow($card-box-shadow); > hr { margin-right: 0; @@ -55,7 +56,7 @@ } .card-subtitle { - margin-top: -$card-title-spacer-y / 2; + margin-top: -$card-title-spacer-y * .5; margin-bottom: 0; } @@ -65,11 +66,11 @@ .card-link { &:hover { - text-decoration: none; + text-decoration: if($link-hover-decoration == underline, none, null); } + .card-link { - margin-left: $card-spacer-x #{"/* rtl:ignore */"}; + margin-left: $card-spacer-x; } } @@ -106,9 +107,9 @@ // .card-header-tabs { - margin-right: -$card-cap-padding-x / 2; + margin-right: -$card-cap-padding-x * .5; margin-bottom: -$card-cap-padding-y; - margin-left: -$card-cap-padding-x / 2; + margin-left: -$card-cap-padding-x * .5; border-bottom: 0; @if $nav-tabs-link-active-bg != $card-bg { @@ -120,8 +121,8 @@ } .card-header-pills { - margin-right: -$card-cap-padding-x / 2; - margin-left: -$card-cap-padding-x / 2; + margin-right: -$card-cap-padding-x * .5; + margin-left: -$card-cap-padding-x * .5; } // Card image diff --git a/scss/_carousel.scss b/scss/_carousel.scss index d389c3042..3d8fb15a0 100644 --- a/scss/_carousel.scss +++ b/scss/_carousel.scss @@ -202,9 +202,9 @@ .carousel-caption { position: absolute; - right: (100% - $carousel-caption-width) / 2; + right: (100% - $carousel-caption-width) * .5; bottom: $carousel-caption-spacer; - left: (100% - $carousel-caption-width) / 2; + left: (100% - $carousel-caption-width) * .5; padding-top: $carousel-caption-padding-y; padding-bottom: $carousel-caption-padding-y; color: $carousel-caption-color; diff --git a/scss/_dropdown.scss b/scss/_dropdown.scss index b71058c58..adc114327 100644 --- a/scss/_dropdown.scss +++ b/scss/_dropdown.scss @@ -16,7 +16,6 @@ // The dropdown menu .dropdown-menu { position: absolute; - top: 100%; z-index: $zindex-dropdown; display: none; // none by default, but block on "open" of the menu min-width: $dropdown-min-width; @@ -33,6 +32,7 @@ @include box-shadow($dropdown-box-shadow); &[data-bs-popper] { + top: 100%; left: 0; margin-top: $dropdown-spacer; } @@ -50,8 +50,8 @@ --bs-position: start; &[data-bs-popper] { - right: auto #{"/* rtl:ignore */"}; - left: 0 #{"/* rtl:ignore */"}; + right: auto; + left: 0; } } @@ -59,8 +59,8 @@ --bs-position: end; &[data-bs-popper] { - right: 0 #{"/* rtl:ignore */"}; - left: auto #{"/* rtl:ignore */"}; + right: 0; + left: auto; } } } @@ -70,14 +70,11 @@ // Allow for dropdowns to go bottom up (aka, dropup-menu) // Just add .dropup after the standard .dropdown class and you're set. .dropup { - .dropdown-menu { + .dropdown-menu[data-bs-popper] { top: auto; bottom: 100%; - - &[data-bs-popper] { - margin-top: 0; - margin-bottom: $dropdown-spacer; - } + margin-top: 0; + margin-bottom: $dropdown-spacer; } .dropdown-toggle { @@ -86,15 +83,12 @@ } .dropend { - .dropdown-menu { + .dropdown-menu[data-bs-popper] { top: 0; right: auto; left: 100%; - - &[data-bs-popper] { - margin-top: 0; - margin-left: $dropdown-spacer; - } + margin-top: 0; + margin-left: $dropdown-spacer; } .dropdown-toggle { @@ -106,15 +100,12 @@ } .dropstart { - .dropdown-menu { + .dropdown-menu[data-bs-popper] { top: 0; right: 100%; left: auto; - - &[data-bs-popper] { - margin-top: 0; - margin-right: $dropdown-spacer; - } + margin-top: 0; + margin-right: $dropdown-spacer; } .dropdown-toggle { diff --git a/scss/_functions.scss b/scss/_functions.scss index 29114fc81..30539b393 100644 --- a/scss/_functions.scss +++ b/scss/_functions.scss @@ -32,6 +32,47 @@ } } +// Colors +@function to-rgb($value) { + @return red($value), green($value), blue($value); +} + +// stylelint-disable scss/dollar-variable-pattern +@function rgba-css-var($identifier, $target) { + @if $identifier == "body" and $target == "bg" { + @return rgba(var(--#{$variable-prefix}#{$identifier}-bg-rgb), var(--#{$variable-prefix}#{$target}-opacity)); + } @if $identifier == "body" and $target == "text" { + @return rgba(var(--#{$variable-prefix}#{$identifier}-color-rgb), var(--#{$variable-prefix}#{$target}-opacity)); + } @else { + @return rgba(var(--#{$variable-prefix}#{$identifier}-rgb), var(--#{$variable-prefix}#{$target}-opacity)); + } +} + +@function map-loop($map, $func, $args...) { + $_map: (); + + @each $key, $value in $map { + // allow to pass the $key and $value of the map as an function argument + $_args: (); + @each $arg in $args { + $_args: append($_args, if($arg == "$key", $key, if($arg == "$value", $value, $arg))); + } + + $_map: map-merge($_map, ($key: call(get-function($func), $_args...))); + } + + @return $_map; +} +// stylelint-enable scss/dollar-variable-pattern + +@function varify($list) { + $result: null; + @each $entry in $list { + $result: append($result, var(--#{$variable-prefix}#{$entry}), space); + } + @return $result; +} + // Internal Bootstrap function to turn maps into its negative variant. // It prefixes the keys with `n` and makes the value negative. @function negativify-map($map) { @@ -55,6 +96,16 @@ @return $result; } +// Merge multiple maps +@function map-merge-multiple($maps...) { + $merged-maps: (); + + @each $map in $maps { + $merged-maps: map-merge($merged-maps, $map); + } + @return $merged-maps; +} + // Replace `$search` with `$replace` in `$string` // Used on our SVG icon backgrounds for custom forms. // @@ -95,7 +146,7 @@ // Color contrast // See https://github.com/twbs/bootstrap/pull/30168 -// A list of pre-calculated numbers of pow(($value / 255 + .055) / 1.055, 2.4). (from 0 to 255) +// A list of pre-calculated numbers of pow(divide((divide($value, 255) + .055), 1.055), 2.4). (from 0 to 255) // stylelint-disable-next-line scss/dollar-variable-default, scss/dollar-variable-pattern $_luminance-list: .0008 .001 .0011 .0013 .0015 .0017 .002 .0022 .0025 .0027 .003 .0033 .0037 .004 .0044 .0048 .0052 .0056 .006 .0065 .007 .0075 .008 .0086 .0091 .0097 .0103 .011 .0116 .0123 .013 .0137 .0144 .0152 .016 .0168 .0176 .0185 .0194 .0203 .0212 .0222 .0232 .0242 .0252 .0262 .0273 .0284 .0296 .0307 .0319 .0331 .0343 .0356 .0369 .0382 .0395 .0409 .0423 .0437 .0452 .0467 .0482 .0497 .0513 .0529 .0545 .0561 .0578 .0595 .0612 .063 .0648 .0666 .0685 .0704 .0723 .0742 .0762 .0782 .0802 .0823 .0844 .0865 .0887 .0908 .0931 .0953 .0976 .0999 .1022 .1046 .107 .1095 .1119 .1144 .117 .1195 .1221 .1248 .1274 .1301 .1329 .1356 .1384 .1413 .1441 .147 .15 .1529 .1559 .159 .162 .1651 .1683 .1714 .1746 .1779 .1812 .1845 .1878 .1912 .1946 .1981 .2016 .2051 .2086 .2122 .2159 .2195 .2232 .227 .2307 .2346 .2384 .2423 .2462 .2502 .2542 .2582 .2623 .2664 .2705 .2747 .2789 .2831 .2874 .2918 .2961 .3005 .305 .3095 .314 .3185 .3231 .3278 .3325 .3372 .3419 .3467 .3515 .3564 .3613 .3663 .3712 .3763 .3813 .3864 .3916 .3968 .402 .4072 .4125 .4179 .4233 .4287 .4342 .4397 .4452 .4508 .4564 .4621 .4678 .4735 .4793 .4851 .491 .4969 .5029 .5089 .5149 .521 .5271 .5333 .5395 .5457 .552 .5583 .5647 .5711 .5776 .5841 .5906 .5972 .6038 .6105 .6172 .624 .6308 .6376 .6445 .6514 .6584 .6654 .6724 .6795 .6867 .6939 .7011 .7084 .7157 .7231 .7305 .7379 .7454 .7529 .7605 .7682 .7758 .7835 .7913 .7991 .807 .8148 .8228 .8308 .8388 .8469 .855 .8632 .8714 .8796 .8879 .8963 .9047 .9131 .9216 .9301 .9387 .9473 .956 .9647 .9734 .9823 .9911 1; @@ -123,7 +174,7 @@ $_luminance-list: .0008 .001 .0011 .0013 .0015 .0017 .002 .0022 .0025 .0027 .003 $l1: luminance($background); $l2: luminance(opaque($background, $foreground)); - @return if($l1 > $l2, ($l1 + .05) / ($l2 + .05), ($l2 + .05) / ($l1 + .05)); + @return if($l1 > $l2, divide($l1 + .05, $l2 + .05), divide($l2 + .05, $l1 + .05)); } // Return WCAG2.0 relative luminance @@ -137,7 +188,7 @@ $_luminance-list: .0008 .001 .0011 .0013 .0015 .0017 .002 .0022 .0025 .0027 .003 ); @each $name, $value in $rgb { - $value: if($value / 255 < .03928, $value / 255 / 12.92, nth($_luminance-list, $value + 1)); + $value: if(divide($value, 255) < .03928, divide(divide($value, 255), 12.92), nth($_luminance-list, $value + 1)); $rgb: map-merge($rgb, ($name: $value)); } @@ -201,5 +252,51 @@ $_luminance-list: .0008 .001 .0011 .0013 .0015 .0017 .002 .0022 .0025 .0027 .003 @return $value1 - $value2; } + @if type-of($value2) != number { + $value2: unquote("(") + $value2 + unquote(")"); + } + @return if($return-calc == true, calc(#{$value1} - #{$value2}), $value1 + unquote(" - ") + $value2); } + +@function divide($dividend, $divisor, $precision: 10) { + $sign: if($dividend > 0 and $divisor > 0 or $dividend < 0 and $divisor < 0, 1, -1); + $dividend: abs($dividend); + $divisor: abs($divisor); + @if $dividend == 0 { + @return 0; + } + @if $divisor == 0 { + @error "Cannot divide by 0"; + } + $remainder: $dividend; + $result: 0; + $factor: 10; + @while ($remainder > 0 and $precision >= 0) { + $quotient: 0; + @while ($remainder >= $divisor) { + $remainder: $remainder - $divisor; + $quotient: $quotient + 1; + } + $result: $result * 10 + $quotient; + $factor: $factor * .1; + $remainder: $remainder * 10; + $precision: $precision - 1; + @if ($precision < 0 and $remainder >= $divisor * 5) { + $result: $result + 1; + } + } + $result: $result * $factor * $sign; + $dividend-unit: unit($dividend); + $divisor-unit: unit($divisor); + $unit-map: ( + "px": 1px, + "rem": 1rem, + "em": 1em, + "%": 1% + ); + @if ($dividend-unit != $divisor-unit and map-has-key($unit-map, $dividend-unit)) { + $result: $result * map-get($unit-map, $dividend-unit); + } + @return $result; +} diff --git a/scss/_grid.scss b/scss/_grid.scss index 5686f31fe..27fd55847 100644 --- a/scss/_grid.scss +++ b/scss/_grid.scss @@ -12,6 +12,17 @@ } } +@if $enable-cssgrid { + .grid { + display: grid; + grid-template-rows: repeat(var(--#{$variable-prefix}rows, 1), 1fr); + grid-template-columns: repeat(var(--#{$variable-prefix}columns, #{$grid-columns}), 1fr); + gap: var(--#{$variable-prefix}gap, #{$grid-gutter-width}); + + @include make-cssgrid(); + } +} + // Columns // diff --git a/scss/_helpers.scss b/scss/_helpers.scss index 8f566d12f..4a989f5a5 100644 --- a/scss/_helpers.scss +++ b/scss/_helpers.scss @@ -2,6 +2,8 @@ @import "helpers/colored-links"; @import "helpers/ratio"; @import "helpers/position"; +@import "helpers/stacks"; @import "helpers/visually-hidden"; @import "helpers/stretched-link"; @import "helpers/text-truncation"; +@import "helpers/vr"; diff --git a/scss/_images.scss b/scss/_images.scss index b11b45a37..3d6a1014c 100644 --- a/scss/_images.scss +++ b/scss/_images.scss @@ -32,7 +32,7 @@ } .figure-img { - margin-bottom: $spacer / 2; + margin-bottom: $spacer * .5; line-height: 1; } diff --git a/scss/_list-group.scss b/scss/_list-group.scss index 7e23b8e0c..dcd61d2b5 100644 --- a/scss/_list-group.scss +++ b/scss/_list-group.scss @@ -12,6 +12,17 @@ @include border-radius($list-group-border-radius); } +.list-group-numbered { + list-style-type: none; + counter-reset: section; + + > li::before { + // Increments only this instance of the section counter + content: counters(section, ".") ". "; + counter-increment: section; + } +} + // Interactive list items // @@ -152,12 +163,12 @@ // Organizationally, this must come after the `:hover` states. @each $state, $value in $theme-colors { - $list-group-background: shift-color($value, $list-group-item-bg-scale); - $list-group-color: shift-color($value, $list-group-item-color-scale); - @if (contrast-ratio($list-group-background, $list-group-color) < $min-contrast-ratio) { - $list-group-color: mix($value, color-contrast($list-group-background), abs($alert-color-scale)); + $list-group-variant-bg: shift-color($value, $list-group-item-bg-scale); + $list-group-variant-color: shift-color($value, $list-group-item-color-scale); + @if (contrast-ratio($list-group-variant-bg, $list-group-variant-color) < $min-contrast-ratio) { + $list-group-variant-color: mix($value, color-contrast($list-group-variant-bg), abs($list-group-item-color-scale)); } - @include list-group-item-variant($state, $list-group-background, $list-group-color); + @include list-group-item-variant($state, $list-group-variant-bg, $list-group-variant-color); } // scss-docs-end list-group-modifiers diff --git a/scss/_mixins.scss b/scss/_mixins.scss index 7b06cd819..af1f74f72 100644 --- a/scss/_mixins.scss +++ b/scss/_mixins.scss @@ -10,6 +10,7 @@ // Helpers @import "mixins/breakpoints"; +@import "mixins/color-scheme"; @import "mixins/image"; @import "mixins/resize"; @import "mixins/visually-hidden"; @@ -21,6 +22,7 @@ // Components @import "mixins/alert"; +@import "mixins/backdrop"; @import "mixins/buttons"; @import "mixins/caret"; @import "mixins/pagination"; diff --git a/scss/_modal.scss b/scss/_modal.scss index 6dd4dd329..21e1258f5 100644 --- a/scss/_modal.scss +++ b/scss/_modal.scss @@ -4,16 +4,6 @@ // .modal-content - actual modal w/ bg and corners and stuff -.modal-open { - // Kill the scroll on the body - overflow: hidden; - - .modal { - overflow-x: hidden; - overflow-y: auto; - } -} - // Container that the modal scrolls within .modal { position: fixed; @@ -23,7 +13,8 @@ display: none; width: 100%; height: 100%; - overflow: hidden; + 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; @@ -94,17 +85,7 @@ // Modal background .modal-backdrop { - position: fixed; - top: 0; - left: 0; - z-index: $zindex-modal-backdrop; - width: 100vw; - height: 100vh; - background-color: $modal-backdrop-bg; - - // Fade for backdrop - &.fade { opacity: 0; } - &.show { opacity: $modal-backdrop-opacity; } + @include overlay-backdrop($zindex-modal-backdrop, $modal-backdrop-bg, $modal-backdrop-opacity); } // Modal header @@ -119,8 +100,8 @@ @include border-top-radius($modal-content-inner-border-radius); .btn-close { - padding: ($modal-header-padding-y / 2) ($modal-header-padding-x / 2); - margin: ($modal-header-padding-y / -2) ($modal-header-padding-x / -2) ($modal-header-padding-y / -2) auto; + padding: ($modal-header-padding-y * .5) ($modal-header-padding-x * .5); + margin: ($modal-header-padding-y * -.5) ($modal-header-padding-x * -.5) ($modal-header-padding-y * -.5) auto; } } @@ -147,7 +128,7 @@ flex-shrink: 0; 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: $modal-inner-padding - $modal-footer-margin-between / 2; + padding: $modal-inner-padding - $modal-footer-margin-between * .5; border-top: $modal-footer-border-width solid $modal-footer-border-color; @include border-bottom-radius($modal-content-inner-border-radius); @@ -155,19 +136,10 @@ // 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: $modal-footer-margin-between / 2; + margin: $modal-footer-margin-between * .5; } } -// Measure scrollbar width for padding body during modal show/hide -.modal-scrollbar-measure { - position: absolute; - top: -9999px; - width: 50px; - height: 50px; - overflow: scroll; -} - // Scale up the modal @include media-breakpoint-up(sm) { // Automatically set modal's width for larger viewports diff --git a/scss/_nav.scss b/scss/_nav.scss index 3d3117af1..9b7760334 100644 --- a/scss/_nav.scss +++ b/scss/_nav.scss @@ -122,6 +122,13 @@ } } +.nav-fill, +.nav-justified { + .nav-item .nav-link { + width: 100%; // Make sure button will grow + } +} + // Tabbable tabs // diff --git a/scss/_navbar.scss b/scss/_navbar.scss index 2ccef11b7..001dfc988 100644 --- a/scss/_navbar.scss +++ b/scss/_navbar.scss @@ -193,13 +193,42 @@ .navbar-toggler { display: none; } + + .offcanvas-header { + display: none; + } + + .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; // stylelint-disable-line declaration-no-important + background-color: transparent; + border-right: 0; + border-left: 0; + @include transition(none); + transform: none; + } + .offcanvas-top, + .offcanvas-bottom { + height: auto; + border-top: 0; + border-bottom: 0; + } + + .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } } } } } // scss-docs-end navbar-expand-loop - // Navbar themes // // Styles for switching between navbars with light or dark background. diff --git a/scss/_offcanvas.scss b/scss/_offcanvas.scss new file mode 100644 index 000000000..a089c2a08 --- /dev/null +++ b/scss/_offcanvas.scss @@ -0,0 +1,83 @@ +.offcanvas { + position: fixed; + bottom: 0; + z-index: $zindex-offcanvas; + display: flex; + flex-direction: column; + max-width: 100%; + color: $offcanvas-color; + visibility: hidden; + background-color: $offcanvas-bg-color; + background-clip: padding-box; + outline: 0; + @include box-shadow($offcanvas-box-shadow); + @include transition(transform $offcanvas-transition-duration ease-in-out); +} + +.offcanvas-backdrop { + @include overlay-backdrop($zindex-offcanvas-backdrop, $offcanvas-backdrop-bg, $offcanvas-backdrop-opacity); +} + +.offcanvas-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: $offcanvas-padding-y $offcanvas-padding-x; + + .btn-close { + padding: ($offcanvas-padding-y * .5) ($offcanvas-padding-x * .5); + margin-top: $offcanvas-padding-y * -.5; + margin-right: $offcanvas-padding-x * -.5; + margin-bottom: $offcanvas-padding-y * -.5; + } +} + +.offcanvas-title { + margin-bottom: 0; + line-height: $offcanvas-title-line-height; +} + +.offcanvas-body { + flex-grow: 1; + padding: $offcanvas-padding-y $offcanvas-padding-x; + overflow-y: auto; +} + +.offcanvas-start { + top: 0; + left: 0; + width: $offcanvas-horizontal-width; + border-right: $offcanvas-border-width solid $offcanvas-border-color; + transform: translateX(-100%); +} + +.offcanvas-end { + top: 0; + right: 0; + width: $offcanvas-horizontal-width; + border-left: $offcanvas-border-width solid $offcanvas-border-color; + transform: translateX(100%); +} + +.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: $offcanvas-vertical-height; + max-height: 100%; + border-bottom: $offcanvas-border-width solid $offcanvas-border-color; + transform: translateY(-100%); +} + +.offcanvas-bottom { + right: 0; + left: 0; + height: $offcanvas-vertical-height; + max-height: 100%; + border-top: $offcanvas-border-width solid $offcanvas-border-color; + transform: translateY(100%); +} + +.offcanvas.show { + transform: none; +} diff --git a/scss/_placeholders.scss b/scss/_placeholders.scss new file mode 100644 index 000000000..2f647cc9b --- /dev/null +++ b/scss/_placeholders.scss @@ -0,0 +1,51 @@ +.placeholder { + 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 { + 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%; + } +} diff --git a/scss/_popover.scss b/scss/_popover.scss index a55555e2e..3b8208e16 100644 --- a/scss/_popover.scss +++ b/scss/_popover.scss @@ -40,13 +40,13 @@ &::before { bottom: 0; - border-width: $popover-arrow-height ($popover-arrow-width / 2) 0; + border-width: $popover-arrow-height ($popover-arrow-width * .5) 0; border-top-color: $popover-arrow-outer-color; } &::after { bottom: $popover-border-width; - border-width: $popover-arrow-height ($popover-arrow-width / 2) 0; + border-width: $popover-arrow-height ($popover-arrow-width * .5) 0; border-top-color: $popover-arrow-color; } } @@ -60,13 +60,13 @@ &::before { left: 0; - border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0; + border-width: ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5) 0; border-right-color: $popover-arrow-outer-color; } &::after { left: $popover-border-width; - border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0; + border-width: ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5) 0; border-right-color: $popover-arrow-color; } } @@ -78,13 +78,13 @@ &::before { top: 0; - border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2); + border-width: 0 ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5); border-bottom-color: $popover-arrow-outer-color; } &::after { top: $popover-border-width; - border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2); + border-width: 0 ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5); border-bottom-color: $popover-arrow-color; } } @@ -96,7 +96,7 @@ left: 50%; display: block; width: $popover-arrow-width; - margin-left: -$popover-arrow-width / 2; + margin-left: -$popover-arrow-width * .5; content: ""; border-bottom: $popover-border-width solid $popover-header-bg; } @@ -110,13 +110,13 @@ &::before { right: 0; - border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height; + border-width: ($popover-arrow-width * .5) 0 ($popover-arrow-width * .5) $popover-arrow-height; border-left-color: $popover-arrow-outer-color; } &::after { right: $popover-border-width; - border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height; + border-width: ($popover-arrow-width * .5) 0 ($popover-arrow-width * .5) $popover-arrow-height; border-left-color: $popover-arrow-color; } } @@ -144,7 +144,7 @@ @include font-size($font-size-base); color: $popover-header-color; background-color: $popover-header-bg; - border-bottom: $popover-border-width solid shade-color($popover-header-bg, 10%); + border-bottom: $popover-border-width solid $popover-border-color; @include border-top-radius($popover-inner-border-radius); &:empty { diff --git a/scss/_reboot.scss b/scss/_reboot.scss index 7b153d1a8..79fedc6ca 100644 --- a/scss/_reboot.scss +++ b/scss/_reboot.scss @@ -26,7 +26,9 @@ // null by default, thus nothing is generated. :root { - font-size: $font-size-root; + @if $font-size-root != null { + font-size: var(--#{$variable-prefix}root-font-size); + } @if $enable-smooth-scroll { @media (prefers-reduced-motion: no-preference) { @@ -43,18 +45,20 @@ // 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: $font-family-base; - @include font-size($font-size-base); - font-weight: $font-weight-base; - line-height: $line-height-base; - color: $body-color; - text-align: $body-text-align; - background-color: $body-bg; // 2 + font-family: var(--#{$variable-prefix}body-font-family); + @include font-size(var(--#{$variable-prefix}body-font-size)); + font-weight: var(--#{$variable-prefix}body-font-weight); + line-height: var(--#{$variable-prefix}body-line-height); + color: var(--#{$variable-prefix}body-color); + text-align: var(--#{$variable-prefix}body-text-align); + background-color: var(--#{$variable-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 @@ -142,7 +146,6 @@ p { abbr[title], abbr[data-bs-original-title] { // 1 - text-decoration: underline; // 2 text-decoration: underline dotted; // 2 cursor: help; // 3 text-decoration-skip-ink: none; // 4 @@ -420,12 +423,10 @@ textarea { } // 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 @@ -433,11 +434,15 @@ select { cursor: pointer; } -// Remove the inheritance of word-wrap in Safari. -// See https://github.com/twbs/bootstrap/issues/24990 - 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 in Chrome from inputs built with datalists. @@ -568,7 +573,6 @@ legend { // Inherit font family and line height for file input buttons -// stylelint-disable-next-line selector-pseudo-element-no-unknown ::file-selector-button { font: inherit; } diff --git a/scss/_root.scss b/scss/_root.scss index 768d6343f..5e138e97b 100644 --- a/scss/_root.scss +++ b/scss/_root.scss @@ -1,16 +1,54 @@ :root { - // Custom variable values only support SassScript inside `#{}`. + // Note: Custom variable values only support SassScript inside `#{}`. + + // Colors + // + // Generate palettes for full colors, grays, and theme colors. + @each $color, $value in $colors { --#{$variable-prefix}#{$color}: #{$value}; } + @each $color, $value in $grays { + --#{$variable-prefix}gray-#{$color}: #{$value}; + } + @each $color, $value in $theme-colors { --#{$variable-prefix}#{$color}: #{$value}; } - // Use `inspect` for lists so that quoted items keep the quotes. + @each $color, $value in $theme-colors-rgb { + --#{$variable-prefix}#{$color}-rgb: #{$value}; + } + + --#{$variable-prefix}white-rgb: #{to-rgb($white)}; + --#{$variable-prefix}black-rgb: #{to-rgb($black)}; + --#{$variable-prefix}body-color-rgb: #{to-rgb($body-color)}; + --#{$variable-prefix}body-bg-rgb: #{to-rgb($body-bg)}; + + // Fonts + + // Note: Use `inspect` for lists so that quoted items keep the quotes. // See https://github.com/sass/sass/issues/2383#issuecomment-336349172 --#{$variable-prefix}font-sans-serif: #{inspect($font-family-sans-serif)}; --#{$variable-prefix}font-monospace: #{inspect($font-family-monospace)}; --#{$variable-prefix}gradient: #{$gradient}; + + // Root and body + // stylelint-disable custom-property-empty-line-before + // scss-docs-start root-body-variables + @if $font-size-root != null { + --#{$variable-prefix}root-font-size: #{$font-size-root}; + } + --#{$variable-prefix}body-font-family: #{$font-family-base}; + --#{$variable-prefix}body-font-size: #{$font-size-base}; + --#{$variable-prefix}body-font-weight: #{$font-weight-base}; + --#{$variable-prefix}body-line-height: #{$line-height-base}; + --#{$variable-prefix}body-color: #{$body-color}; + @if $body-text-align != null { + --#{$variable-prefix}body-text-align: #{$body-text-align}; + } + --#{$variable-prefix}body-bg: #{$body-bg}; + // scss-docs-end root-body-variables + // stylelint-enable custom-property-empty-line-before } diff --git a/scss/_spinners.scss b/scss/_spinners.scss index 8e19bae51..a4a2c77cf 100644 --- a/scss/_spinners.scss +++ b/scss/_spinners.scss @@ -12,7 +12,7 @@ display: inline-block; width: $spinner-width; height: $spinner-height; - vertical-align: text-bottom; + vertical-align: $spinner-vertical-align; border: $spinner-border-width solid currentColor; border-right-color: transparent; // stylelint-disable-next-line property-disallowed-list @@ -46,7 +46,7 @@ display: inline-block; width: $spinner-width; height: $spinner-height; - vertical-align: text-bottom; + vertical-align: $spinner-vertical-align; background-color: currentColor; // stylelint-disable-next-line property-disallowed-list border-radius: 50%; diff --git a/scss/_tables.scss b/scss/_tables.scss index 50368293a..92556ba05 100644 --- a/scss/_tables.scss +++ b/scss/_tables.scss @@ -4,6 +4,7 @@ .table { --#{$variable-prefix}table-bg: #{$table-bg}; + --#{$variable-prefix}table-accent-bg: #{$table-accent-bg}; --#{$variable-prefix}table-striped-color: #{$table-striped-color}; --#{$variable-prefix}table-striped-bg: #{$table-striped-bg}; --#{$variable-prefix}table-active-color: #{$table-active-color}; diff --git a/scss/_toasts.scss b/scss/_toasts.scss index 5c533d7f5..0a2d6ec87 100644 --- a/scss/_toasts.scss +++ b/scss/_toasts.scss @@ -10,11 +10,11 @@ box-shadow: $toast-box-shadow; @include border-radius($toast-border-radius); - &:not(.showing):not(.show) { + &.showing { opacity: 0; } - &.hide { + &:not(.show) { display: none; } } @@ -40,7 +40,7 @@ @include border-top-radius(subtract($toast-border-radius, $toast-border-width)); .btn-close { - margin-right: $toast-padding-x / -2; + margin-right: $toast-padding-x * -.5; margin-left: $toast-padding-x; } } diff --git a/scss/_tooltip.scss b/scss/_tooltip.scss index 2993bf7de..75ff07838 100644 --- a/scss/_tooltip.scss +++ b/scss/_tooltip.scss @@ -37,7 +37,7 @@ &::before { top: -1px; - border-width: $tooltip-arrow-height ($tooltip-arrow-width / 2) 0; + border-width: $tooltip-arrow-height ($tooltip-arrow-width * .5) 0; border-top-color: $tooltip-arrow-color; } } @@ -53,7 +53,7 @@ &::before { right: -1px; - border-width: ($tooltip-arrow-width / 2) $tooltip-arrow-height ($tooltip-arrow-width / 2) 0; + border-width: ($tooltip-arrow-width * .5) $tooltip-arrow-height ($tooltip-arrow-width * .5) 0; border-right-color: $tooltip-arrow-color; } } @@ -67,7 +67,7 @@ &::before { bottom: -1px; - border-width: 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height; + border-width: 0 ($tooltip-arrow-width * .5) $tooltip-arrow-height; border-bottom-color: $tooltip-arrow-color; } } @@ -83,7 +83,7 @@ &::before { left: -1px; - border-width: ($tooltip-arrow-width / 2) 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height; + border-width: ($tooltip-arrow-width * .5) 0 ($tooltip-arrow-width * .5) $tooltip-arrow-height; border-left-color: $tooltip-arrow-color; } } diff --git a/scss/_transitions.scss b/scss/_transitions.scss index 2905df45c..bfb26aa8a 100644 --- a/scss/_transitions.scss +++ b/scss/_transitions.scss @@ -17,5 +17,11 @@ height: 0; overflow: hidden; @include transition($transition-collapse); + + &.collapse-horizontal { + width: 0; + height: auto; + @include transition($transition-collapse-width); + } } // scss-docs-end collapse-classes diff --git a/scss/_utilities.scss b/scss/_utilities.scss index 3c927cf59..960d6f1ad 100644 --- a/scss/_utilities.scss +++ b/scss/_utilities.scss @@ -24,6 +24,19 @@ $utilities: map-merge( ) ), // scss-docs-end utils-float + // Opacity utilities + // scss-docs-start utils-opacity + "opacity": ( + property: opacity, + values: ( + 0: 0, + 25: .25, + 50: .5, + 75: .75, + 100: 1, + ) + ), + // scss-docs-end utils-opacity // scss-docs-start utils-overflow "overflow": ( property: overflow, @@ -501,32 +514,55 @@ $utilities: map-merge( "color": ( property: color, class: text, + local-vars: ( + "text-opacity": 1 + ), values: map-merge( - $theme-colors, + $utilities-text-colors, ( - "white": $white, - "body": $body-color, "muted": $text-muted, - "black-50": rgba($black, .5), - "white-50": rgba($white, .5), + "black-50": rgba($black, .5), // deprecated + "white-50": rgba($white, .5), // deprecated "reset": inherit, ) ) ), + "text-opacity": ( + css-var: true, + class: text-opacity, + values: ( + 25: .25, + 50: .5, + 75: .75, + 100: 1 + ) + ), // scss-docs-end utils-color // scss-docs-start utils-bg-color "background-color": ( property: background-color, class: bg, + local-vars: ( + "bg-opacity": 1 + ), values: map-merge( - $theme-colors, + $utilities-bg-colors, ( - "body": $body-bg, - "white": $white, "transparent": transparent ) ) ), + "bg-opacity": ( + css-var: true, + class: bg-opacity, + values: ( + 10: .1, + 25: .25, + 50: .5, + 75: .75, + 100: 1 + ) + ), // scss-docs-end utils-bg-color "gradient": ( property: background-image, diff --git a/scss/_variables.scss b/scss/_variables.scss index 7f4dca3c7..dbaa294a3 100644 --- a/scss/_variables.scss +++ b/scss/_variables.scss @@ -90,6 +90,10 @@ $theme-colors: ( ) !default; // scss-docs-end theme-colors-map +// scss-docs-start theme-colors-rgb +$theme-colors-rgb: map-loop($theme-colors, to-rgb, "$value") !default; +// scss-docs-end theme-colors-rgb + // The contrast ratio to reach against white, to determine if color changes from "light" to "dark". Acceptable values for WCAG 2.0 are 3, 4.5 and 7. // See https://www.w3.org/TR/WCAG20/#visual-audio-contrast-contrast $min-contrast-ratio: 4.5 !default; @@ -198,6 +202,126 @@ $cyan-600: shade-color($cyan, 20%) !default; $cyan-700: shade-color($cyan, 40%) !default; $cyan-800: shade-color($cyan, 60%) !default; $cyan-900: shade-color($cyan, 80%) !default; + +$blues: ( + "blue-100": $blue-100, + "blue-200": $blue-200, + "blue-300": $blue-300, + "blue-400": $blue-400, + "blue-500": $blue-500, + "blue-600": $blue-600, + "blue-700": $blue-700, + "blue-800": $blue-800, + "blue-900": $blue-900 +) !default; + +$indigos: ( + "indigo-100": $indigo-100, + "indigo-200": $indigo-200, + "indigo-300": $indigo-300, + "indigo-400": $indigo-400, + "indigo-500": $indigo-500, + "indigo-600": $indigo-600, + "indigo-700": $indigo-700, + "indigo-800": $indigo-800, + "indigo-900": $indigo-900 +) !default; + +$purples: ( + "purple-100": $purple-200, + "purple-200": $purple-100, + "purple-300": $purple-300, + "purple-400": $purple-400, + "purple-500": $purple-500, + "purple-600": $purple-600, + "purple-700": $purple-700, + "purple-800": $purple-800, + "purple-900": $purple-900 +) !default; + +$pinks: ( + "pink-100": $pink-100, + "pink-200": $pink-200, + "pink-300": $pink-300, + "pink-400": $pink-400, + "pink-500": $pink-500, + "pink-600": $pink-600, + "pink-700": $pink-700, + "pink-800": $pink-800, + "pink-900": $pink-900 +) !default; + +$reds: ( + "red-100": $red-100, + "red-200": $red-200, + "red-300": $red-300, + "red-400": $red-400, + "red-500": $red-500, + "red-600": $red-600, + "red-700": $red-700, + "red-800": $red-800, + "red-900": $red-900 +) !default; + +$oranges: ( + "orange-100": $orange-100, + "orange-200": $orange-200, + "orange-300": $orange-300, + "orange-400": $orange-400, + "orange-500": $orange-500, + "orange-600": $orange-600, + "orange-700": $orange-700, + "orange-800": $orange-800, + "orange-900": $orange-900 +) !default; + +$yellows: ( + "yellow-100": $yellow-100, + "yellow-200": $yellow-200, + "yellow-300": $yellow-300, + "yellow-400": $yellow-400, + "yellow-500": $yellow-500, + "yellow-600": $yellow-600, + "yellow-700": $yellow-700, + "yellow-800": $yellow-800, + "yellow-900": $yellow-900 +) !default; + +$greens: ( + "green-100": $green-100, + "green-200": $green-200, + "green-300": $green-300, + "green-400": $green-400, + "green-500": $green-500, + "green-600": $green-600, + "green-700": $green-700, + "green-800": $green-800, + "green-900": $green-900 +) !default; + +$teals: ( + "teal-100": $teal-100, + "teal-200": $teal-200, + "teal-300": $teal-300, + "teal-400": $teal-400, + "teal-500": $teal-500, + "teal-600": $teal-600, + "teal-700": $teal-700, + "teal-800": $teal-800, + "teal-900": $teal-900 +) !default; + +$cyans: ( + "cyan-100": $cyan-100, + "cyan-200": $cyan-200, + "cyan-300": $cyan-300, + "cyan-400": $cyan-400, + "cyan-500": $cyan-500, + "cyan-600": $cyan-600, + "cyan-700": $cyan-700, + "cyan-800": $cyan-800, + "cyan-900": $cyan-900 +) !default; // fusv-enable // Characters which are escaped by the escape-svg function @@ -221,6 +345,7 @@ $enable-transitions: true !default; $enable-reduced-motion: true !default; $enable-smooth-scroll: true !default; $enable-grid-classes: true !default; +$enable-cssgrid: false !default; $enable-button-pointers: true !default; $enable-rfs: true !default; $enable-validation-icons: true !default; @@ -250,8 +375,8 @@ $gradient: linear-gradient(180deg, rgba($white, .15), rgba($white, 0)) !default; $spacer: 1rem !default; $spacers: ( 0: 0, - 1: $spacer / 4, - 2: $spacer / 2, + 1: $spacer * .25, + 2: $spacer * .5, 3: $spacer, 4: $spacer * 1.5, 5: $spacer * 3, @@ -280,6 +405,38 @@ $body-bg: $white !default; $body-color: $gray-900 !default; $body-text-align: null !default; +// Utilities maps +// +// Extends the default `$theme-colors` maps to help create our utilities. + +// Come v6, we'll de-dupe these variables. Until then, for backward compatibility, we keep them to reassign. +// scss-docs-start utilities-colors +$utilities-colors: $theme-colors-rgb !default; +// scss-docs-end utilities-colors + +// scss-docs-start utilities-text-colors +$utilities-text: map-merge( + $utilities-colors, + ( + "black": to-rgb($black), + "white": to-rgb($white), + "body": to-rgb($body-color) + ) +) !default; +$utilities-text-colors: map-loop($utilities-text, rgba-css-var, "$key", "text") !default; +// scss-docs-end utilities-text-colors + +// scss-docs-start utilities-bg-colors +$utilities-bg: map-merge( + $utilities-colors, + ( + "black": to-rgb($black), + "white": to-rgb($white), + "body": to-rgb($body-bg) + ) +) !default; +$utilities-bg-colors: map-loop($utilities-bg, rgba-css-var, "$key", "bg") !default; +// scss-docs-end utilities-bg-colors // Links // @@ -350,7 +507,7 @@ $gutters: $spacers !default; // Container padding -$container-padding-x: $grid-gutter-width / 2 !default; +$container-padding-x: $grid-gutter-width * .5 !default; // Components @@ -405,6 +562,7 @@ $transition-base: all .2s ease-in-out !default; $transition-fade: opacity .15s linear !default; // scss-docs-start collapse-transition $transition-collapse: height .35s ease !default; +$transition-collapse-width: width .35s ease !default; // scss-docs-end collapse-transition // stylelint-disable function-disallowed-list @@ -430,8 +588,8 @@ $font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberati $font-family-base: var(--#{$variable-prefix}font-sans-serif) !default; $font-family-code: var(--#{$variable-prefix}font-monospace) !default; -// $font-size-root effects the value of `rem`, which is used for as well font sizes, paddings and margins -// $font-size-base effects the font size of the body text +// $font-size-root affects the value of `rem`, which is used for as well font sizes, paddings, and margins +// $font-size-base affects the font size of the body text $font-size-root: null !default; $font-size-base: 1rem !default; // Assumes the browser default, typically `16px` $font-size-sm: $font-size-base * .875 !default; @@ -469,7 +627,7 @@ $font-sizes: ( // scss-docs-end font-sizes // scss-docs-start headings-variables -$headings-margin-bottom: $spacer / 2 !default; +$headings-margin-bottom: $spacer * .5 !default; $headings-font-family: null !default; $headings-font-style: null !default; $headings-font-weight: 500 !default; @@ -543,6 +701,7 @@ $table-cell-vertical-align: top !default; $table-color: $body-color !default; $table-bg: transparent !default; +$table-accent-bg: transparent !default; $table-th-font-weight: null !default; @@ -699,7 +858,7 @@ $input-padding-y-lg: $input-btn-padding-y-lg !default; $input-padding-x-lg: $input-btn-padding-x-lg !default; $input-font-size-lg: $input-btn-font-size-lg !default; -$input-bg: $white !default; +$input-bg: $body-bg !default; $input-disabled-bg: $gray-200 !default; $input-disabled-border-color: null !default; @@ -725,13 +884,15 @@ $input-height-border: $input-border-width * 2 !default; $input-height-inner: add($input-line-height * 1em, $input-padding-y * 2) !default; $input-height-inner-half: add($input-line-height * .5em, $input-padding-y) !default; -$input-height-inner-quarter: add($input-line-height * .25em, $input-padding-y / 2) !default; +$input-height-inner-quarter: add($input-line-height * .25em, $input-padding-y * .5) !default; $input-height: add($input-line-height * 1em, add($input-padding-y * 2, $input-height-border, false)) !default; $input-height-sm: add($input-line-height * 1em, add($input-padding-y-sm * 2, $input-height-border, false)) !default; $input-height-lg: add($input-line-height * 1em, add($input-padding-y-lg * 2, $input-height-border, false)) !default; $input-transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out !default; + +$form-color-width: 3rem !default; // scss-docs-end form-input-variables // scss-docs-start form-check-variables @@ -746,7 +907,7 @@ $form-check-transition: null !default; $form-check-input-active-filter: brightness(90%) !default; $form-check-input-bg: $input-bg !default; -$form-check-input-border: 1px solid rgba(0, 0, 0, .25) !default; +$form-check-input-border: 1px solid rgba($black, .25) !default; $form-check-input-border-radius: .25em !default; $form-check-radio-border-radius: 50% !default; $form-check-input-focus-border: $input-focus-border-color !default; @@ -804,8 +965,8 @@ $form-select-indicator-padding: $form-select-padding-x * 3 !default; // Extr $form-select-font-weight: $input-font-weight !default; $form-select-line-height: $input-line-height !default; $form-select-color: $input-color !default; -$form-select-disabled-color: $gray-600 !default; $form-select-bg: $input-bg !default; +$form-select-disabled-color: null !default; $form-select-disabled-bg: $gray-200 !default; $form-select-disabled-border-color: $input-disabled-border-color !default; $form-select-bg-position: right $form-select-padding-x center !default; @@ -833,6 +994,8 @@ $form-select-font-size-sm: $input-font-size-sm !default; $form-select-padding-y-lg: $input-padding-y-lg !default; $form-select-padding-x-lg: $input-padding-x-lg !default; $form-select-font-size-lg: $input-font-size-lg !default; + +$form-select-transition: $input-transition !default; // scss-docs-end form-select-variables // scss-docs-start form-range-variables @@ -864,6 +1027,7 @@ $form-file-button-hover-bg: shade-color($form-file-button-bg, 5%) !default // scss-docs-start form-floating-variables $form-floating-height: add(3.5rem, $input-height-border) !default; +$form-floating-line-height: 1.25 !default; $form-floating-padding-x: $input-padding-x !default; $form-floating-padding-y: 1rem !default; $form-floating-input-padding-t: 1.625rem !default; @@ -910,10 +1074,12 @@ $form-validation-states: ( $zindex-dropdown: 1000 !default; $zindex-sticky: 1020 !default; $zindex-fixed: 1030 !default; -$zindex-modal-backdrop: 1040 !default; -$zindex-modal: 1050 !default; -$zindex-popover: 1060 !default; -$zindex-tooltip: 1070 !default; +$zindex-offcanvas-backdrop: 1040 !default; +$zindex-offcanvas: 1045 !default; +$zindex-modal-backdrop: 1050 !default; +$zindex-modal: 1055 !default; +$zindex-popover: 1070 !default; +$zindex-tooltip: 1080 !default; // scss-docs-end zindex-stack @@ -924,8 +1090,8 @@ $nav-link-padding-y: .5rem !default; $nav-link-padding-x: 1rem !default; $nav-link-font-size: null !default; $nav-link-font-weight: null !default; -$nav-link-color: null !default; -$nav-link-hover-color: null !default; +$nav-link-color: $link-color !default; +$nav-link-hover-color: $link-hover-color !default; $nav-link-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out !default; $nav-link-disabled-color: $gray-600 !default; $nav-link-focus-box-shadow: $focus-ring-box-shadow !default; @@ -947,7 +1113,7 @@ $nav-pills-link-active-bg: $component-active-bg !default; // Navbar // scss-docs-start navbar-variables -$navbar-padding-y: $spacer / 2 !default; +$navbar-padding-y: $spacer * .5 !default; $navbar-padding-x: null !default; $navbar-nav-link-padding-x: .5rem !default; @@ -956,7 +1122,7 @@ $navbar-brand-font-size: $font-size-lg !default; // Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link $nav-link-height: $font-size-base * $line-height-base + $nav-link-padding-y * 2 !default; $navbar-brand-height: $navbar-brand-font-size * $line-height-base !default; -$navbar-brand-padding-y: ($nav-link-height - $navbar-brand-height) / 2 !default; +$navbar-brand-padding-y: ($nav-link-height - $navbar-brand-height) * .5 !default; $navbar-brand-margin-end: 1rem !default; $navbar-toggler-padding-y: .25rem !default; @@ -1006,7 +1172,7 @@ $dropdown-border-radius: $border-radius !default; $dropdown-border-width: $border-width !default; $dropdown-inner-border-radius: subtract($dropdown-border-radius, $dropdown-border-width) !default; $dropdown-divider-bg: $dropdown-border-color !default; -$dropdown-divider-margin-y: $spacer / 2 !default; +$dropdown-divider-margin-y: $spacer * .5 !default; $dropdown-box-shadow: $box-shadow !default; $dropdown-link-color: $gray-900 !default; @@ -1018,7 +1184,7 @@ $dropdown-link-active-bg: $component-active-bg !default; $dropdown-link-disabled-color: $gray-500 !default; -$dropdown-item-padding-y: $spacer / 4 !default; +$dropdown-item-padding-y: $spacer * .25 !default; $dropdown-item-padding-x: $spacer !default; $dropdown-header-color: $gray-600 !default; @@ -1082,17 +1248,25 @@ $pagination-border-radius-lg: $border-radius-lg !default; // scss-docs-end pagination-variables +// Placeholders + +// scss-docs-start placeholders +$placeholder-opacity-max: .5 !default; +$placeholder-opacity-min: .2 !default; +// scss-docs-end placeholders + // Cards // scss-docs-start card-variables $card-spacer-y: $spacer !default; $card-spacer-x: $spacer !default; -$card-title-spacer-y: $spacer / 2 !default; +$card-title-spacer-y: $spacer * .5 !default; $card-border-width: $border-width !default; -$card-border-radius: $border-radius !default; $card-border-color: rgba($black, .125) !default; +$card-border-radius: $border-radius !default; +$card-box-shadow: null !default; $card-inner-border-radius: subtract($card-border-radius, $card-border-width) !default; -$card-cap-padding-y: $card-spacer-y / 2 !default; +$card-cap-padding-y: $card-spacer-y * .5 !default; $card-cap-padding-x: $card-spacer-x !default; $card-cap-bg: rgba($black, .03) !default; $card-cap-color: null !default; @@ -1100,7 +1274,7 @@ $card-height: null !default; $card-color: null !default; $card-bg: $white !default; $card-img-overlay-padding: $spacer !default; -$card-group-margin: $grid-gutter-width / 2 !default; +$card-group-margin: $grid-gutter-width * .5 !default; // scss-docs-end card-variables // Accordion @@ -1109,10 +1283,11 @@ $card-group-margin: $grid-gutter-width / 2 !default; $accordion-padding-y: 1rem !default; $accordion-padding-x: 1.25rem !default; $accordion-color: $body-color !default; -$accordion-bg: transparent !default; +$accordion-bg: $body-bg !default; $accordion-border-width: $border-width !default; $accordion-border-color: rgba($black, .125) !default; $accordion-border-radius: $border-radius !default; +$accordion-inner-border-radius: subtract($accordion-border-radius, $accordion-border-width) !default; $accordion-body-padding-y: $accordion-padding-y !default; $accordion-body-padding-x: $accordion-padding-x !default; @@ -1129,10 +1304,10 @@ $accordion-button-focus-border-color: $input-focus-border-color !default; $accordion-button-focus-box-shadow: $btn-focus-box-shadow !default; $accordion-icon-width: 1.25rem !default; -$accordion-icon-color: $accordion-color !default; +$accordion-icon-color: $accordion-button-color !default; $accordion-icon-active-color: $accordion-button-active-color !default; $accordion-icon-transition: transform .2s ease-in-out !default; -$accordion-icon-transform: rotate(180deg) !default; +$accordion-icon-transform: rotate(-180deg) !default; $accordion-button-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-color}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>") !default; $accordion-button-active-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-active-color}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>") !default; @@ -1147,8 +1322,8 @@ $tooltip-color: $white !default; $tooltip-bg: $black !default; $tooltip-border-radius: $border-radius !default; $tooltip-opacity: .9 !default; -$tooltip-padding-y: $spacer / 4 !default; -$tooltip-padding-x: $spacer / 2 !default; +$tooltip-padding-y: $spacer * .25 !default; +$tooltip-padding-x: $spacer * .5 !default; $tooltip-margin: 0 !default; $tooltip-arrow-width: .8rem !default; @@ -1164,7 +1339,7 @@ $form-feedback-tooltip-font-size: $tooltip-font-size !default; $form-feedback-tooltip-line-height: null !default; $form-feedback-tooltip-opacity: $tooltip-opacity !default; $form-feedback-tooltip-border-radius: $tooltip-border-radius !default; -// scss-docs-start tooltip-feedback-variables +// scss-docs-end tooltip-feedback-variables // Popovers @@ -1308,13 +1483,13 @@ $progress-bar-transition: width .6s ease !default; // List group // scss-docs-start list-group-variables -$list-group-color: null !default; +$list-group-color: $gray-900 !default; $list-group-bg: $white !default; $list-group-border-color: rgba($black, .125) !default; $list-group-border-width: $border-width !default; $list-group-border-radius: $border-radius !default; -$list-group-item-padding-y: $spacer / 2 !default; +$list-group-item-padding-y: $spacer * .5 !default; $list-group-item-padding-x: $spacer !default; $list-group-item-bg-scale: -80% !default; $list-group-item-color-scale: 40% !default; @@ -1413,6 +1588,7 @@ $carousel-dark-control-icon-filter: invert(1) grayscale(100) !default; // scss-docs-start spinner-variables $spinner-width: 2rem !default; $spinner-height: $spinner-width !default; +$spinner-vertical-align: -.125em !default; $spinner-border-width: .25em !default; $spinner-animation-speed: .75s !default; @@ -1440,6 +1616,24 @@ $btn-close-white-filter: invert(1) grayscale(100%) brightness(200%) !default // scss-docs-end close-variables +// Offcanvas + +// scss-docs-start offcanvas-variables +$offcanvas-padding-y: $modal-inner-padding !default; +$offcanvas-padding-x: $modal-inner-padding !default; +$offcanvas-horizontal-width: 400px !default; +$offcanvas-vertical-height: 30vh !default; +$offcanvas-transition-duration: .3s !default; +$offcanvas-border-color: $modal-content-border-color !default; +$offcanvas-border-width: $modal-content-border-width !default; +$offcanvas-title-line-height: $modal-title-line-height !default; +$offcanvas-bg-color: $modal-content-bg !default; +$offcanvas-color: $modal-content-color !default; +$offcanvas-box-shadow: $modal-content-box-shadow-xs !default; +$offcanvas-backdrop-bg: $modal-backdrop-bg !default; +$offcanvas-backdrop-opacity: $modal-backdrop-opacity !default; +// scss-docs-end offcanvas-variables + // Code $code-font-size: $small-font-size !default; diff --git a/scss/bootstrap-grid.scss b/scss/bootstrap-grid.scss index e394a29ed..2c68fbbf7 100644 --- a/scss/bootstrap-grid.scss +++ b/scss/bootstrap-grid.scss @@ -1,5 +1,5 @@ /*! - * Bootstrap Grid v5.0.0-beta2 (https://getbootstrap.com/) + * Bootstrap Grid v5.1.0 (https://getbootstrap.com/) * Copyright 2011-2021 The Bootstrap Authors * Copyright 2011-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) diff --git a/scss/bootstrap-reboot.scss b/scss/bootstrap-reboot.scss index 7aef48c99..0c4bbe589 100644 --- a/scss/bootstrap-reboot.scss +++ b/scss/bootstrap-reboot.scss @@ -1,5 +1,5 @@ /*! - * Bootstrap Reboot v5.0.0-beta2 (https://getbootstrap.com/) + * Bootstrap Reboot v5.1.0 (https://getbootstrap.com/) * Copyright 2011-2021 The Bootstrap Authors * Copyright 2011-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) diff --git a/scss/bootstrap-utilities.scss b/scss/bootstrap-utilities.scss index 6c818b63a..297e825fa 100644 --- a/scss/bootstrap-utilities.scss +++ b/scss/bootstrap-utilities.scss @@ -1,5 +1,5 @@ /*! - * Bootstrap Utilities v5.0.0-beta2 (https://getbootstrap.com/) + * Bootstrap Utilities v5.1.0 (https://getbootstrap.com/) * Copyright 2011-2021 The Bootstrap Authors * Copyright 2011-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) diff --git a/scss/bootstrap.scss b/scss/bootstrap.scss index f5f411753..e42b4b457 100644 --- a/scss/bootstrap.scss +++ b/scss/bootstrap.scss @@ -1,5 +1,5 @@ /*! - * Bootstrap v5.0.0-beta2 (https://getbootstrap.com/) + * Bootstrap v5.1.0 (https://getbootstrap.com/) * Copyright 2011-2021 The Bootstrap Authors * Copyright 2011-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) @@ -42,6 +42,8 @@ @import "popover"; @import "carousel"; @import "spinners"; +@import "offcanvas"; +@import "placeholders"; // Helpers @import "helpers"; diff --git a/scss/forms/_floating-labels.scss b/scss/forms/_floating-labels.scss index 8b2e2b8eb..2f4295480 100644 --- a/scss/forms/_floating-labels.scss +++ b/scss/forms/_floating-labels.scss @@ -4,7 +4,7 @@ > .form-control, > .form-select { height: $form-floating-height; - padding: $form-floating-padding-y $form-floating-padding-x; + line-height: $form-floating-line-height; } > label { @@ -21,6 +21,8 @@ // stylelint-disable no-duplicate-selectors > .form-control { + padding: $form-floating-padding-y $form-floating-padding-x; + &::placeholder { color: transparent; } diff --git a/scss/forms/_form-check.scss b/scss/forms/_form-check.scss index b34250a71..6321b4100 100644 --- a/scss/forms/_form-check.scss +++ b/scss/forms/_form-check.scss @@ -17,7 +17,7 @@ .form-check-input { width: $form-check-input-width; height: $form-check-input-width; - margin-top: ($line-height-base - $form-check-input-width) / 2; // line-height minus check height + margin-top: ($line-height-base - $form-check-input-width) * .5; // line-height minus check height vertical-align: top; background-color: $form-check-input-bg; background-repeat: no-repeat; diff --git a/scss/forms/_form-control.scss b/scss/forms/_form-control.scss index bac416f8c..96423c530 100644 --- a/scss/forms/_form-control.scss +++ b/scss/forms/_form-control.scss @@ -73,7 +73,6 @@ } // File input buttons theming - // stylelint-disable-next-line selector-pseudo-element-no-unknown &::file-selector-button { padding: $input-padding-y $input-padding-x; margin: (-$input-padding-y) (-$input-padding-x); @@ -89,7 +88,6 @@ @include transition($btn-transition); } - // stylelint-disable-next-line selector-pseudo-element-no-unknown &:hover:not(:disabled):not([readonly])::file-selector-button { background-color: $form-file-button-hover-bg; } @@ -150,7 +148,6 @@ @include font-size($input-font-size-sm); @include border-radius($input-border-radius-sm); - // stylelint-disable-next-line selector-pseudo-element-no-unknown &::file-selector-button { padding: $input-padding-y-sm $input-padding-x-sm; margin: (-$input-padding-y-sm) (-$input-padding-x-sm); @@ -170,7 +167,6 @@ @include font-size($input-font-size-lg); @include border-radius($input-border-radius-lg); - // stylelint-disable-next-line selector-pseudo-element-no-unknown &::file-selector-button { padding: $input-padding-y-lg $input-padding-x-lg; margin: (-$input-padding-y-lg) (-$input-padding-x-lg); @@ -203,7 +199,7 @@ textarea { // stylelint-enable selector-no-qualifying-type .form-control-color { - max-width: 3rem; + width: $form-color-width; height: auto; // Override fixed browser height padding: $input-padding-y; diff --git a/scss/forms/_form-range.scss b/scss/forms/_form-range.scss index ae1d841d5..6de42132e 100644 --- a/scss/forms/_form-range.scss +++ b/scss/forms/_form-range.scss @@ -27,7 +27,7 @@ &::-webkit-slider-thumb { width: $form-range-thumb-width; height: $form-range-thumb-height; - margin-top: ($form-range-track-height - $form-range-thumb-height) / 2; // Webkit specific + margin-top: ($form-range-track-height - $form-range-thumb-height) * .5; // Webkit specific @include gradient-bg($form-range-thumb-bg); border: $form-range-thumb-border; @include border-radius($form-range-thumb-border-radius); diff --git a/scss/forms/_form-select.scss b/scss/forms/_form-select.scss index 15d5061ad..4506a979a 100644 --- a/scss/forms/_form-select.scss +++ b/scss/forms/_form-select.scss @@ -7,6 +7,8 @@ display: block; width: 100%; padding: $form-select-padding-y $form-select-indicator-padding $form-select-padding-y $form-select-padding-x; + // stylelint-disable-next-line property-no-vendor-prefix + -moz-padding-start: subtract($form-select-padding-x, 3px); // See https://github.com/twbs/bootstrap/issues/32636 font-family: $form-select-font-family; @include font-size($form-select-font-size); font-weight: $form-select-font-weight; @@ -20,6 +22,7 @@ border: $form-select-border-width solid $form-select-border-color; @include border-radius($form-select-border-radius, 0); @include box-shadow($form-select-box-shadow); + @include transition($form-select-transition); appearance: none; &:focus { diff --git a/scss/helpers/_stacks.scss b/scss/helpers/_stacks.scss new file mode 100644 index 000000000..6cd237ae6 --- /dev/null +++ b/scss/helpers/_stacks.scss @@ -0,0 +1,15 @@ +// scss-docs-start stacks +.hstack { + display: flex; + flex-direction: row; + align-items: center; + align-self: stretch; +} + +.vstack { + display: flex; + flex: 1 1 auto; + flex-direction: column; + align-self: stretch; +} +// scss-docs-end stacks diff --git a/scss/helpers/_vr.scss b/scss/helpers/_vr.scss new file mode 100644 index 000000000..37f864777 --- /dev/null +++ b/scss/helpers/_vr.scss @@ -0,0 +1,8 @@ +.vr { + display: inline-block; + align-self: stretch; + width: 1px; + min-height: 1em; + background-color: currentColor; + opacity: $hr-opacity; +} diff --git a/scss/mixins/_backdrop.scss b/scss/mixins/_backdrop.scss new file mode 100644 index 000000000..9705ae9ee --- /dev/null +++ b/scss/mixins/_backdrop.scss @@ -0,0 +1,14 @@ +// Shared between modals and offcanvases +@mixin overlay-backdrop($zindex, $backdrop-bg, $backdrop-opacity) { + position: fixed; + top: 0; + left: 0; + z-index: $zindex; + width: 100vw; + height: 100vh; + background-color: $backdrop-bg; + + // Fade for backdrop + &.fade { opacity: 0; } + &.show { opacity: $backdrop-opacity; } +} diff --git a/scss/mixins/_buttons.scss b/scss/mixins/_buttons.scss index c06fa4a98..b67499668 100644 --- a/scss/mixins/_buttons.scss +++ b/scss/mixins/_buttons.scss @@ -11,7 +11,7 @@ $hover-background: if($color == $color-contrast-light, shade-color($background, $btn-hover-bg-shade-amount), tint-color($background, $btn-hover-bg-tint-amount)), $hover-border: if($color == $color-contrast-light, shade-color($border, $btn-hover-border-shade-amount), tint-color($border, $btn-hover-border-tint-amount)), $hover-color: color-contrast($hover-background), - $active-background: if($color == $color-contrast-light, shade-color($background,$btn-active-bg-shade-amount), tint-color($background, $btn-active-bg-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-border: if($color == $color-contrast-light, shade-color($border, $btn-active-border-shade-amount), tint-color($border, $btn-active-border-tint-amount)), $active-color: color-contrast($active-background), $disabled-background: $background, diff --git a/scss/mixins/_color-scheme.scss b/scss/mixins/_color-scheme.scss new file mode 100644 index 000000000..90497aa0a --- /dev/null +++ b/scss/mixins/_color-scheme.scss @@ -0,0 +1,7 @@ +// scss-docs-start mixin-color-scheme +@mixin color-scheme($name) { + @media (prefers-color-scheme: #{$name}) { + @content; + } +} +// scss-docs-end mixin-color-scheme diff --git a/scss/mixins/_forms.scss b/scss/mixins/_forms.scss index e3f8061e9..dc5bdb0b9 100644 --- a/scss/mixins/_forms.scss +++ b/scss/mixins/_forms.scss @@ -88,10 +88,13 @@ border-color: $color; @if $enable-validation-icons { - padding-right: $form-select-feedback-icon-padding-end; - background-image: escape-svg($form-select-indicator), escape-svg($icon); - background-position: $form-select-bg-position, $form-select-feedback-icon-position; - background-size: $form-select-bg-size, $form-select-feedback-icon-size; + &:not([multiple]):not([size]), + &:not([multiple])[size="1"] { + padding-right: $form-select-feedback-icon-padding-end; + background-image: escape-svg($form-select-indicator), escape-svg($icon); + background-position: $form-select-bg-position, $form-select-feedback-icon-position; + background-size: $form-select-bg-size, $form-select-feedback-icon-size; + } } &:focus { @@ -123,5 +126,19 @@ margin-left: .5em; } } + + .input-group .form-control, + .input-group .form-select { + @include form-validation-state-selector($state) { + @if $state == "valid" { + z-index: 1; + } @else if $state == "invalid" { + z-index: 2; + } + &:focus { + z-index: 3; + } + } + } } // scss-docs-end form-validation-mixins diff --git a/scss/mixins/_grid.scss b/scss/mixins/_grid.scss index 92bb88ad4..59cc56376 100644 --- a/scss/mixins/_grid.scss +++ b/scss/mixins/_grid.scss @@ -1,4 +1,4 @@ -/// Grid system +// Grid system // // Generate semantic grid columns with these mixins. @@ -8,8 +8,8 @@ display: flex; flex-wrap: wrap; margin-top: calc(var(--#{$variable-prefix}gutter-y) * -1); // stylelint-disable-line function-disallowed-list - margin-right: calc(var(--#{$variable-prefix}gutter-x) / -2); // stylelint-disable-line function-disallowed-list - margin-left: calc(var(--#{$variable-prefix}gutter-x) / -2); // stylelint-disable-line function-disallowed-list + margin-right: calc(var(--#{$variable-prefix}gutter-x) * -.5); // stylelint-disable-line function-disallowed-list + margin-left: calc(var(--#{$variable-prefix}gutter-x) * -.5); // stylelint-disable-line function-disallowed-list } @mixin make-col-ready($gutter: $grid-gutter-width) { @@ -21,14 +21,20 @@ flex-shrink: 0; width: 100%; max-width: 100%; // Prevent `.col-auto`, `.col` (& responsive variants) from breaking out the grid - padding-right: calc(var(--#{$variable-prefix}gutter-x) / 2); // stylelint-disable-line function-disallowed-list - padding-left: calc(var(--#{$variable-prefix}gutter-x) / 2); // stylelint-disable-line function-disallowed-list + padding-right: calc(var(--#{$variable-prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list + padding-left: calc(var(--#{$variable-prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list margin-top: var(--#{$variable-prefix}gutter-y); } -@mixin make-col($size, $columns: $grid-columns) { - flex: 0 0 auto; - width: percentage($size / $columns); +@mixin make-col($size: false, $columns: $grid-columns) { + @if $size { + flex: 0 0 auto; + width: percentage(divide($size, $columns)); + + } @else { + flex: 1 1 0; + max-width: 100%; + } } @mixin make-col-auto() { @@ -37,7 +43,7 @@ } @mixin make-col-offset($size, $columns: $grid-columns) { - $num: $size / $columns; + $num: divide($size, $columns); margin-left: if($num == 0, 0, percentage($num)); } @@ -49,7 +55,7 @@ @mixin row-cols($count) { > * { flex: 0 0 auto; - width: 100% / $count; + width: divide(100%, $count); } } @@ -118,3 +124,27 @@ } } } + +@mixin make-cssgrid($columns: $grid-columns, $breakpoints: $grid-breakpoints) { + @each $breakpoint in map-keys($breakpoints) { + $infix: breakpoint-infix($breakpoint, $breakpoints); + + @include media-breakpoint-up($breakpoint, $breakpoints) { + @if $columns > 0 { + @for $i from 1 through $columns { + .g-col#{$infix}-#{$i} { + grid-column: auto / span $i; + } + } + + // Start with `1` because `0` is and invalid value. + // Ends with `$columns - 1` because offsetting by the width of an entire row isn't possible. + @for $i from 1 through ($columns - 1) { + .g-start#{$infix}-#{$i} { + grid-column-start: $i; + } + } + } + } + } +} diff --git a/scss/mixins/_utilities.scss b/scss/mixins/_utilities.scss index 4d2370a0b..e871b4233 100644 --- a/scss/mixins/_utilities.scss +++ b/scss/mixins/_utilities.scss @@ -41,25 +41,46 @@ } } + $is-css-var: map-get($utility, css-var); + $is-local-vars: map-get($utility, local-vars); $is-rtl: map-get($utility, rtl); @if $value != null { @if $is-rtl == false { /* rtl:begin:remove */ } - .#{$property-class + $infix + $property-class-modifier} { - @each $property in $properties { - #{$property}: $value if($enable-important-utilities, !important, null); + + @if $is-css-var { + .#{$property-class + $infix + $property-class-modifier} { + --#{$variable-prefix}#{$property-class}: #{$value}; } - } - @each $pseudo in $state { - .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} { + @each $pseudo in $state { + .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} { + --#{$variable-prefix}#{$property-class}: #{$value}; + } + } + } @else { + .#{$property-class + $infix + $property-class-modifier} { @each $property in $properties { + @if $is-local-vars { + @each $local-var, $value in $is-local-vars { + --#{$variable-prefix}#{$local-var}: #{$value}; + } + } #{$property}: $value if($enable-important-utilities, !important, null); } } + + @each $pseudo in $state { + .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} { + @each $property in $properties { + #{$property}: $value if($enable-important-utilities, !important, null); + } + } + } } + @if $is-rtl == false { /* rtl:end:remove */ } diff --git a/scss/vendor/_rfs.scss b/scss/vendor/_rfs.scss index 798753ecb..7e9a6c7a8 100644 --- a/scss/vendor/_rfs.scss +++ b/scss/vendor/_rfs.scss @@ -4,7 +4,7 @@ // // Automated responsive values for font sizes, paddings, margins and much more // -// Licensed under MIT (https://github.com/twbs/rfs/blob/master/LICENSE) +// Licensed under MIT (https://github.com/twbs/rfs/blob/main/LICENSE) // Configuration @@ -52,12 +52,54 @@ $enable-rfs: true !default; // Cache $rfs-base-value unit $rfs-base-value-unit: unit($rfs-base-value); +@function divide($dividend, $divisor, $precision: 10) { + $sign: if($dividend > 0 and $divisor > 0 or $dividend < 0 and $divisor < 0, 1, -1); + $dividend: abs($dividend); + $divisor: abs($divisor); + @if $dividend == 0 { + @return 0; + } + @if $divisor == 0 { + @error "Cannot divide by 0"; + } + $remainder: $dividend; + $result: 0; + $factor: 10; + @while ($remainder > 0 and $precision >= 0) { + $quotient: 0; + @while ($remainder >= $divisor) { + $remainder: $remainder - $divisor; + $quotient: $quotient + 1; + } + $result: $result * 10 + $quotient; + $factor: $factor * .1; + $remainder: $remainder * 10; + $precision: $precision - 1; + @if ($precision < 0 and $remainder >= $divisor * 5) { + $result: $result + 1; + } + } + $result: $result * $factor * $sign; + $dividend-unit: unit($dividend); + $divisor-unit: unit($divisor); + $unit-map: ( + "px": 1px, + "rem": 1rem, + "em": 1em, + "%": 1% + ); + @if ($dividend-unit != $divisor-unit and map-has-key($unit-map, $dividend-unit)) { + $result: $result * map-get($unit-map, $dividend-unit); + } + @return $result; +} + // Remove px-unit from $rfs-base-value for calculations @if $rfs-base-value-unit == px { - $rfs-base-value: $rfs-base-value / ($rfs-base-value * 0 + 1); + $rfs-base-value: divide($rfs-base-value, $rfs-base-value * 0 + 1); } @else if $rfs-base-value-unit == rem { - $rfs-base-value: $rfs-base-value / ($rfs-base-value * 0 + 1 / $rfs-rem-value); + $rfs-base-value: divide($rfs-base-value, divide($rfs-base-value * 0 + 1, $rfs-rem-value)); } // Cache $rfs-breakpoint unit to prevent multiple calls @@ -65,14 +107,14 @@ $rfs-breakpoint-unit-cache: unit($rfs-breakpoint); // Remove unit from $rfs-breakpoint for calculations @if $rfs-breakpoint-unit-cache == px { - $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1); + $rfs-breakpoint: divide($rfs-breakpoint, $rfs-breakpoint * 0 + 1); } @else if $rfs-breakpoint-unit-cache == rem or $rfs-breakpoint-unit-cache == "em" { - $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1 / $rfs-rem-value); + $rfs-breakpoint: divide($rfs-breakpoint, divide($rfs-breakpoint * 0 + 1, $rfs-rem-value)); } // Calculate the media query value -$rfs-mq-value: if($rfs-breakpoint-unit == px, #{$rfs-breakpoint}px, #{$rfs-breakpoint / $rfs-rem-value}#{$rfs-breakpoint-unit}); +$rfs-mq-value: if($rfs-breakpoint-unit == px, #{$rfs-breakpoint}px, #{divide($rfs-breakpoint, $rfs-rem-value)}#{$rfs-breakpoint-unit}); $rfs-mq-property-width: if($rfs-mode == max-media-query, max-width, min-width); $rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height); @@ -164,11 +206,11 @@ $rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height @if $unit == px { // Convert to rem if needed - $val: $val + ' ' + if($rfs-unit == rem, #{$value / ($value * 0 + $rfs-rem-value)}rem, $value); + $val: $val + ' ' + if($rfs-unit == rem, #{divide($value, $value * 0 + $rfs-rem-value)}rem, $value); } @else if $unit == rem { // Convert to px if needed - $val: $val + ' ' + if($rfs-unit == px, #{$value / ($value * 0 + 1) * $rfs-rem-value}px, $value); + $val: $val + ' ' + if($rfs-unit == px, #{divide($value, $value * 0 + 1) * $rfs-rem-value}px, $value); } @else { // If $value isn't a number (like inherit) or $value has a unit (not px or rem, like 1.5em) or $ is 0, just print the value @@ -205,21 +247,21 @@ $rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height @else { // Remove unit from $value for calculations - $value: $value / ($value * 0 + if($unit == px, 1, 1 / $rfs-rem-value)); + $value: divide($value, $value * 0 + if($unit == px, 1, divide(1, $rfs-rem-value))); // Only add the media query if the value is greater than the minimum value @if abs($value) <= $rfs-base-value or not $enable-rfs { - $val: $val + ' ' + if($rfs-unit == rem, #{$value / $rfs-rem-value}rem, #{$value}px); + $val: $val + ' ' + if($rfs-unit == rem, #{divide($value, $rfs-rem-value)}rem, #{$value}px); } @else { // Calculate the minimum value - $value-min: $rfs-base-value + (abs($value) - $rfs-base-value) / $rfs-factor; + $value-min: $rfs-base-value + divide(abs($value) - $rfs-base-value, $rfs-factor); // Calculate difference between $value and the minimum value $value-diff: abs($value) - $value-min; // Base value formatting - $min-width: if($rfs-unit == rem, #{$value-min / $rfs-rem-value}rem, #{$value-min}px); + $min-width: if($rfs-unit == rem, #{divide($value-min, $rfs-rem-value)}rem, #{$value-min}px); // Use negative value if needed $min-width: if($value < 0, -$min-width, $min-width); @@ -228,7 +270,7 @@ $rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height $variable-unit: if($rfs-two-dimensional, vmin, vw); // Calculate the variable width between 0 and $rfs-breakpoint - $variable-width: #{$value-diff * 100 / $rfs-breakpoint}#{$variable-unit}; + $variable-width: #{divide($value-diff * 100, $rfs-breakpoint)}#{$variable-unit}; // Return the calculated value $val: $val + ' calc(' + $min-width + if($value < 0, ' - ', ' + ') + $variable-width + ')'; |
