Created
February 11, 2020 17:13
-
-
Save nickolas1/ae7db87a1fe2aa11c0af4d5cac8639e8 to your computer and use it in GitHub Desktop.
bootstrap 4.3.1 scss in toto
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Bootstrap functions | |
// | |
// Utility mixins and functions for evaluating source code across our variables, maps, and mixins. | |
// Ascending | |
// Used to evaluate Sass maps like our grid breakpoints. | |
@mixin _assert-ascending($map, $map-name) { | |
$prev-key: null; | |
$prev-num: null; | |
@each $key, $num in $map { | |
@if $prev-num == null or unit($num) == "%" or unit($prev-num) == "%" { | |
// Do nothing | |
} @else if not comparable($prev-num, $num) { | |
@warn "Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !"; | |
} @else if $prev-num >= $num { | |
@warn "Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !"; | |
} | |
$prev-key: $key; | |
$prev-num: $num; | |
} | |
} | |
// Starts at zero | |
// Used to ensure the min-width of the lowest breakpoint starts at 0. | |
@mixin _assert-starts-at-zero($map, $map-name: "$grid-breakpoints") { | |
$values: map-values($map); | |
$first-value: nth($values, 1); | |
@if $first-value != 0 { | |
@warn "First breakpoint in #{$map-name} must start at 0, but starts at #{$first-value}."; | |
} | |
} | |
// 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) { | |
$result: (); | |
@each $key, $value in $map { | |
@if $key != 0 { | |
$result: map-merge($result, ("n" + $key: (-$value))); | |
} | |
} | |
@return $result; | |
} | |
// Get multiple keys from a sass map | |
@function map-get-multiple($map, $values) { | |
$result: (); | |
@each $key, $value in $map { | |
@if (index($values, $key) != null) { | |
$result: map-merge($result, ($key: $value)); | |
} | |
} | |
@return $result; | |
} | |
// Replace `$search` with `$replace` in `$string` | |
// Used on our SVG icon backgrounds for custom forms. | |
// | |
// @author Hugo Giraudel | |
// @param {String} $string - Initial string | |
// @param {String} $search - Substring to replace | |
// @param {String} $replace ('') - New value | |
// @return {String} - Updated string | |
@function str-replace($string, $search, $replace: "") { | |
$index: str-index($string, $search); | |
@if $index { | |
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace); | |
} | |
@return $string; | |
} | |
// See https://codepen.io/kevinweber/pen/dXWoRw | |
@function escape-svg($string) { | |
@if str-index($string, "data:image/svg+xml") { | |
@each $char, $encoded in $escaped-characters { | |
// Do not escape the url brackets | |
@if str-index($string, "url(") == 1 { | |
$string: url("#{str-replace(str-slice($string, 6, -3), $char, $encoded)}"); | |
} @else { | |
$string: str-replace($string, $char, $encoded); | |
} | |
} | |
} | |
@return $string; | |
} | |
// Color contrast | |
@function color-yiq($color, $dark: $yiq-text-dark, $light: $yiq-text-light) { | |
$r: red($color); | |
$g: green($color); | |
$b: blue($color); | |
$yiq: (($r * 299) + ($g * 587) + ($b * 114)) / 1000; | |
@return if($yiq >= $yiq-contrasted-threshold, $dark, $light); | |
} | |
// Request a color level | |
@function color-level($color: $primary, $level: 0) { | |
$color-base: if($level > 0, $black, $white); | |
$level: abs($level); | |
@return mix($color-base, $color, $level * $theme-color-interval); | |
} | |
@function tint-color($color, $level) { | |
@return mix(white, $color, $level * $theme-color-interval); | |
} | |
@function shade-color($color, $level) { | |
@return mix(black, $color, $level * $theme-color-interval); | |
} | |
// Return valid calc | |
@function add($value1, $value2, $return-calc: true) { | |
@if $value1 == null { | |
@return $value2; | |
} | |
@if $value2 == null { | |
@return $value1; | |
} | |
@if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) { | |
@return $value1 + $value2; | |
} | |
@return if($return-calc == true, calc(#{$value1} + #{$value2}), $value1 + unquote(" + ") + $value2); | |
} | |
@function subtract($value1, $value2, $return-calc: true) { | |
@if $value1 == null and $value2 == null { | |
@return null; | |
} | |
@if $value1 == null { | |
@return -$value2; | |
} | |
@if $value2 == null { | |
@return $value1; | |
} | |
@if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) { | |
@return $value1 - $value2; | |
} | |
@return if($return-calc == true, calc(#{$value1} - #{$value2}), $value1 + unquote(" - ") + $value2); | |
} | |
// Variables | |
// | |
// Variables should follow the `$component-state-property-size` formula for | |
// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs. | |
// Color system | |
$white: #fff !default; | |
$gray-100: #f8f9fa !default; | |
$gray-200: #e9ecef !default; | |
$gray-300: #dee2e6 !default; | |
$gray-400: #ced4da !default; | |
$gray-500: #adb5bd !default; | |
$gray-600: #6c757d !default; | |
$gray-700: #495057 !default; | |
$gray-800: #343a40 !default; | |
$gray-900: #212529 !default; | |
$black: #000 !default; | |
$grays: () !default; | |
// stylelint-disable-next-line scss/dollar-variable-default | |
$grays: map-merge( | |
( | |
"100": $gray-100, | |
"200": $gray-200, | |
"300": $gray-300, | |
"400": $gray-400, | |
"500": $gray-500, | |
"600": $gray-600, | |
"700": $gray-700, | |
"800": $gray-800, | |
"900": $gray-900 | |
), | |
$grays | |
); | |
$blue: #0d6efd !default; | |
$indigo: #6610f2 !default; | |
$purple: #6f42c1 !default; | |
$pink: #d63384 !default; | |
$red: #dc3545 !default; | |
$orange: #fd7e14 !default; | |
$yellow: #ffc107 !default; | |
$green: #28a745 !default; | |
$teal: #20c997 !default; | |
$cyan: #17a2b8 !default; | |
$colors: () !default; | |
// stylelint-disable-next-line scss/dollar-variable-default | |
$colors: map-merge( | |
( | |
"blue": $blue, | |
"indigo": $indigo, | |
"purple": $purple, | |
"pink": $pink, | |
"red": $red, | |
"orange": $orange, | |
"yellow": $yellow, | |
"green": $green, | |
"teal": $teal, | |
"cyan": $cyan, | |
"white": $white, | |
"gray": $gray-600, | |
"gray-dark": $gray-800 | |
), | |
$colors | |
); | |
$primary: $blue !default; | |
$secondary: $gray-600 !default; | |
$success: $green !default; | |
$info: $cyan !default; | |
$warning: $yellow !default; | |
$danger: $red !default; | |
$light: $gray-100 !default; | |
$dark: $gray-800 !default; | |
$theme-colors: () !default; | |
// stylelint-disable-next-line scss/dollar-variable-default | |
$theme-colors: map-merge( | |
( | |
"primary": $primary, | |
"secondary": $secondary, | |
"success": $success, | |
"info": $info, | |
"warning": $warning, | |
"danger": $danger, | |
"light": $light, | |
"dark": $dark | |
), | |
$theme-colors | |
); | |
// Set a specific jump point for requesting color jumps | |
$theme-color-interval: 8% !default; | |
// The yiq lightness value that determines when the lightness of color changes from "dark" to "light". Acceptable values are between 0 and 255. | |
$yiq-contrasted-threshold: 150 !default; | |
// Customize the light and dark text colors for use in our YIQ color contrast function. | |
$yiq-text-dark: $gray-900 !default; | |
$yiq-text-light: $white !default; | |
// fusv-disable | |
$blue-100: tint-color($blue, 8) !default; | |
$blue-200: tint-color($blue, 6) !default; | |
$blue-300: tint-color($blue, 4) !default; | |
$blue-400: tint-color($blue, 2) !default; | |
$blue-500: $blue !default; | |
$blue-600: shade-color($blue, 2) !default; | |
$blue-700: shade-color($blue, 4) !default; | |
$blue-800: shade-color($blue, 6) !default; | |
$blue-900: shade-color($blue, 8) !default; | |
$indigo-100: tint-color($indigo, 8) !default; | |
$indigo-200: tint-color($indigo, 6) !default; | |
$indigo-300: tint-color($indigo, 4) !default; | |
$indigo-400: tint-color($indigo, 2) !default; | |
$indigo-500: $indigo !default; | |
$indigo-600: shade-color($indigo, 2) !default; | |
$indigo-700: shade-color($indigo, 4) !default; | |
$indigo-800: shade-color($indigo, 6) !default; | |
$indigo-900: shade-color($indigo, 8) !default; | |
$purple-100: tint-color($purple, 8) !default; | |
$purple-200: tint-color($purple, 6) !default; | |
$purple-300: tint-color($purple, 4) !default; | |
$purple-400: tint-color($purple, 2) !default; | |
$purple-500: $purple !default; | |
$purple-600: shade-color($purple, 2) !default; | |
$purple-700: shade-color($purple, 4) !default; | |
$purple-800: shade-color($purple, 6) !default; | |
$purple-900: shade-color($purple, 8) !default; | |
$pink-100: tint-color($pink, 8) !default; | |
$pink-200: tint-color($pink, 6) !default; | |
$pink-300: tint-color($pink, 4) !default; | |
$pink-400: tint-color($pink, 2) !default; | |
$pink-500: $pink !default; | |
$pink-600: shade-color($pink, 2) !default; | |
$pink-700: shade-color($pink, 4) !default; | |
$pink-800: shade-color($pink, 6) !default; | |
$pink-900: shade-color($pink, 8) !default; | |
$red-100: tint-color($red, 8) !default; | |
$red-200: tint-color($red, 6) !default; | |
$red-300: tint-color($red, 4) !default; | |
$red-400: tint-color($red, 2) !default; | |
$red-500: $red !default; | |
$red-600: shade-color($red, 2) !default; | |
$red-700: shade-color($red, 4) !default; | |
$red-800: shade-color($red, 6) !default; | |
$red-900: shade-color($red, 8) !default; | |
$orange-100: tint-color($orange, 8) !default; | |
$orange-200: tint-color($orange, 6) !default; | |
$orange-300: tint-color($orange, 4) !default; | |
$orange-400: tint-color($orange, 2) !default; | |
$orange-500: $orange !default; | |
$orange-600: shade-color($orange, 2) !default; | |
$orange-700: shade-color($orange, 4) !default; | |
$orange-800: shade-color($orange, 6) !default; | |
$orange-900: shade-color($orange, 8) !default; | |
$yellow-100: tint-color($yellow, 8) !default; | |
$yellow-200: tint-color($yellow, 6) !default; | |
$yellow-300: tint-color($yellow, 4) !default; | |
$yellow-400: tint-color($yellow, 2) !default; | |
$yellow-500: $yellow !default; | |
$yellow-600: shade-color($yellow, 2) !default; | |
$yellow-700: shade-color($yellow, 4) !default; | |
$yellow-800: shade-color($yellow, 6) !default; | |
$yellow-900: shade-color($yellow, 8) !default; | |
$green-100: tint-color($green, 8) !default; | |
$green-200: tint-color($green, 6) !default; | |
$green-300: tint-color($green, 4) !default; | |
$green-400: tint-color($green, 2) !default; | |
$green-500: $green !default; | |
$green-600: shade-color($green, 2) !default; | |
$green-700: shade-color($green, 4) !default; | |
$green-800: shade-color($green, 6) !default; | |
$green-900: shade-color($green, 8) !default; | |
$teal-100: tint-color($teal, 8) !default; | |
$teal-200: tint-color($teal, 6) !default; | |
$teal-300: tint-color($teal, 4) !default; | |
$teal-400: tint-color($teal, 2) !default; | |
$teal-500: $teal !default; | |
$teal-600: shade-color($teal, 2) !default; | |
$teal-700: shade-color($teal, 4) !default; | |
$teal-800: shade-color($teal, 6) !default; | |
$teal-900: shade-color($teal, 8) !default; | |
$cyan-100: tint-color($cyan, 8) !default; | |
$cyan-200: tint-color($cyan, 6) !default; | |
$cyan-300: tint-color($cyan, 4) !default; | |
$cyan-400: tint-color($cyan, 2) !default; | |
$cyan-500: $cyan !default; | |
$cyan-600: shade-color($cyan, 2) !default; | |
$cyan-700: shade-color($cyan, 4) !default; | |
$cyan-800: shade-color($cyan, 6) !default; | |
$cyan-900: shade-color($cyan, 8) !default; | |
// fusv-enable | |
// Characters which are escaped by the escape-svg function | |
$escaped-characters: ( | |
("<","%3c"), | |
(">","%3e"), | |
("#","%23"), | |
("(","%28"), | |
(")","%29"), | |
) !default; | |
// Options | |
// | |
// Quickly modify global styling by enabling or disabling optional features. | |
$enable-caret: true !default; | |
$enable-rounded: true !default; | |
$enable-shadows: false !default; | |
$enable-gradients: false !default; | |
$enable-transitions: true !default; | |
$enable-prefers-reduced-motion-media-query: true !default; | |
$enable-grid-classes: true !default; | |
$enable-pointer-cursor-for-buttons: true !default; | |
$enable-rfs: true !default; | |
$enable-validation-icons: true !default; | |
$enable-deprecation-messages: true !default; | |
$enable-important-utilities: true !default; | |
// Spacing | |
// | |
// Control the default styling of most Bootstrap elements by modifying these | |
// variables. Mostly focused on spacing. | |
// You can add more entries to the $spacers map, should you need more variation. | |
$spacer: 1rem !default; | |
$spacers: () !default; | |
// stylelint-disable-next-line scss/dollar-variable-default | |
$spacers: map-merge( | |
( | |
0: 0, | |
1: $spacer * .25, | |
2: $spacer * .5, | |
3: $spacer, | |
4: $spacer * 1.5, | |
5: $spacer * 3, | |
), | |
$spacers | |
); | |
$negative-spacers: negativify-map($spacers) !default; | |
// Body | |
// | |
// Settings for the `<body>` element. | |
$body-bg: $white !default; | |
$body-color: $gray-900 !default; | |
$body-text-align: null !default; | |
// Links | |
// | |
// Style anchor elements. | |
$link-color: $primary !default; | |
$link-decoration: none !default; | |
$link-hover-color: darken($link-color, 15%) !default; | |
$link-hover-decoration: underline !default; | |
// Darken percentage for links with `.text-*` class (e.g. `.text-success`) | |
$emphasized-link-hover-darken-percentage: 15% !default; | |
$stretched-link-pseudo-element: after !default; | |
$stretched-link-z-index: 1 !default; | |
// Paragraphs | |
// | |
// Style p element. | |
$paragraph-margin-bottom: 1rem !default; | |
// Grid breakpoints | |
// | |
// Define the minimum dimensions at which your layout will change, | |
// adapting to different screen sizes, for use in media queries. | |
$grid-breakpoints: ( | |
xs: 0, | |
sm: 576px, | |
md: 768px, | |
lg: 992px, | |
xl: 1200px | |
) !default; | |
@include _assert-ascending($grid-breakpoints, "$grid-breakpoints"); | |
@include _assert-starts-at-zero($grid-breakpoints, "$grid-breakpoints"); | |
// Grid containers | |
// | |
// Define the maximum width of `.container` for different screen sizes. | |
$container-max-widths: ( | |
sm: 540px, | |
md: 720px, | |
lg: 960px, | |
xl: 1140px | |
) !default; | |
@include _assert-ascending($container-max-widths, "$container-max-widths"); | |
// Grid columns | |
// | |
// Set the number of columns and specify the width of the gutters. | |
$grid-columns: 12 !default; | |
$grid-gutter-width: 30px !default; | |
$grid-row-columns: 6 !default; | |
// Container padding | |
$container-padding-x: $grid-gutter-width / 2 !default; | |
// Components | |
// | |
// Define common padding and border radius sizes and more. | |
$border-width: 1px !default; | |
$border-color: $gray-300 !default; | |
$border-radius: .25rem !default; | |
$border-radius-lg: .3rem !default; | |
$border-radius-sm: .2rem !default; | |
$rounded-pill: 50rem !default; | |
$box-shadow-sm: 0 .125rem .25rem rgba($black, .075) !default; | |
$box-shadow: 0 .5rem 1rem rgba($black, .15) !default; | |
$box-shadow-lg: 0 1rem 3rem rgba($black, .175) !default; | |
$box-shadow-inset: inset 0 1px 2px rgba($black, .075) !default; | |
$component-active-color: $white !default; | |
$component-active-bg: $primary !default; | |
$caret-width: .3em !default; | |
$caret-vertical-align: $caret-width * .85 !default; | |
$caret-spacing: $caret-width * .85 !default; | |
$transition-base: all .2s ease-in-out !default; | |
$transition-fade: opacity .15s linear !default; | |
$transition-collapse: height .35s ease !default; | |
$embed-responsive-aspect-ratios: () !default; | |
// stylelint-disable-next-line scss/dollar-variable-default | |
$embed-responsive-aspect-ratios: map-merge( | |
( | |
"21by9": ( | |
x: 21, | |
y: 9 | |
), | |
"16by9": ( | |
x: 16, | |
y: 9 | |
), | |
"4by3": ( | |
x: 4, | |
y: 3 | |
), | |
"1by1": ( | |
x: 1, | |
y: 1 | |
) | |
), | |
$embed-responsive-aspect-ratios | |
); | |
// Typography | |
// | |
// Font, line-height, and color for body text, headings, and more. | |
// stylelint-disable value-keyword-case | |
$font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !default; | |
$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !default; | |
$font-family-base: $font-family-sans-serif !default; | |
// stylelint-enable value-keyword-case | |
// $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: null !default; | |
$font-size-base: 1rem !default; // Assumes the browser default, typically `16px` | |
$font-size-lg: $font-size-base * 1.25 !default; | |
$font-size-sm: $font-size-base * .875 !default; | |
$font-weight-lighter: lighter !default; | |
$font-weight-light: 300 !default; | |
$font-weight-normal: 400 !default; | |
$font-weight-bold: 700 !default; | |
$font-weight-bolder: bolder !default; | |
$font-weight-base: $font-weight-normal !default; | |
$line-height-base: 1.5 !default; | |
$line-height-lg: 2 !default; | |
$line-height-sm: 1.25 !default; | |
$h1-font-size: $font-size-base * 2.5 !default; | |
$h2-font-size: $font-size-base * 2 !default; | |
$h3-font-size: $font-size-base * 1.75 !default; | |
$h4-font-size: $font-size-base * 1.5 !default; | |
$h5-font-size: $font-size-base * 1.25 !default; | |
$h6-font-size: $font-size-base !default; | |
$headings-margin-bottom: $spacer / 2 !default; | |
$headings-font-family: null !default; | |
$headings-font-style: null !default; | |
$headings-font-weight: 500 !default; | |
$headings-line-height: 1.2 !default; | |
$headings-color: null !default; | |
$display1-size: 6rem !default; | |
$display2-size: 5.5rem !default; | |
$display3-size: 4.5rem !default; | |
$display4-size: 3.5rem !default; | |
$display1-weight: 300 !default; | |
$display2-weight: 300 !default; | |
$display3-weight: 300 !default; | |
$display4-weight: 300 !default; | |
$display-line-height: $headings-line-height !default; | |
$lead-font-size: $font-size-base * 1.25 !default; | |
$lead-font-weight: 300 !default; | |
$small-font-size: .875em !default; | |
$sub-sup-font-size: .75em !default; | |
$text-muted: $gray-600 !default; | |
$initialism-font-size: $small-font-size !default; | |
$blockquote-small-color: $gray-600 !default; | |
$blockquote-small-font-size: $small-font-size !default; | |
$blockquote-font-size: $font-size-base * 1.25 !default; | |
$hr-color: inherit !default; | |
$hr-height: $border-width !default; | |
$hr-opacity: .25 !default; | |
$legend-margin-bottom: .5rem !default; | |
$legend-font-size: 1.5rem !default; | |
$legend-font-weight: null !default; | |
$mark-padding: .2em !default; | |
$dt-font-weight: $font-weight-bold !default; | |
$nested-kbd-font-weight: $font-weight-bold !default; | |
$list-inline-padding: .5rem !default; | |
$mark-bg: #fcf8e3 !default; | |
$hr-margin-y: $spacer !default; | |
// Tables | |
// | |
// Customizes the `.table` component with basic values, each used across all table variations. | |
$table-cell-padding: .5rem !default; | |
$table-cell-padding-sm: .25rem !default; | |
$table-cell-vertical-align: top !default; | |
$table-color: $body-color !default; | |
$table-bg: null !default; | |
$table-accent-bg: rgba($black, .05) !default; | |
$table-hover-color: $table-color !default; | |
$table-hover-bg: rgba($black, .075) !default; | |
$table-active-bg: $table-hover-bg !default; | |
$table-border-width: $border-width !default; | |
$table-border-color: $border-color !default; | |
$table-head-bg: $gray-200 !default; | |
$table-head-color: $gray-700 !default; | |
$table-head-border-color: $gray-700 !default; | |
$table-dark-color: $white !default; | |
$table-dark-bg: $gray-800 !default; | |
$table-dark-accent-bg: rgba($white, .05) !default; | |
$table-dark-hover-color: $table-dark-color !default; | |
$table-dark-hover-bg: rgba($white, .075) !default; | |
$table-dark-border-color: lighten($table-dark-bg, 7.5%) !default; | |
$table-striped-order: odd !default; | |
$table-caption-color: $text-muted !default; | |
$table-bg-level: -9 !default; | |
$table-border-level: -6 !default; | |
// Buttons + Forms | |
// | |
// Shared variables that are reassigned to `$input-` and `$btn-` specific variables. | |
$input-btn-padding-y: .375rem !default; | |
$input-btn-padding-x: .75rem !default; | |
$input-btn-font-family: null !default; | |
$input-btn-font-size: $font-size-base !default; | |
$input-btn-line-height: $line-height-base !default; | |
$input-btn-focus-width: .2rem !default; | |
$input-btn-focus-color: rgba($component-active-bg, .25) !default; | |
$input-btn-focus-box-shadow: 0 0 0 $input-btn-focus-width $input-btn-focus-color !default; | |
$input-btn-padding-y-sm: .25rem !default; | |
$input-btn-padding-x-sm: .5rem !default; | |
$input-btn-font-size-sm: $font-size-sm !default; | |
$input-btn-padding-y-lg: .5rem !default; | |
$input-btn-padding-x-lg: 1rem !default; | |
$input-btn-font-size-lg: $font-size-lg !default; | |
$input-btn-border-width: $border-width !default; | |
// Buttons | |
// | |
// For each of Bootstrap's buttons, define text, background, and border color. | |
$btn-padding-y: $input-btn-padding-y !default; | |
$btn-padding-x: $input-btn-padding-x !default; | |
$btn-font-family: $input-btn-font-family !default; | |
$btn-font-size: $input-btn-font-size !default; | |
$btn-line-height: $input-btn-line-height !default; | |
$btn-white-space: null !default; // Set to `nowrap` to prevent text wrapping | |
$btn-padding-y-sm: $input-btn-padding-y-sm !default; | |
$btn-padding-x-sm: $input-btn-padding-x-sm !default; | |
$btn-font-size-sm: $input-btn-font-size-sm !default; | |
$btn-padding-y-lg: $input-btn-padding-y-lg !default; | |
$btn-padding-x-lg: $input-btn-padding-x-lg !default; | |
$btn-font-size-lg: $input-btn-font-size-lg !default; | |
$btn-border-width: $input-btn-border-width !default; | |
$btn-font-weight: $font-weight-normal !default; | |
$btn-box-shadow: inset 0 1px 0 rgba($white, .15), 0 1px 1px rgba($black, .075) !default; | |
$btn-focus-width: $input-btn-focus-width !default; | |
$btn-focus-box-shadow: $input-btn-focus-box-shadow !default; | |
$btn-disabled-opacity: .65 !default; | |
$btn-active-box-shadow: inset 0 3px 5px rgba($black, .125) !default; | |
$btn-link-color: $link-color !default; | |
$btn-link-hover-color: $link-hover-color !default; | |
$btn-link-disabled-color: $gray-600 !default; | |
$btn-block-spacing-y: .5rem !default; | |
// Allows for customizing button radius independently from global border radius | |
$btn-border-radius: $border-radius !default; | |
$btn-border-radius-lg: $border-radius-lg !default; | |
$btn-border-radius-sm: $border-radius-sm !default; | |
$btn-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default; | |
// Forms | |
$label-margin-bottom: .5rem !default; | |
$input-padding-y: $input-btn-padding-y !default; | |
$input-padding-x: $input-btn-padding-x !default; | |
$input-font-family: $input-btn-font-family !default; | |
$input-font-size: $input-btn-font-size !default; | |
$input-font-weight: $font-weight-base !default; | |
$input-line-height: $input-btn-line-height !default; | |
$input-padding-y-sm: $input-btn-padding-y-sm !default; | |
$input-padding-x-sm: $input-btn-padding-x-sm !default; | |
$input-font-size-sm: $input-btn-font-size-sm !default; | |
$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-disabled-bg: $gray-200 !default; | |
$input-disabled-border-color: null !default; | |
$input-color: $gray-700 !default; | |
$input-border-color: $gray-400 !default; | |
$input-border-width: $input-btn-border-width !default; | |
$input-box-shadow: $box-shadow-inset !default; | |
$input-border-radius: $border-radius !default; | |
$input-border-radius-lg: $border-radius-lg !default; | |
$input-border-radius-sm: $border-radius-sm !default; | |
$input-focus-bg: $input-bg !default; | |
$input-focus-border-color: lighten($component-active-bg, 25%) !default; | |
$input-focus-color: $input-color !default; | |
$input-focus-width: $input-btn-focus-width !default; | |
$input-focus-box-shadow: $input-btn-focus-box-shadow !default; | |
$input-placeholder-color: $gray-600 !default; | |
$input-plaintext-color: $body-color !default; | |
$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: 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-check-input-width: 1.25em !default; | |
$form-check-min-height: $font-size-base * $line-height-base !default; | |
$form-check-padding-left: $form-check-input-width + .5em !default; | |
$form-check-margin-bottom: .125rem !default; | |
$form-check-label-cursor: null !default; | |
$form-check-input-active-filter: brightness(90%) !default; | |
$form-check-input-bg: $body-bg !default; | |
$form-check-input-border: 1px solid rgba(0, 0, 0, .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; | |
$form-check-input-focus-box-shadow: $input-btn-focus-box-shadow !default; | |
$form-check-input-checked-color: $component-active-color !default; | |
$form-check-input-checked-bg-color: $component-active-bg !default; | |
$form-check-input-checked-border-color: $form-check-input-checked-bg-color !default; | |
$form-check-input-checked-bg-repeat: no-repeat !default; | |
$form-check-input-checked-bg-position: center center !default; | |
$form-check-input-checked-bg-size: 1em !default; | |
$form-check-input-checked-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='none' stroke='#{$form-check-input-checked-color}' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M4 8.5L6.5 11l6-6'/></svg>") !default; | |
$form-check-radio-checked-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='2' fill='#{$form-check-input-checked-color}'/></svg>") !default; | |
$form-check-input-indeterminate-color: $component-active-color !default; | |
$form-check-input-indeterminate-bg-color: $component-active-bg !default; | |
$form-check-input-indeterminate-border-color: $form-check-input-indeterminate-bg-color !default; | |
$form-check-input-indeterminate-bg-repeat: no-repeat !default; | |
$form-check-input-indeterminate-bg-position: center center !default; | |
$form-check-input-indeterminate-bg-size: 1em !default; | |
$form-check-input-indeterminate-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='none' stroke='#{$form-check-input-indeterminate-color}' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M5 8h6'/></svg>") !default; | |
$form-switch-color: rgba(0, 0, 0, .25) !default; | |
$form-switch-width: 2em !default; | |
$form-switch-padding-left: $form-switch-width + .5em !default; | |
$form-switch-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-switch-color}'/></svg>") !default; | |
$form-switch-bg-size: contain !default; | |
$form-switch-border-radius: $form-switch-width !default; | |
$form-switch-transition: .2s ease-in-out !default; | |
$form-switch-transition-property: background-position, background-color !default; | |
$form-switch-focus-color: hsla(211, 100%, 75%, 1) !default; | |
$form-switch-focus-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-switch-focus-color}'/></svg>") !default; | |
$form-switch-checked-color: $component-active-color !default; | |
$form-switch-checked-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-switch-checked-color}'/></svg>") !default; | |
$form-switch-checked-bg-position: right center !default; | |
$form-text-margin-top: .25rem !default; | |
$form-check-inline-margin-right: 1rem !default; | |
$form-check-input-margin-x: .25rem !default; | |
$form-grid-gutter-width: 10px !default; | |
$input-group-addon-color: $input-color !default; | |
$input-group-addon-bg: $gray-200 !default; | |
$input-group-addon-border-color: $input-border-color !default; | |
$form-select-padding-y: $input-padding-y !default; | |
$form-select-padding-x: $input-padding-x !default; | |
$form-select-font-family: $input-font-family !default; | |
$form-select-font-size: $input-font-size !default; | |
$form-select-height: $input-height !default; | |
$form-select-indicator-padding: 1rem !default; // Extra padding to account for the presence of the background-image based indicator | |
$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-bg: $gray-200 !default; | |
$form-select-disabled-border-color: $input-disabled-border-color !default; | |
$form-select-bg-size: 16px 12px !default; // In pixels because image dimensions | |
$form-select-indicator-color: $gray-800 !default; | |
$form-select-indicator: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='none' stroke='#{$form-select-indicator-color}' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/></svg>") !default; | |
$form-select-background: no-repeat right $form-select-padding-x center / $form-select-bg-size !default; // Used so we can have multiple background elements (e.g., arrow and feedback icon) | |
$form-select-feedback-icon-padding-right: add(1em * .75, (2 * $form-select-padding-y * .75) + $form-select-padding-x + $form-select-indicator-padding) !default; | |
$form-select-feedback-icon-position: center right ($form-select-padding-x + $form-select-indicator-padding) !default; | |
$form-select-feedback-icon-size: $input-height-inner-half $input-height-inner-half !default; | |
$form-select-border-width: $input-border-width !default; | |
$form-select-border-color: $input-border-color !default; | |
$form-select-border-radius: $border-radius !default; | |
$form-select-box-shadow: $box-shadow-inset !default; | |
$form-select-focus-border-color: $input-focus-border-color !default; | |
$form-select-focus-width: $input-focus-width !default; | |
$form-select-focus-box-shadow: 0 0 0 $form-select-focus-width $input-btn-focus-color !default; | |
$form-select-padding-y-sm: $input-padding-y-sm !default; | |
$form-select-padding-x-sm: $input-padding-x-sm !default; | |
$form-select-font-size-sm: $input-font-size-sm !default; | |
$form-select-height-sm: $input-height-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-height-lg: $input-height-lg !default; | |
$form-range-track-width: 100% !default; | |
$form-range-track-height: .5rem !default; | |
$form-range-track-cursor: pointer !default; | |
$form-range-track-bg: $gray-300 !default; | |
$form-range-track-border-radius: 1rem !default; | |
$form-range-track-box-shadow: $box-shadow-inset !default; | |
$form-range-thumb-width: 1rem !default; | |
$form-range-thumb-height: $form-range-thumb-width !default; | |
$form-range-thumb-bg: $component-active-bg !default; | |
$form-range-thumb-border: 0 !default; | |
$form-range-thumb-border-radius: 1rem !default; | |
$form-range-thumb-box-shadow: 0 .1rem .25rem rgba($black, .1) !default; | |
$form-range-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-focus-box-shadow !default; | |
$form-range-thumb-focus-box-shadow-width: $input-focus-width !default; // For focus box shadow issue in IE/Edge | |
$form-range-thumb-active-bg: lighten($component-active-bg, 35%) !default; | |
$form-range-thumb-disabled-bg: $gray-500 !default; | |
$form-range-thumb-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default; | |
$form-file-height: $input-height !default; | |
$form-file-focus-border-color: $input-focus-border-color !default; | |
$form-file-focus-box-shadow: $input-focus-box-shadow !default; | |
$form-file-disabled-bg: $input-disabled-bg !default; | |
$form-file-disabled-border-color: $input-disabled-border-color !default; | |
$form-file-padding-y: $input-padding-y !default; | |
$form-file-padding-x: $input-padding-x !default; | |
$form-file-line-height: $input-line-height !default; | |
$form-file-font-family: $input-font-family !default; | |
$form-file-font-weight: $input-font-weight !default; | |
$form-file-color: $input-color !default; | |
$form-file-bg: $input-bg !default; | |
$form-file-border-width: $input-border-width !default; | |
$form-file-border-color: $input-border-color !default; | |
$form-file-border-radius: $input-border-radius !default; | |
$form-file-box-shadow: $input-box-shadow !default; | |
$form-file-button-color: $form-file-color !default; | |
$form-file-button-bg: $input-group-addon-bg !default; | |
// Form validation | |
$form-feedback-margin-top: $form-text-margin-top !default; | |
$form-feedback-font-size: $small-font-size !default; | |
$form-feedback-valid-color: $success !default; | |
$form-feedback-invalid-color: $danger !default; | |
$form-feedback-icon-valid-color: $form-feedback-valid-color !default; | |
$form-feedback-icon-valid: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'><path fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/></svg>") !default; | |
$form-feedback-icon-invalid-color: $form-feedback-invalid-color !default; | |
$form-feedback-icon-invalid: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='#{$form-feedback-icon-invalid-color}' viewBox='0 0 12 12'><circle cx='6' cy='6' r='4.5'/><path stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/><circle cx='6' cy='8.2' r='.6' fill='#{$form-feedback-icon-invalid-color}' stroke='none'/></svg>") !default; | |
$form-validation-states: () !default; | |
// stylelint-disable-next-line scss/dollar-variable-default | |
$form-validation-states: map-merge( | |
( | |
"valid": ( | |
"color": $form-feedback-valid-color, | |
"icon": $form-feedback-icon-valid | |
), | |
"invalid": ( | |
"color": $form-feedback-invalid-color, | |
"icon": $form-feedback-icon-invalid | |
), | |
), | |
$form-validation-states | |
); | |
// Z-index master list | |
// | |
// Warning: Avoid customizing these values. They're used for a bird's eye view | |
// of components dependent on the z-axis and are designed to all work together. | |
$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; | |
// Navs | |
$nav-link-padding-y: .5rem !default; | |
$nav-link-padding-x: 1rem !default; | |
$nav-link-disabled-color: $gray-600 !default; | |
$nav-tabs-border-color: $gray-300 !default; | |
$nav-tabs-border-width: $border-width !default; | |
$nav-tabs-border-radius: $border-radius !default; | |
$nav-tabs-link-hover-border-color: $gray-200 $gray-200 $nav-tabs-border-color !default; | |
$nav-tabs-link-active-color: $gray-700 !default; | |
$nav-tabs-link-active-bg: $body-bg !default; | |
$nav-tabs-link-active-border-color: $gray-300 $gray-300 $nav-tabs-link-active-bg !default; | |
$nav-pills-border-radius: $border-radius !default; | |
$nav-pills-link-active-color: $component-active-color !default; | |
$nav-pills-link-active-bg: $component-active-bg !default; | |
// Navbar | |
$navbar-padding-y: $spacer / 2 !default; | |
$navbar-padding-x: null !default; | |
$navbar-nav-link-padding-x: .5rem !default; | |
$navbar-brand-font-size: $font-size-lg !default; | |
// Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link | |
$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-margin-right: 1rem !default; | |
$navbar-toggler-padding-y: .25rem !default; | |
$navbar-toggler-padding-x: .75rem !default; | |
$navbar-toggler-font-size: $font-size-lg !default; | |
$navbar-toggler-border-radius: $btn-border-radius !default; | |
$navbar-toggler-focus-width: $btn-focus-width !default; | |
$navbar-toggler-transition: box-shadow .15s ease-in-out !default; | |
$navbar-dark-color: rgba($white, .55) !default; | |
$navbar-dark-hover-color: rgba($white, .75) !default; | |
$navbar-dark-active-color: $white !default; | |
$navbar-dark-disabled-color: rgba($white, .25) !default; | |
$navbar-dark-toggler-icon-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'><path stroke='#{$navbar-dark-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>") !default; | |
$navbar-dark-toggler-border-color: rgba($white, .1) !default; | |
$navbar-light-color: rgba($black, .55) !default; | |
$navbar-light-hover-color: rgba($black, .7) !default; | |
$navbar-light-active-color: rgba($black, .9) !default; | |
$navbar-light-disabled-color: rgba($black, .3) !default; | |
$navbar-light-toggler-icon-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'><path stroke='#{$navbar-light-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>") !default; | |
$navbar-light-toggler-border-color: rgba($black, .1) !default; | |
$navbar-light-brand-color: $navbar-light-active-color !default; | |
$navbar-light-brand-hover-color: $navbar-light-active-color !default; | |
$navbar-dark-brand-color: $navbar-dark-active-color !default; | |
$navbar-dark-brand-hover-color: $navbar-dark-active-color !default; | |
// Dropdowns | |
// | |
// Dropdown menu container and contents. | |
$dropdown-min-width: 10rem !default; | |
$dropdown-padding-y: .5rem !default; | |
$dropdown-spacer: .125rem !default; | |
$dropdown-font-size: $font-size-base !default; | |
$dropdown-color: $body-color !default; | |
$dropdown-bg: $white !default; | |
$dropdown-border-color: rgba($black, .15) !default; | |
$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: $gray-200 !default; | |
$dropdown-divider-margin-y: $spacer / 2 !default; | |
$dropdown-box-shadow: $box-shadow !default; | |
$dropdown-link-color: $gray-900 !default; | |
$dropdown-link-hover-color: darken($gray-900, 5%) !default; | |
$dropdown-link-hover-bg: $gray-100 !default; | |
$dropdown-link-active-color: $component-active-color !default; | |
$dropdown-link-active-bg: $component-active-bg !default; | |
$dropdown-link-disabled-color: $gray-600 !default; | |
$dropdown-item-padding-y: .25rem !default; | |
$dropdown-item-padding-x: 1.5rem !default; | |
$dropdown-header-color: $gray-600 !default; | |
// Pagination | |
$pagination-padding-y: .375rem !default; | |
$pagination-padding-x: .75rem !default; | |
$pagination-padding-y-sm: .25rem !default; | |
$pagination-padding-x-sm: .5rem !default; | |
$pagination-padding-y-lg: .75rem !default; | |
$pagination-padding-x-lg: 1.5rem !default; | |
$pagination-color: $link-color !default; | |
$pagination-bg: $white !default; | |
$pagination-border-width: $border-width !default; | |
$pagination-border-radius: $border-radius !default; | |
$pagination-margin-left: -$pagination-border-width !default; | |
$pagination-border-color: $gray-300 !default; | |
$pagination-focus-box-shadow: $input-btn-focus-box-shadow !default; | |
$pagination-focus-outline: 0 !default; | |
$pagination-hover-color: $link-hover-color !default; | |
$pagination-hover-bg: $gray-200 !default; | |
$pagination-hover-border-color: $gray-300 !default; | |
$pagination-active-color: $component-active-color !default; | |
$pagination-active-bg: $component-active-bg !default; | |
$pagination-active-border-color: $pagination-active-bg !default; | |
$pagination-disabled-color: $gray-600 !default; | |
$pagination-disabled-bg: $white !default; | |
$pagination-disabled-border-color: $gray-300 !default; | |
// Cards | |
$card-spacer-y: 1.25rem !default; | |
$card-spacer-x: 1.25rem !default; | |
$card-title-spacer-y: .75rem !default; | |
$card-border-width: $border-width !default; | |
$card-border-radius: $border-radius !default; | |
$card-border-color: rgba($black, .125) !default; | |
$card-inner-border-radius: subtract($card-border-radius, $card-border-width) !default; | |
$card-cap-padding-y: .75rem !default; | |
$card-cap-padding-x: 1.25rem !default; | |
$card-cap-bg: rgba($black, .03) !default; | |
$card-cap-color: null !default; | |
$card-height: null !default; | |
$card-color: null !default; | |
$card-bg: $white !default; | |
$card-img-overlay-padding: 1.25rem !default; | |
$card-group-margin: $grid-gutter-width / 2 !default; | |
$card-deck-margin: $card-group-margin !default; | |
// Tooltips | |
$tooltip-font-size: $font-size-sm !default; | |
$tooltip-max-width: 200px !default; | |
$tooltip-color: $white !default; | |
$tooltip-bg: $black !default; | |
$tooltip-border-radius: $border-radius !default; | |
$tooltip-opacity: .9 !default; | |
$tooltip-padding-y: .25rem !default; | |
$tooltip-padding-x: .5rem !default; | |
$tooltip-margin: 0 !default; | |
$tooltip-arrow-width: .8rem !default; | |
$tooltip-arrow-height: .4rem !default; | |
$tooltip-arrow-color: $tooltip-bg !default; | |
// Form tooltips must come after regular tooltips | |
$form-feedback-tooltip-padding-y: $tooltip-padding-y !default; | |
$form-feedback-tooltip-padding-x: $tooltip-padding-x !default; | |
$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; | |
// Popovers | |
$popover-font-size: $font-size-sm !default; | |
$popover-bg: $white !default; | |
$popover-max-width: 276px !default; | |
$popover-border-width: $border-width !default; | |
$popover-border-color: rgba($black, .2) !default; | |
$popover-border-radius: $border-radius-lg !default; | |
$popover-inner-border-radius: subtract($popover-border-radius, $popover-border-width) !default; | |
$popover-box-shadow: $box-shadow !default; | |
$popover-header-bg: darken($popover-bg, 3%) !default; | |
$popover-header-color: $headings-color !default; | |
$popover-header-padding-y: .5rem !default; | |
$popover-header-padding-x: .75rem !default; | |
$popover-body-color: $body-color !default; | |
$popover-body-padding-y: $popover-header-padding-y !default; | |
$popover-body-padding-x: $popover-header-padding-x !default; | |
$popover-arrow-width: 1rem !default; | |
$popover-arrow-height: .5rem !default; | |
$popover-arrow-color: $popover-bg !default; | |
$popover-arrow-outer-color: fade-in($popover-border-color, .05) !default; | |
// Toasts | |
$toast-max-width: 350px !default; | |
$toast-padding-x: .75rem !default; | |
$toast-padding-y: .25rem !default; | |
$toast-font-size: .875rem !default; | |
$toast-color: null !default; | |
$toast-background-color: rgba($white, .85) !default; | |
$toast-border-width: 1px !default; | |
$toast-border-color: rgba(0, 0, 0, .1) !default; | |
$toast-border-radius: $border-radius !default; | |
$toast-box-shadow: $box-shadow !default; | |
$toast-header-color: $gray-600 !default; | |
$toast-header-background-color: rgba($white, .85) !default; | |
$toast-header-border-color: rgba(0, 0, 0, .05) !default; | |
// Badges | |
$badge-font-size: .75em !default; | |
$badge-font-weight: $font-weight-bold !default; | |
$badge-color: $white !default; | |
$badge-padding-y: .25em !default; | |
$badge-padding-x: .5em !default; | |
$badge-border-radius: $border-radius !default; | |
// Modals | |
// Padding applied to the modal body | |
$modal-inner-padding: 1rem !default; | |
// Margin between elements in footer, must be lower than or equal to 2 * $modal-inner-padding | |
$modal-footer-margin-between: .5rem !default; | |
$modal-dialog-margin: .5rem !default; | |
$modal-dialog-margin-y-sm-up: 1.75rem !default; | |
$modal-title-line-height: $line-height-base !default; | |
$modal-content-color: null !default; | |
$modal-content-bg: $white !default; | |
$modal-content-border-color: rgba($black, .2) !default; | |
$modal-content-border-width: $border-width !default; | |
$modal-content-border-radius: $border-radius-lg !default; | |
$modal-content-inner-border-radius: subtract($modal-content-border-radius, $modal-content-border-width) !default; | |
$modal-content-box-shadow-xs: $box-shadow-sm !default; | |
$modal-content-box-shadow-sm-up: $box-shadow !default; | |
$modal-backdrop-bg: $black !default; | |
$modal-backdrop-opacity: .5 !default; | |
$modal-header-border-color: $border-color !default; | |
$modal-footer-border-color: $modal-header-border-color !default; | |
$modal-header-border-width: $modal-content-border-width !default; | |
$modal-footer-border-width: $modal-header-border-width !default; | |
$modal-header-padding-y: 1rem !default; | |
$modal-header-padding-x: 1rem !default; | |
$modal-header-padding: $modal-header-padding-y $modal-header-padding-x !default; // Keep this for backwards compatibility | |
$modal-xl: 1140px !default; | |
$modal-lg: 800px !default; | |
$modal-md: 500px !default; | |
$modal-sm: 300px !default; | |
$modal-fade-transform: translate(0, -50px) !default; | |
$modal-show-transform: none !default; | |
$modal-transition: transform .3s ease-out !default; | |
$modal-scale-transform: scale(1.02) !default; | |
// Alerts | |
// | |
// Define alert colors, border radius, and padding. | |
$alert-padding-y: .75rem !default; | |
$alert-padding-x: 1.25rem !default; | |
$alert-margin-bottom: 1rem !default; | |
$alert-border-radius: $border-radius !default; | |
$alert-link-font-weight: $font-weight-bold !default; | |
$alert-border-width: $border-width !default; | |
$alert-bg-level: -10 !default; | |
$alert-border-level: -9 !default; | |
$alert-color-level: 6 !default; | |
// Progress bars | |
$progress-height: 1rem !default; | |
$progress-font-size: $font-size-base * .75 !default; | |
$progress-bg: $gray-200 !default; | |
$progress-border-radius: $border-radius !default; | |
$progress-box-shadow: $box-shadow-inset !default; | |
$progress-bar-color: $white !default; | |
$progress-bar-bg: $primary !default; | |
$progress-bar-animation-timing: 1s linear infinite !default; | |
$progress-bar-transition: width .6s ease !default; | |
// List group | |
$list-group-color: null !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: .75rem !default; | |
$list-group-item-padding-x: 1.25rem !default; | |
$list-group-hover-bg: $gray-100 !default; | |
$list-group-active-color: $component-active-color !default; | |
$list-group-active-bg: $component-active-bg !default; | |
$list-group-active-border-color: $list-group-active-bg !default; | |
$list-group-disabled-color: $gray-600 !default; | |
$list-group-disabled-bg: $list-group-bg !default; | |
$list-group-action-color: $gray-700 !default; | |
$list-group-action-hover-color: $list-group-action-color !default; | |
$list-group-action-active-color: $body-color !default; | |
$list-group-action-active-bg: $gray-200 !default; | |
// Image thumbnails | |
$thumbnail-padding: .25rem !default; | |
$thumbnail-bg: $body-bg !default; | |
$thumbnail-border-width: $border-width !default; | |
$thumbnail-border-color: $gray-300 !default; | |
$thumbnail-border-radius: $border-radius !default; | |
$thumbnail-box-shadow: $box-shadow-sm !default; | |
// Figures | |
$figure-caption-font-size: $small-font-size !default; | |
$figure-caption-color: $gray-600 !default; | |
// Breadcrumbs | |
$breadcrumb-font-size: null !default; | |
$breadcrumb-padding-y: .75rem !default; | |
$breadcrumb-padding-x: 1rem !default; | |
$breadcrumb-item-padding-x: .5rem !default; | |
$breadcrumb-margin-bottom: 1rem !default; | |
$breadcrumb-bg: $gray-200 !default; | |
$breadcrumb-divider-color: $gray-600 !default; | |
$breadcrumb-active-color: $gray-600 !default; | |
$breadcrumb-divider: quote("/") !default; | |
$breadcrumb-border-radius: $border-radius !default; | |
// Carousel | |
$carousel-control-color: $white !default; | |
$carousel-control-width: 15% !default; | |
$carousel-control-opacity: .5 !default; | |
$carousel-control-hover-opacity: .9 !default; | |
$carousel-control-transition: opacity .15s ease !default; | |
$carousel-indicator-width: 30px !default; | |
$carousel-indicator-height: 3px !default; | |
$carousel-indicator-hit-area-height: 10px !default; | |
$carousel-indicator-spacer: 3px !default; | |
$carousel-indicator-opacity: .5 !default; | |
$carousel-indicator-active-bg: $white !default; | |
$carousel-indicator-active-opacity: 1 !default; | |
$carousel-indicator-transition: opacity .6s ease !default; | |
$carousel-caption-width: 70% !default; | |
$carousel-caption-color: $white !default; | |
$carousel-caption-padding-y: 1.25rem !default; | |
$carousel-caption-spacer: 1.25rem !default; | |
$carousel-control-icon-width: 20px !default; | |
$carousel-control-prev-icon-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'><path d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/></svg>") !default; | |
$carousel-control-next-icon-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'><path d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/></svg>") !default; | |
$carousel-transition-duration: .6s !default; | |
$carousel-transition: transform $carousel-transition-duration ease-in-out !default; // Define transform transition first if using multiple transitions (e.g., `transform 2s ease, opacity .5s ease-out`) | |
// Spinners | |
$spinner-width: 2rem !default; | |
$spinner-height: $spinner-width !default; | |
$spinner-border-width: .25em !default; | |
$spinner-animation-speed: .75s !default; | |
$spinner-width-sm: 1rem !default; | |
$spinner-height-sm: $spinner-width-sm !default; | |
$spinner-border-width-sm: .2em !default; | |
// Close | |
$close-font-size: $font-size-base * 1.5 !default; | |
$close-font-weight: $font-weight-bold !default; | |
$close-color: $black !default; | |
$close-text-shadow: 0 1px 0 $white !default; | |
// Code | |
$code-font-size: $small-font-size !default; | |
$code-color: $pink !default; | |
$kbd-padding-y: .2rem !default; | |
$kbd-padding-x: .4rem !default; | |
$kbd-font-size: $code-font-size !default; | |
$kbd-color: $white !default; | |
$kbd-bg: $gray-900 !default; | |
$pre-color: null !default; | |
// Toggles | |
// | |
// Used in conjunction with global variables to enable certain theme features. | |
// Vendor | |
// Deprecate | |
// Helpers | |
// Utilities | |
// Components | |
// Skins | |
// Layout | |
// stylelint-disable property-blacklist, scss/dollar-variable-default | |
// SCSS RFS mixin | |
// | |
// Automated responsive values for font sizes, paddings, margins and much more | |
// | |
// Licensed under MIT (https://github.com/twbs/rfs/blob/master/LICENSE) | |
// Configuration | |
// Base value | |
$rfs-base-value: 1.25rem !default; | |
$rfs-unit: rem !default; | |
@if $rfs-unit != rem and $rfs-unit != px { | |
@error "`#{$rfs-unit}` is not a valid unit for $rfs-unit. Use `px` or `rem`."; | |
} | |
// Breakpoint at where values start decreasing if screen width is smaller | |
$rfs-breakpoint: 1200px !default; | |
$rfs-breakpoint-unit: px !default; | |
@if $rfs-breakpoint-unit != px and $rfs-breakpoint-unit != em and $rfs-breakpoint-unit != rem { | |
@error "`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`."; | |
} | |
// Resize values based on screen height and width | |
$rfs-two-dimensional: false !default; | |
// Factor of decrease | |
$rfs-factor: 10 !default; | |
@if type-of($rfs-factor) != number or $rfs-factor <= 1 { | |
@error "`#{$rfs-factor}` is not a valid $rfs-factor, it must be greater than 1."; | |
} | |
// Mode. Possibilities: "min-media-query", "max-media-query" | |
$rfs-mode: min-media-query !default; | |
// Generate enable or disable classes. Possibilities: false, "enable" or "disable" | |
$rfs-class: false !default; | |
// 1 rem = $rfs-rem-value px | |
$rfs-rem-value: 16 !default; | |
// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14 | |
$rfs-safari-iframe-resize-bug-fix: false !default; | |
// Disable RFS by setting $enable-rfs to false | |
$enable-rfs: true !default; | |
// Cache $rfs-base-value unit | |
$rfs-base-value-unit: unit($rfs-base-value); | |
// 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); | |
} | |
@else if $rfs-base-value-unit == rem { | |
$rfs-base-value: $rfs-base-value / ($rfs-base-value * 0 + 1 / $rfs-rem-value); | |
} | |
// Cache $rfs-breakpoint unit to prevent multiple calls | |
$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); | |
} | |
@else if $rfs-breakpoint-unit-cache == rem or $rfs-breakpoint-unit-cache == "em" { | |
$rfs-breakpoint: $rfs-breakpoint / ($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-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); | |
// Internal mixin used to determine which media query needs to be used | |
@mixin _rfs-media-query { | |
@if $rfs-two-dimensional { | |
@media (#{$rfs-mq-property-width}: #{$rfs-mq-value}), (#{$rfs-mq-property-height}: #{$rfs-mq-value}) { | |
@content; | |
} | |
} | |
@else { | |
@media (#{$rfs-mq-property-width}: #{$rfs-mq-value}) { | |
@content; | |
} | |
} | |
} | |
// Internal mixin that adds disable classes to the selector if needed. | |
@mixin _rfs-rule { | |
@if $rfs-class == disable and $rfs-mode == max-media-query { | |
// Adding an extra class increases specificity, which prevents the media query to override the property | |
&, | |
.disable-rfs &, | |
&.disable-rfs { | |
@content; | |
} | |
} | |
@else if $rfs-class == enable and $rfs-mode == min-media-query { | |
.enable-rfs &, | |
&.enable-rfs { | |
@content; | |
} | |
} | |
@else { | |
@content; | |
} | |
} | |
// Internal mixin that adds enable classes to the selector if needed. | |
@mixin _rfs-media-query-rule { | |
@if $rfs-class == enable { | |
@if $rfs-mode == min-media-query { | |
@content; | |
} | |
@include _rfs-media-query { | |
.enable-rfs &, | |
&.enable-rfs { | |
@content; | |
} | |
} | |
} | |
@else { | |
@if $rfs-class == disable and $rfs-mode == min-media-query { | |
.disable-rfs &, | |
&.disable-rfs { | |
@content; | |
} | |
} | |
@include _rfs-media-query { | |
@content; | |
} | |
} | |
} | |
// Helper function to get the formatted non-responsive value | |
@function rfs-value($values) { | |
// Convert to list | |
$values: if(type-of($values) != list, ($values,), $values); | |
$val: ''; | |
// Loop over each value and calculate value | |
@each $value in $values { | |
@if $value == 0 { | |
$val: $val + ' 0'; | |
} | |
@else { | |
// Cache $value unit | |
$unit: if(type-of($value) == "number", unit($value), false); | |
@if $unit == px { | |
// Convert to rem if needed | |
$val: $val + ' ' + if($rfs-unit == rem, #{$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); | |
} | |
@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 | |
$val: $val + ' ' + $value; | |
} | |
} | |
} | |
// Remove first space | |
@return unquote(str-slice($val, 2)); | |
} | |
// Helper function to get the responsive value calculated by RFS | |
@function rfs-fluid-value($values) { | |
// Convert to list | |
$values: if(type-of($values) != list, ($values,), $values); | |
$val: ''; | |
// Loop over each value and calculate value | |
@each $value in $values { | |
@if $value == 0 { | |
$val: $val + ' 0'; | |
} | |
@else { | |
// Cache $value unit | |
$unit: if(type-of($value) == "number", unit($value), false); | |
// 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 | |
@if not $unit or $unit != px and $unit != rem { | |
$val: $val + ' ' + $value; | |
} | |
@else { | |
// Remove unit from $value for calculations | |
$value: $value / ($value * 0 + if($unit == px, 1, 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); | |
} | |
@else { | |
// Calculate the minimum value | |
$value-min: $rfs-base-value + (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); | |
// Use negative value if needed | |
$min-width: if($value < 0, -$min-width, $min-width); | |
// Use `vmin` if two-dimensional is enabled | |
$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}; | |
// Return the calculated value | |
$val: $val + ' calc(' + $min-width + if($value < 0, ' - ', ' + ') + $variable-width + ')'; | |
} | |
} | |
} | |
} | |
// Remove first space | |
@return unquote(str-slice($val, 2)); | |
} | |
// RFS mixin | |
@mixin rfs($values, $property: font-size) { | |
@if $values != null { | |
$val: rfs-value($values); | |
$fluidVal: rfs-fluid-value($values); | |
// Do not print the media query if responsive & non-responsive values are the same | |
@if $val == $fluidVal { | |
#{$property}: $val; | |
} | |
@else { | |
@include _rfs-rule { | |
#{$property}: if($rfs-mode == max-media-query, $val, $fluidVal); | |
// Include safari iframe resize fix if needed | |
min-width: if($rfs-safari-iframe-resize-bug-fix, (0 * 1vw), null); | |
} | |
@include _rfs-media-query-rule { | |
#{$property}: if($rfs-mode == max-media-query, $fluidVal, $val); | |
} | |
} | |
} | |
} | |
// Shorthand helper mixins | |
@mixin font-size($value) { | |
@include rfs($value); | |
} | |
@mixin padding($value) { | |
@include rfs($value, padding); | |
} | |
@mixin padding-top($value) { | |
@include rfs($value, padding-top); | |
} | |
@mixin padding-right($value) { | |
@include rfs($value, padding-right); | |
} | |
@mixin padding-bottom($value) { | |
@include rfs($value, padding-bottom); | |
} | |
@mixin padding-left($value) { | |
@include rfs($value, padding-left); | |
} | |
@mixin margin($value) { | |
@include rfs($value, margin); | |
} | |
@mixin margin-top($value) { | |
@include rfs($value, margin-top); | |
} | |
@mixin margin-right($value) { | |
@include rfs($value, margin-right); | |
} | |
@mixin margin-bottom($value) { | |
@include rfs($value, margin-bottom); | |
} | |
@mixin margin-left($value) { | |
@include rfs($value, margin-left); | |
} | |
// Deprecate mixin | |
// | |
// This mixin can be used to deprecate mixins or functions. | |
// `$enable-deprecation-messages` is a global variable, `$ignore-warning` is a variable that can be passed to | |
// some deprecated mixins to suppress the warning (for example if the mixin is still be used in the current version of Bootstrap) | |
@mixin deprecate($name, $deprecate-version, $remove-version, $ignore-warning: false) { | |
@if ($enable-deprecation-messages != false and $ignore-warning != true) { | |
@warn "#{$name} has been deprecated as of #{$deprecate-version}. It will be removed entirely in #{$remove-version}."; | |
} | |
} | |
// Breakpoint viewport sizes and media queries. | |
// | |
// Breakpoints are defined as a map of (name: minimum width), order from small to large: | |
// | |
// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px) | |
// | |
// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default. | |
// Name of the next breakpoint, or null for the last breakpoint. | |
// | |
// >> breakpoint-next(sm) | |
// md | |
// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)) | |
// md | |
// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl)) | |
// md | |
@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) { | |
$n: index($breakpoint-names, $name); | |
@if not $n { | |
@error "breakpoint `#{$name}` not found in `#{$breakpoints}`"; | |
} | |
@return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null); | |
} | |
// Minimum breakpoint width. Null for the smallest (first) breakpoint. | |
// | |
// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)) | |
// 576px | |
@function breakpoint-min($name, $breakpoints: $grid-breakpoints) { | |
$min: map-get($breakpoints, $name); | |
@return if($min != 0, $min, null); | |
} | |
// Maximum breakpoint width. Null for the largest (last) breakpoint. | |
// The maximum value is calculated as the minimum of the next one less 0.02px | |
// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths. | |
// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max | |
// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari. | |
// See https://bugs.webkit.org/show_bug.cgi?id=178261 | |
// | |
// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)) | |
// 767.98px | |
@function breakpoint-max($name, $breakpoints: $grid-breakpoints) { | |
$next: breakpoint-next($name, $breakpoints); | |
@return if($next, breakpoint-min($next, $breakpoints) - .02, null); | |
} | |
// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front. | |
// Useful for making responsive utilities. | |
// | |
// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)) | |
// "" (Returns a blank string) | |
// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)) | |
// "-sm" | |
@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) { | |
@return if(breakpoint-min($name, $breakpoints) == null, "", "-#{$name}"); | |
} | |
// Media of at least the minimum breakpoint width. No query for the smallest breakpoint. | |
// Makes the @content apply to the given breakpoint and wider. | |
@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) { | |
$min: breakpoint-min($name, $breakpoints); | |
@if $min { | |
@media (min-width: $min) { | |
@content; | |
} | |
} @else { | |
@content; | |
} | |
} | |
// Media of at most the maximum breakpoint width. No query for the largest breakpoint. | |
// Makes the @content apply to the given breakpoint and narrower. | |
@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) { | |
$max: breakpoint-max($name, $breakpoints); | |
@if $max { | |
@media (max-width: $max) { | |
@content; | |
} | |
} @else { | |
@content; | |
} | |
} | |
// Media that spans multiple breakpoint widths. | |
// Makes the @content apply between the min and max breakpoints | |
@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) { | |
$min: breakpoint-min($lower, $breakpoints); | |
$max: breakpoint-max($upper, $breakpoints); | |
@if $min != null and $max != null { | |
@media (min-width: $min) and (max-width: $max) { | |
@content; | |
} | |
} @else if $max == null { | |
@include media-breakpoint-up($lower, $breakpoints) { | |
@content; | |
} | |
} @else if $min == null { | |
@include media-breakpoint-down($upper, $breakpoints) { | |
@content; | |
} | |
} | |
} | |
// Media between the breakpoint's minimum and maximum widths. | |
// No minimum for the smallest breakpoint, and no maximum for the largest one. | |
// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower. | |
@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) { | |
$min: breakpoint-min($name, $breakpoints); | |
$max: breakpoint-max($name, $breakpoints); | |
@if $min != null and $max != null { | |
@media (min-width: $min) and (max-width: $max) { | |
@content; | |
} | |
} @else if $max == null { | |
@include media-breakpoint-up($name, $breakpoints) { | |
@content; | |
} | |
} @else if $min == null { | |
@include media-breakpoint-down($name, $breakpoints) { | |
@content; | |
} | |
} | |
} | |
// Image Mixins | |
// - Responsive image | |
// - Retina image | |
// Responsive image | |
// | |
// Keep images from scaling beyond the width of their parents. | |
@mixin img-fluid { | |
// Part 1: Set a maximum relative to the parent | |
max-width: 100%; | |
// Part 2: Override the height to auto, otherwise images will be stretched | |
// when setting a width and height attribute on the img element. | |
height: auto; | |
} | |
// Resize anything | |
@mixin resizable($direction) { | |
overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible` | |
resize: $direction; // Options: horizontal, vertical, both | |
} | |
// stylelint-disable declaration-no-important | |
// Only display content to screen readers | |
// | |
// See: https://a11yproject.com/posts/how-to-hide-content/ | |
// See: https://hugogiraudel.com/2016/10/13/css-hide-and-seek/ | |
@mixin sr-only { | |
position: absolute !important; | |
width: 1px !important; | |
height: 1px !important; | |
padding: 0 !important; | |
margin: -1px !important; // Fix for https://github.com/twbs/bootstrap/issues/25686 | |
overflow: hidden !important; | |
clip: rect(0, 0, 0, 0) !important; | |
white-space: nowrap !important; | |
border: 0 !important; | |
} | |
// Use to only display content when it's focused. | |
// | |
// Useful for "Skip to main content" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 | |
@mixin sr-only-focusable { | |
&:not(:focus) { | |
@include sr-only(); | |
} | |
} | |
@mixin reset-text { | |
font-family: $font-family-base; | |
// We deliberately do NOT reset font-size or overflow-wrap / word-wrap. | |
font-style: normal; | |
font-weight: $font-weight-normal; | |
line-height: $line-height-base; | |
text-align: left; // Fallback for where `start` is not supported | |
text-align: start; | |
text-decoration: none; | |
text-shadow: none; | |
text-transform: none; | |
letter-spacing: normal; | |
word-break: normal; | |
word-spacing: normal; | |
white-space: normal; | |
line-break: auto; | |
} | |
// Text truncate | |
// Requires inline-block or block for proper styling | |
@mixin text-truncate() { | |
overflow: hidden; | |
text-overflow: ellipsis; | |
white-space: nowrap; | |
} | |
// Utility generator | |
// Used to generate utilities & print utilities | |
@mixin generate-utility($utility, $infix) { | |
$values: map-get($utility, values); | |
// If the values are a list or string, convert it into a map | |
@if type-of($values) == "string" or type-of(nth($values, 1)) != "list" { | |
$values: zip($values, $values); | |
} | |
@each $key, $value in $values { | |
$properties: map-get($utility, property); | |
// Multiple properties are possible, for example with vertical or horizontal margins or paddings | |
@if type-of($properties) == "string" { | |
$properties: append((), $properties); | |
} | |
// Use custom class if present | |
$property-class: if(map-has-key($utility, class), map-get($utility, class), nth($properties, 1)); | |
$property-class: if($property-class == null, "", $property-class); | |
$infix: if($property-class == "" and str-slice($infix, 1, 1) == "-", str-slice($infix, 2), $infix); | |
// Don't prefix if value key is null (eg. with shadow class) | |
$property-class-modifier: if($key, if($property-class == "" and $infix == "", "", "-") + $key, ""); | |
.#{$property-class + $infix + $property-class-modifier} { | |
@each $property in $properties { | |
// stylelint-disable-next-line declaration-no-important | |
#{$property}: $value if($enable-important-utilities, !important, null); | |
} | |
} | |
} | |
} | |
@mixin alert-variant($background, $border, $color) { | |
color: $color; | |
@include gradient-bg($background); | |
border-color: $border; | |
.alert-link { | |
color: darken($color, 10%); | |
} | |
} | |
// Button variants | |
// | |
// Easily pump out default styles, as well as :hover, :focus, :active, | |
// and disabled options for all buttons | |
@mixin button-variant( | |
$background, | |
$border, | |
$color: color-yiq($background), | |
$hover-background: darken($background, 7.5%), | |
$hover-border: darken($border, 10%), | |
$hover-color: color-yiq($hover-background), | |
$active-background: darken($background, 10%), | |
$active-border: darken($border, 12.5%), | |
$active-color: color-yiq($active-background) | |
) { | |
color: $color; | |
@include gradient-bg($background); | |
border-color: $border; | |
@include box-shadow($btn-box-shadow); | |
&:hover { | |
color: $hover-color; | |
@include gradient-bg($hover-background); | |
border-color: $hover-border; | |
} | |
&:focus, | |
&.focus { | |
color: $hover-color; | |
@include gradient-bg($hover-background); | |
border-color: $hover-border; | |
// Avoid using mixin so we can pass custom focus shadow properly | |
@if $enable-shadows { | |
box-shadow: $btn-box-shadow, 0 0 0 $btn-focus-width rgba(mix($color, $border, 15%), .5); | |
} @else { | |
box-shadow: 0 0 0 $btn-focus-width rgba(mix($color, $border, 15%), .5); | |
} | |
} | |
&:active, | |
&.active, | |
.show > &.dropdown-toggle { | |
color: $active-color; | |
background-color: $active-background; | |
@if $enable-gradients { | |
background-image: none; // Remove the gradient for the pressed/active state | |
} | |
border-color: $active-border; | |
&:focus { | |
// Avoid using mixin so we can pass custom focus shadow properly | |
@if $enable-shadows and $btn-active-box-shadow != none { | |
box-shadow: $btn-active-box-shadow, 0 0 0 $btn-focus-width rgba(mix($color, $border, 15%), .5); | |
} @else { | |
box-shadow: 0 0 0 $btn-focus-width rgba(mix($color, $border, 15%), .5); | |
} | |
} | |
} | |
&:disabled, | |
&.disabled { | |
color: $color; | |
background-color: $background; | |
border-color: $border; | |
// Remove CSS gradients if they're enabled | |
@if $enable-gradients { | |
background-image: none; | |
} | |
} | |
} | |
@mixin button-outline-variant( | |
$color, | |
$color-hover: color-yiq($color), | |
$active-background: $color, | |
$active-border: $color, | |
$active-color: color-yiq($active-background) | |
) { | |
color: $color; | |
border-color: $color; | |
&:hover { | |
color: $color-hover; | |
background-color: $active-background; | |
border-color: $active-border; | |
} | |
&:focus, | |
&.focus { | |
box-shadow: 0 0 0 $btn-focus-width rgba($color, .5); | |
} | |
&:active, | |
&.active, | |
.show > &.dropdown-toggle { | |
color: $active-color; | |
background-color: $active-background; | |
border-color: $active-border; | |
&:focus { | |
// Avoid using mixin so we can pass custom focus shadow properly | |
@if $enable-shadows and $btn-active-box-shadow != none { | |
box-shadow: $btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($color, .5); | |
} @else { | |
box-shadow: 0 0 0 $btn-focus-width rgba($color, .5); | |
} | |
} | |
} | |
&:disabled, | |
&.disabled { | |
color: $color; | |
background-color: transparent; | |
} | |
} | |
// Button sizes | |
@mixin button-size($padding-y, $padding-x, $font-size, $border-radius) { | |
padding: $padding-y $padding-x; | |
@include font-size($font-size); | |
// Manually declare to provide an override to the browser default | |
@include border-radius($border-radius, 0); | |
} | |
@mixin caret-down { | |
border-top: $caret-width solid; | |
border-right: $caret-width solid transparent; | |
border-bottom: 0; | |
border-left: $caret-width solid transparent; | |
} | |
@mixin caret-up { | |
border-top: 0; | |
border-right: $caret-width solid transparent; | |
border-bottom: $caret-width solid; | |
border-left: $caret-width solid transparent; | |
} | |
@mixin caret-right { | |
border-top: $caret-width solid transparent; | |
border-right: 0; | |
border-bottom: $caret-width solid transparent; | |
border-left: $caret-width solid; | |
} | |
@mixin caret-left { | |
border-top: $caret-width solid transparent; | |
border-right: $caret-width solid; | |
border-bottom: $caret-width solid transparent; | |
} | |
@mixin caret($direction: down) { | |
@if $enable-caret { | |
&::after { | |
display: inline-block; | |
margin-left: $caret-spacing; | |
vertical-align: $caret-vertical-align; | |
content: ""; | |
@if $direction == down { | |
@include caret-down(); | |
} @else if $direction == up { | |
@include caret-up(); | |
} @else if $direction == right { | |
@include caret-right(); | |
} | |
} | |
@if $direction == left { | |
&::after { | |
display: none; | |
} | |
&::before { | |
display: inline-block; | |
margin-right: $caret-spacing; | |
vertical-align: $caret-vertical-align; | |
content: ""; | |
@include caret-left(); | |
} | |
} | |
&:empty::after { | |
margin-left: 0; | |
} | |
} | |
} | |
// Pagination | |
@mixin pagination-size($padding-y, $padding-x, $font-size, $border-radius) { | |
.page-link { | |
padding: $padding-y $padding-x; | |
@include font-size($font-size); | |
} | |
.page-item { | |
@if $pagination-margin-left == (-$pagination-border-width) { | |
&:first-child { | |
.page-link { | |
@include border-left-radius($border-radius); | |
} | |
} | |
&:last-child { | |
.page-link { | |
@include border-right-radius($border-radius); | |
} | |
} | |
} @else { | |
//Add border-radius to all pageLinks in case they have left margin | |
.page-link { | |
@include border-radius($border-radius); | |
} | |
} | |
} | |
} | |
// Lists | |
// Unstyled keeps list items block level, just removes default browser padding and list-style | |
@mixin list-unstyled { | |
padding-left: 0; | |
list-style: none; | |
} | |
// List Groups | |
@mixin list-group-item-variant($state, $background, $color) { | |
.list-group-item-#{$state} { | |
color: $color; | |
background-color: $background; | |
&.list-group-item-action { | |
&:hover, | |
&:focus { | |
color: $color; | |
background-color: darken($background, 5%); | |
} | |
&.active { | |
color: $white; | |
background-color: $color; | |
border-color: $color; | |
} | |
} | |
} | |
} | |
// 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 | |
@mixin form-validation-state-selector($state) { | |
@if ($state == "valid" or $state == "invalid") { | |
.was-validated #{if(&, "&", "")}:#{$state}, | |
#{if(&, "&", "")}.is-#{$state} { | |
@content; | |
} | |
} @else { | |
#{if(&, "&", "")}.is-#{$state} { | |
@content; | |
} | |
} | |
} | |
@mixin form-validation-state($state, $color, $icon) { | |
.#{$state}-feedback { | |
display: none; | |
width: 100%; | |
margin-top: $form-feedback-margin-top; | |
@include font-size($form-feedback-font-size); | |
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: color-yiq($color); | |
background-color: rgba($color, $form-feedback-tooltip-opacity); | |
@include border-radius($form-feedback-tooltip-border-radius); | |
} | |
@include form-validation-state-selector($state) { | |
~ .#{$state}-feedback, | |
~ .#{$state}-tooltip { | |
display: block; | |
} | |
} | |
.form-control { | |
@include form-validation-state-selector($state) { | |
border-color: $color; | |
@if $enable-validation-icons { | |
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: $color; | |
box-shadow: 0 0 0 $input-focus-width rgba($color, .25); | |
} | |
} | |
} | |
// 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: $color; | |
@if $enable-validation-icons { | |
padding-right: $form-select-feedback-icon-padding-right; | |
background: escape-svg($form-select-indicator) $form-select-background, escape-svg($icon) $form-select-bg no-repeat $form-select-feedback-icon-position / $form-select-feedback-icon-size; | |
} | |
&:focus { | |
border-color: $color; | |
box-shadow: 0 0 0 $input-focus-width rgba($color, .25); | |
} | |
} | |
} | |
.form-check-input { | |
@include form-validation-state-selector($state) { | |
border-color: $color; | |
&:checked { | |
@include gradient-bg(lighten($color, 10%), escape-svg($form-check-input-checked-bg-image)); | |
} | |
&:focus { | |
box-shadow: 0 0 0 $input-focus-width rgba($color, .25); | |
} | |
~ .form-check-label { | |
color: $color; | |
} | |
} | |
} | |
.form-check-inline .form-check-input { | |
~ .#{$state}-feedback { | |
margin-left: .5em; | |
} | |
} | |
// custom file | |
.form-file-input { | |
@include form-validation-state-selector($state) { | |
~ .form-file-label { | |
border-color: $color; | |
} | |
&:focus { | |
~ .form-file-label { | |
border-color: $color; | |
box-shadow: 0 0 0 $input-focus-width rgba($color, .25); | |
} | |
} | |
} | |
} | |
} | |
// Tables | |
@mixin table-row-variant($state, $background, $border: null) { | |
// Exact selectors below required to override `.table-striped` and prevent | |
// inheritance to nested tables. | |
.table-#{$state} { | |
&, | |
> th, | |
> td { | |
background-color: $background; | |
} | |
@if $border != null { | |
th, | |
td, | |
thead th, | |
tbody + tbody { | |
border-color: $border; | |
} | |
} | |
} | |
// Hover states for `.table-hover` | |
// Note: this is not available for cells or rows within `thead` or `tfoot`. | |
.table-hover { | |
$hover-background: darken($background, 5%); | |
.table-#{$state} { | |
&:hover { | |
background-color: $hover-background; | |
> td, | |
> th { | |
background-color: $hover-background; | |
} | |
} | |
} | |
} | |
} | |
// stylelint-disable declaration-no-important | |
@mixin bg-gradient-variant($parent, $color) { | |
#{$parent} { | |
background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x !important; | |
} | |
} | |
// stylelint-disable property-blacklist | |
// Single side border-radius | |
@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) { | |
@if $enable-rounded { | |
border-radius: $radius; | |
} | |
@else if $fallback-border-radius != false { | |
border-radius: $fallback-border-radius; | |
} | |
} | |
@mixin border-top-radius($radius) { | |
@if $enable-rounded { | |
border-top-left-radius: $radius; | |
border-top-right-radius: $radius; | |
} | |
} | |
@mixin border-right-radius($radius) { | |
@if $enable-rounded { | |
border-top-right-radius: $radius; | |
border-bottom-right-radius: $radius; | |
} | |
} | |
@mixin border-bottom-radius($radius) { | |
@if $enable-rounded { | |
border-bottom-right-radius: $radius; | |
border-bottom-left-radius: $radius; | |
} | |
} | |
@mixin border-left-radius($radius) { | |
@if $enable-rounded { | |
border-top-left-radius: $radius; | |
border-bottom-left-radius: $radius; | |
} | |
} | |
@mixin border-top-left-radius($radius) { | |
@if $enable-rounded { | |
border-top-left-radius: $radius; | |
} | |
} | |
@mixin border-top-right-radius($radius) { | |
@if $enable-rounded { | |
border-top-right-radius: $radius; | |
} | |
} | |
@mixin border-bottom-right-radius($radius) { | |
@if $enable-rounded { | |
border-bottom-right-radius: $radius; | |
} | |
} | |
@mixin border-bottom-left-radius($radius) { | |
@if $enable-rounded { | |
border-bottom-left-radius: $radius; | |
} | |
} | |
@mixin box-shadow($shadow...) { | |
@if $enable-shadows { | |
$result: (); | |
@if (length($shadow) == 1) { | |
// We can pass `@include box-shadow(none);` | |
$result: $shadow; | |
} @else { | |
// Filter to avoid invalid properties for example `box-shadow: none, 1px 1px black;` | |
@for $i from 1 through length($shadow) { | |
@if nth($shadow, $i) != "none" { | |
$result: append($result, nth($shadow, $i), "comma"); | |
} | |
} | |
} | |
@if (length($result) > 0) { | |
box-shadow: $result; | |
} | |
} | |
} | |
// Gradients | |
@mixin gradient-bg($color, $foreground: null) { | |
@if $enable-gradients { | |
@if $foreground { | |
background-color: $color; | |
background-image: $foreground, linear-gradient(180deg, mix($body-bg, $color, 15%), $color); | |
background-repeat: no-repeat; | |
background-size: 1em, auto; | |
} @else { | |
background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x; | |
} | |
} @else { | |
background-color: $color; | |
} | |
} | |
// Horizontal gradient, from left to right | |
// | |
// Creates two color stops, start and end, by specifying a color and position for each color stop. | |
@mixin gradient-x($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) { | |
background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent); | |
background-repeat: repeat-x; | |
} | |
// Vertical gradient, from top to bottom | |
// | |
// Creates two color stops, start and end, by specifying a color and position for each color stop. | |
@mixin gradient-y($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) { | |
background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent); | |
background-repeat: repeat-x; | |
} | |
@mixin gradient-directional($start-color: $gray-700, $end-color: $gray-800, $deg: 45deg) { | |
background-image: linear-gradient($deg, $start-color, $end-color); | |
background-repeat: repeat-x; | |
} | |
@mixin gradient-x-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) { | |
background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color); | |
background-repeat: no-repeat; | |
} | |
@mixin gradient-y-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) { | |
background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color); | |
background-repeat: no-repeat; | |
} | |
@mixin gradient-radial($inner-color: $gray-700, $outer-color: $gray-800) { | |
background-image: radial-gradient(circle, $inner-color, $outer-color); | |
background-repeat: no-repeat; | |
} | |
@mixin gradient-striped($color: rgba($white, .15), $angle: 45deg) { | |
background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent); | |
} | |
// stylelint-disable property-blacklist | |
@mixin transition($transition...) { | |
@if $enable-transitions { | |
@if length($transition) == 0 { | |
transition: $transition-base; | |
} @else { | |
transition: $transition; | |
} | |
} | |
@if $enable-prefers-reduced-motion-media-query { | |
@media (prefers-reduced-motion: reduce) { | |
transition: none; | |
} | |
} | |
} | |
@mixin clearfix() { | |
&::after { | |
display: block; | |
clear: both; | |
content: ""; | |
} | |
} | |
// Container mixins | |
@mixin make-container($padding-x: $container-padding-x) { | |
width: 100%; | |
padding-right: $padding-x; | |
padding-left: $padding-x; | |
margin-right: auto; | |
margin-left: auto; | |
} | |
// For each breakpoint, define the maximum width of the container in a media query | |
@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) { | |
@each $breakpoint, $container-max-width in $max-widths { | |
@include media-breakpoint-up($breakpoint, $breakpoints) { | |
max-width: $container-max-width; | |
} | |
} | |
} | |
/// Grid system | |
// | |
// Generate semantic grid columns with these mixins. | |
@mixin make-row($gutter: $grid-gutter-width) { | |
display: flex; | |
flex-wrap: wrap; | |
margin-right: -$gutter / 2; | |
margin-left: -$gutter / 2; | |
} | |
@mixin make-col-ready($gutter: $grid-gutter-width) { | |
position: relative; | |
// Prevent columns from becoming too narrow when at smaller grid tiers by | |
// always setting `width: 100%;`. This works because we use `flex` values | |
// later on to override this initial width. | |
width: 100%; | |
padding-right: $gutter / 2; | |
padding-left: $gutter / 2; | |
} | |
@mixin make-col($size, $columns: $grid-columns) { | |
flex: 0 0 percentage($size / $columns); | |
// Add a `max-width` to ensure content within each column does not blow out | |
// the width of the column. Applies to IE10+ and Firefox. Chrome and Safari | |
// do not appear to require this. | |
max-width: percentage($size / $columns); | |
} | |
@mixin make-col-auto() { | |
flex: 0 0 auto; | |
width: auto; | |
max-width: 100%; // Reset earlier grid tiers | |
} | |
@mixin make-col-offset($size, $columns: $grid-columns) { | |
$num: $size / $columns; | |
margin-left: if($num == 0, 0, percentage($num)); | |
} | |
// Row columns | |
// | |
// Specify on a parent element(e.g., .row) to force immediate children into NN | |
// numberof columns. Supports wrapping to new lines, but does not do a Masonry | |
// style grid. | |
@mixin row-cols($count) { | |
& > * { | |
flex: 0 0 100% / $count; | |
max-width: 100% / $count; | |
} | |
} | |
// Framework grid generation | |
// | |
// Used only by Bootstrap to generate the correct number of grid classes given | |
// any value of `$grid-columns`. | |
@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) { | |
// Common properties for all breakpoints | |
%grid-column { | |
position: relative; | |
width: 100%; | |
padding-right: $gutter / 2; | |
padding-left: $gutter / 2; | |
} | |
@each $breakpoint in map-keys($breakpoints) { | |
$infix: breakpoint-infix($breakpoint, $breakpoints); | |
// Allow columns to stretch full width below their breakpoints | |
@for $i from 1 through $columns { | |
.col#{$infix}-#{$i} { | |
@extend %grid-column; | |
} | |
} | |
.col#{$infix}, | |
.col#{$infix}-auto { | |
@extend %grid-column; | |
} | |
@include media-breakpoint-up($breakpoint, $breakpoints) { | |
// Provide basic `.col-{bp}` classes for equal-width flexbox columns | |
.col#{$infix} { | |
flex-basis: 0; | |
flex-grow: 1; | |
min-width: 0; // See https://github.com/twbs/bootstrap/issues/25410 | |
max-width: 100%; | |
} | |
@for $i from 1 through $grid-row-columns { | |
.row-cols#{$infix}-#{$i} { | |
@include row-cols($i); | |
} | |
} | |
.col#{$infix}-auto { | |
@include make-col-auto(); | |
} | |
@for $i from 1 through $columns { | |
.col#{$infix}-#{$i} { | |
@include make-col($i, $columns); | |
} | |
} | |
// `$columns - 1` because offsetting by the width of an entire row isn't possible | |
@for $i from 0 through ($columns - 1) { | |
@if not ($infix == "" and $i == 0) { // Avoid emitting useless .offset-0 | |
.offset#{$infix}-#{$i} { | |
@include make-col-offset($i, $columns); | |
} | |
} | |
} | |
} | |
} | |
} | |
// Utilities | |
$utilities: () !default; | |
// stylelint-disable-next-line scss/dollar-variable-default | |
$utilities: map-merge( | |
( | |
"align": ( | |
property: vertical-align, | |
class: align, | |
values: baseline top middle bottom text-bottom text-top | |
), | |
"float": ( | |
responsive: true, | |
property: float, | |
values: left right none | |
), | |
"overflow": ( | |
property: overflow, | |
values: auto hidden, | |
), | |
"display": ( | |
responsive: true, | |
print: true, | |
property: display, | |
class: d, | |
values: none inline inline-block block table table-row table-cell flex inline-flex | |
), | |
"shadow": ( | |
property: box-shadow, | |
class: shadow, | |
values: ( | |
sm: $box-shadow-sm, | |
null: $box-shadow, | |
lg: $box-shadow-lg, | |
none: none, | |
) | |
), | |
"position": ( | |
property: position, | |
values: static relative absolute fixed sticky | |
), | |
"border": ( | |
property: border, | |
values: ( | |
null: $border-width solid $border-color, | |
0: 0, | |
) | |
), | |
"border-top": ( | |
property: border-top, | |
values: ( | |
null: $border-width solid $border-color, | |
0: 0, | |
) | |
), | |
"border-right": ( | |
property: border-right, | |
values: ( | |
null: $border-width solid $border-color, | |
0: 0, | |
) | |
), | |
"border-bottom": ( | |
property: border-bottom, | |
values: ( | |
null: $border-width solid $border-color, | |
0: 0, | |
) | |
), | |
"border-left": ( | |
property: border-left, | |
values: ( | |
null: $border-width solid $border-color, | |
0: 0, | |
) | |
), | |
"border-color": ( | |
property: border-color, | |
class: border, | |
values: map-merge($theme-colors, ("white": $white)) | |
), | |
// Sizing utilities | |
"width": ( | |
property: width, | |
class: w, | |
values: ( | |
25: 25%, | |
50: 50%, | |
75: 75%, | |
100: 100%, | |
auto: auto | |
) | |
), | |
"max-width": ( | |
property: max-width, | |
class: mw, | |
values: (100: 100%) | |
), | |
"viewport-width": ( | |
property: width, | |
class: vw, | |
values: (100: 100vw) | |
), | |
"min-viewport-width": ( | |
property: min-width, | |
class: min-vw, | |
values: (100: 100vw) | |
), | |
"height": ( | |
property: height, | |
class: h, | |
values: ( | |
25: 25%, | |
50: 50%, | |
75: 75%, | |
100: 100%, | |
auto: auto | |
) | |
), | |
"max-height": ( | |
property: max-height, | |
class: mh, | |
values: (100: 100%) | |
), | |
"viewport-height": ( | |
property: height, | |
class: vh, | |
values: (100: 100vh) | |
), | |
"min-viewport-height": ( | |
property: min-height, | |
class: min-vh, | |
values: (100: 100vh) | |
), | |
// Flex utilities | |
"flex": ( | |
responsive: true, | |
property: flex, | |
values: (fill: 1 1 auto) | |
), | |
"flex-direction": ( | |
responsive: true, | |
property: flex-direction, | |
class: flex, | |
values: row column row-reverse column-reverse | |
), | |
"flex-grow": ( | |
responsive: true, | |
property: flex-grow, | |
class: flex, | |
values: ( | |
grow-0: 0, | |
grow-1: 1, | |
) | |
), | |
"flex-shrink": ( | |
responsive: true, | |
property: flex-shrink, | |
class: flex, | |
values: ( | |
shrink-0: 0, | |
shrink-1: 1, | |
) | |
), | |
"flex-wrap": ( | |
responsive: true, | |
property: flex-wrap, | |
class: flex, | |
values: wrap nowrap wrap-reverse | |
), | |
"justify-content": ( | |
responsive: true, | |
property: justify-content, | |
values: ( | |
start: flex-start, | |
end: flex-end, | |
center: center, | |
between: space-between, | |
around: space-around, | |
) | |
), | |
"align-items": ( | |
responsive: true, | |
property: align-items, | |
values: ( | |
start: flex-start, | |
end: flex-end, | |
center: center, | |
baseline: baseline, | |
stretch: stretch, | |
) | |
), | |
"align-content": ( | |
responsive: true, | |
property: align-content, | |
values: ( | |
start: flex-start, | |
end: flex-end, | |
center: center, | |
between: space-between, | |
around: space-around, | |
stretch: stretch, | |
) | |
), | |
"align-self": ( | |
responsive: true, | |
property: align-self, | |
values: ( | |
auto: auto, | |
start: flex-start, | |
end: flex-end, | |
center: center, | |
baseline: baseline, | |
stretch: stretch, | |
) | |
), | |
"order": ( | |
responsive: true, | |
property: order, | |
values: ( | |
first: -1, | |
0: 0, | |
1: 1, | |
2: 2, | |
3: 3, | |
4: 4, | |
5: 5, | |
last: 6, | |
), | |
), | |
// Margin utilities | |
"margin": ( | |
responsive: true, | |
property: margin, | |
class: m, | |
values: map-merge($spacers, (auto: auto)) | |
), | |
"margin-x": ( | |
responsive: true, | |
property: margin-right margin-left, | |
class: mx, | |
values: map-merge($spacers, (auto: auto)) | |
), | |
"margin-y": ( | |
responsive: true, | |
property: margin-top margin-bottom, | |
class: my, | |
values: map-merge($spacers, (auto: auto)) | |
), | |
"margin-top": ( | |
responsive: true, | |
property: margin-top, | |
class: mt, | |
values: map-merge($spacers, (auto: auto)) | |
), | |
"margin-right": ( | |
responsive: true, | |
property: margin-right, | |
class: mr, | |
values: map-merge($spacers, (auto: auto)) | |
), | |
"margin-bottom": ( | |
responsive: true, | |
property: margin-bottom, | |
class: mb, | |
values: map-merge($spacers, (auto: auto)) | |
), | |
"margin-left": ( | |
responsive: true, | |
property: margin-left, | |
class: ml, | |
values: map-merge($spacers, (auto: auto)) | |
), | |
// Negative margin utilities | |
"negative-margin": ( | |
responsive: true, | |
property: margin, | |
class: m, | |
values: $negative-spacers | |
), | |
"negative-margin-x": ( | |
responsive: true, | |
property: margin-right margin-left, | |
class: mx, | |
values: $negative-spacers | |
), | |
"negative-margin-y": ( | |
responsive: true, | |
property: margin-top margin-bottom, | |
class: my, | |
values: $negative-spacers | |
), | |
"negative-margin-top": ( | |
responsive: true, | |
property: margin-top, | |
class: mt, | |
values: $negative-spacers | |
), | |
"negative-margin-right": ( | |
responsive: true, | |
property: margin-right, | |
class: mr, | |
values: $negative-spacers | |
), | |
"negative-margin-bottom": ( | |
responsive: true, | |
property: margin-bottom, | |
class: mb, | |
values: $negative-spacers | |
), | |
"negative-margin-left": ( | |
responsive: true, | |
property: margin-left, | |
class: ml, | |
values: $negative-spacers | |
), | |
// Padding utilities | |
"padding": ( | |
responsive: true, | |
property: padding, | |
class: p, | |
values: $spacers | |
), | |
"padding-x": ( | |
responsive: true, | |
property: padding-right padding-left, | |
class: px, | |
values: $spacers | |
), | |
"padding-y": ( | |
responsive: true, | |
property: padding-top padding-bottom, | |
class: py, | |
values: $spacers | |
), | |
"padding-top": ( | |
responsive: true, | |
property: padding-top, | |
class: pt, | |
values: $spacers | |
), | |
"padding-right": ( | |
responsive: true, | |
property: padding-right, | |
class: pr, | |
values: $spacers | |
), | |
"padding-bottom": ( | |
responsive: true, | |
property: padding-bottom, | |
class: pb, | |
values: $spacers | |
), | |
"padding-left": ( | |
responsive: true, | |
property: padding-left, | |
class: pl, | |
values: $spacers | |
), | |
// Text | |
"font-weight": ( | |
property: font-weight, | |
values: ( | |
light: $font-weight-light, | |
lighter: $font-weight-lighter, | |
normal: $font-weight-normal, | |
bold: $font-weight-bold, | |
bolder: $font-weight-bolder | |
) | |
), | |
"text-transform": ( | |
property: text-transform, | |
class: text, | |
values: lowercase uppercase capitalize | |
), | |
"text-align": ( | |
responsive: true, | |
property: text-align, | |
class: text, | |
values: left right center | |
), | |
"color": ( | |
property: color, | |
class: text, | |
values: map-merge( | |
$theme-colors, | |
( | |
"white": $white, | |
"body": $body-color, | |
"muted": $text-muted, | |
"black-50": rgba($black, .5), | |
"white-50": rgba($white, .5), | |
"reset": inherit, | |
) | |
) | |
), | |
"line-height": ( | |
property: line-height, | |
class: lh, | |
values: ( | |
1: 1, | |
sm: $line-height-sm, | |
base: $line-height-base, | |
lg: $line-height-lg, | |
) | |
), | |
"background-color": ( | |
property: background-color, | |
class: bg, | |
values: map-merge( | |
$theme-colors, | |
( | |
"body": $body-bg, | |
"white": $white, | |
"transparent": transparent | |
) | |
) | |
), | |
"white-space": ( | |
property: white-space, | |
class: text, | |
values: ( | |
wrap: normal, | |
nowrap: nowrap, | |
) | |
), | |
"text-decoration": ( | |
property: text-decoration, | |
values: none underline line-through | |
), | |
"font-style": ( | |
property: font-style, | |
class: font, | |
values: italic normal | |
), | |
"word-wrap": ( | |
property: word-wrap, | |
class: text, | |
values: (break: break-word) | |
), | |
"font-family": ( | |
property: font-family, | |
class: font, | |
values: (monospace: $font-family-monospace) | |
), | |
"rounded": ( | |
property: border-radius, | |
class: rounded, | |
values: ( | |
null: $border-radius, | |
sm: $border-radius-sm, | |
lg: $border-radius-lg, | |
circle: 50%, | |
pill: $rounded-pill, | |
0: 0, | |
) | |
), | |
"rounded-top": ( | |
property: border-top-left-radius border-top-right-radius, | |
class: rounded-top, | |
values: (null: $border-radius) | |
), | |
"rounded-right": ( | |
property: border-top-right-radius border-bottom-right-radius, | |
class: rounded-right, | |
values: (null: $border-radius) | |
), | |
"rounded-bottom": ( | |
property: border-bottom-right-radius border-bottom-left-radius, | |
class: rounded-bottom, | |
values: (null: $border-radius) | |
), | |
"rounded-left": ( | |
property: border-bottom-left-radius border-top-left-radius, | |
class: rounded-left, | |
values: (null: $border-radius) | |
), | |
"visibility": ( | |
property: visibility, | |
class: null, | |
values: ( | |
visible: visible, | |
invisible: hidden, | |
) | |
) | |
), | |
$utilities | |
); | |
:root { | |
// Custom variable values only support SassScript inside `#{}`. | |
@each $color, $value in $colors { | |
--#{$color}: #{$value}; | |
} | |
@each $color, $value in $theme-colors { | |
--#{$color}: #{$value}; | |
} | |
// Use `inspect` for lists so that quoted items keep the quotes. | |
// See https://github.com/sass/sass/issues/2383#issuecomment-336349172 | |
--font-family-sans-serif: #{inspect($font-family-sans-serif)}; | |
--font-family-monospace: #{inspect($font-family-monospace)}; | |
} | |
// stylelint-disable at-rule-no-vendor-prefix, 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 | |
// | |
// 1. Ability to the value of the root font sizes, affecting the value of `rem`. | |
// null by default, thus nothing is generated. | |
:root { | |
font-size: $font-size-root; // 1 | |
} | |
// 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 IE on Windows Phone and in iOS. | |
// 4. Change the default tap highlight to be completely transparent in iOS. | |
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 | |
-webkit-text-size-adjust: 100%; // 3 | |
-webkit-tap-highlight-color: rgba($black, 0); // 4 | |
} | |
// Future-proof rule: in browsers that support :focus-visible, suppress the focus outline | |
// on elements that programmatically receive focus but wouldn't normally show a visible | |
// focus outline. In general, this would mean that the outline is only applied if the | |
// interaction that led to the element receiving programmatic focus was a keyboard interaction, | |
// or the browser has somehow determined that the user is primarily a keyboard user and/or | |
// wants focus outlines to always be presented. | |
// | |
// See https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible | |
// and https://developer.paciellogroup.com/blog/2018/03/focus-visible-and-backwards-compatibility/ | |
[tabindex="-1"]:focus:not(:focus-visible) { | |
outline: 0 !important; | |
} | |
// Content grouping | |
// | |
// 1. Reset Firefox's gray color | |
// 2. Set correct height and prevent the `size` attribute to make the `hr` look like an input field | |
// See https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_hr_size | |
hr { | |
margin: $hr-margin-y 0; | |
color: $hr-color; // 1 | |
background-color: currentColor; | |
border: 0; | |
opacity: $hr-opacity; | |
} | |
hr:not([size]) { | |
height: $hr-height; // 2 | |
} | |
// 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: $headings-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. Duplicate behavior to the data-* attribute for our tooltip plugin | |
// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. | |
// 3. Add explicit cursor to indicate changed behavior. | |
// 4. Prevent the text-decoration to be skipped. | |
abbr[title], | |
abbr[data-original-title] { // 1 | |
text-decoration: underline; // 2 | |
text-decoration: underline dotted; // 2 | |
cursor: help; // 3 | |
text-decoration-skip-ink: none; // 4 | |
} | |
address { | |
margin-bottom: 1rem; | |
font-style: normal; | |
line-height: inherit; | |
} | |
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 { | |
margin: 0 0 1rem; | |
} | |
// Add the correct font weight in Chrome, Edge, and Safari | |
b, | |
strong { | |
font-weight: $font-weight-bolder; | |
} | |
// Add the correct font size in all browsers | |
small { | |
@include font-size($small-font-size); | |
} | |
// 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: $link-color; | |
text-decoration: $link-decoration; | |
&:hover { | |
color: $link-hover-color; | |
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]) { | |
&, | |
&:hover { | |
color: inherit; | |
text-decoration: none; | |
} | |
} | |
// Code | |
pre, | |
code, | |
kbd, | |
samp { | |
font-family: $font-family-monospace; | |
@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: $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 { | |
vertical-align: middle; | |
} | |
// 1. Workaround for the SVG overflow bug in IE 11 is still required. | |
// See https://github.com/twbs/bootstrap/issues/26878 | |
svg { | |
overflow: hidden; // 1 | |
vertical-align: middle; | |
} | |
// Tables | |
// Prevent double borders | |
table { | |
border-collapse: collapse; | |
} | |
caption { | |
padding-top: $table-cell-padding; | |
padding-bottom: $table-cell-padding; | |
color: $table-caption-color; | |
text-align: left; | |
caption-side: bottom; | |
} | |
// Matches default `<td>` alignment by inheriting from the `<body>`, or the | |
// closest parent with a set `text-align`. | |
th { | |
text-align: inherit; | |
} | |
// Forms | |
// 1. Allow labels to use `margin` for spacing. | |
label { | |
display: inline-block; // 1 | |
margin-bottom: $label-margin-bottom; | |
} | |
// Remove the default `border-radius` that macOS Chrome adds. | |
// | |
// Details at https://github.com/twbs/bootstrap/issues/24093 | |
button { | |
// stylelint-disable-next-line property-blacklist | |
border-radius: 0; | |
} | |
// Work around a Firefox/IE bug where the transparent `button` background | |
// results in a loss of the default `button` focus styles. | |
// | |
// Credit: https://github.com/suitcss/base/ | |
button:focus { | |
outline: 1px dotted; | |
outline: 5px auto -webkit-focus-ring-color; | |
} | |
// 1. Remove the margin in Firefox and Safari | |
input, | |
button, | |
select, | |
optgroup, | |
textarea { | |
margin: 0; | |
font-family: inherit; | |
@include font-size(inherit); | |
line-height: inherit; | |
} | |
// Show the overflow in Edge | |
button, | |
input { | |
overflow: visible; | |
} | |
// Remove the inheritance of text transform in Firefox | |
button, | |
select { | |
text-transform: none; | |
} | |
// Remove the inheritance of word-wrap in Safari. | |
// | |
// Details at https://github.com/twbs/bootstrap/issues/24990 | |
select { | |
word-wrap: normal; | |
} | |
// Remove the dropdown arrow in Chrome from inputs built with datalists. | |
// | |
// Source: https://stackoverflow.com/a/54997118 | |
[list]::-webkit-calendar-picker-indicator { | |
display: none; | |
} | |
// 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-pointer-cursor-for-buttons { | |
&: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; | |
} | |
// Remove the default appearance of temporal inputs to avoid a Mobile Safari | |
// bug where setting a custom line-height prevents text from being vertically | |
// centered within the input. | |
// See https://bugs.webkit.org/show_bug.cgi?id=139848 | |
// and https://github.com/twbs/bootstrap/issues/11266 | |
input[type="date"], | |
input[type="time"], | |
input[type="datetime-local"], | |
input[type="month"] { | |
-webkit-appearance: textfield; | |
} | |
// 1. Remove the default vertical scrollbar in IE. | |
// 2. Textareas should really only resize vertically so they don't break their (horizontal) containers. | |
textarea { | |
overflow: auto; // 1 | |
resize: vertical; // 2 | |
} | |
// 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 | |
// 2. Correct the color inheritance from `fieldset` elements in IE. | |
// 3. Correct the text wrapping in Edge and IE. | |
legend { | |
float: left; // 1 | |
width: 100%; | |
padding: 0; | |
margin-bottom: $legend-margin-bottom; | |
@include font-size($legend-font-size); | |
font-weight: $legend-font-weight; | |
line-height: inherit; | |
color: inherit; // 2 | |
white-space: normal; // 3 | |
} | |
mark { | |
padding: $mark-padding; | |
background-color: $mark-bg; | |
} | |
// Add the correct vertical alignment in Chrome, Firefox, and Opera. | |
progress { | |
vertical-align: baseline; | |
} | |
// 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 { | |
overflow: visible; | |
line-height: 0; | |
} | |
// 1. Correct the outline style in Safari. | |
// 2. 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. | |
[type="search"] { | |
outline-offset: -2px; // 1 | |
-webkit-appearance: textfield; // 2 | |
} | |
// 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. Change font properties to `inherit` in Safari. | |
// 2. Correct the inability to style clickable types in iOS and Safari. | |
::-webkit-file-upload-button { | |
font: inherit; // 1 | |
-webkit-appearance: button; // 2 | |
} | |
// Correct element displays | |
output { | |
display: inline-block; | |
} | |
// 1. Add the correct display in all browsers | |
summary { | |
display: list-item; // 1 | |
cursor: pointer; | |
} | |
// Add the correct display for template & main in IE 11 | |
template { | |
display: none; | |
} | |
main { | |
display: block; | |
} | |
// Always hide an element with the `hidden` HTML attribute. | |
[hidden] { | |
display: none !important; | |
} | |
// | |
// Headings | |
// | |
.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 | |
.display-1 { | |
@include font-size($display1-size); | |
font-weight: $display1-weight; | |
line-height: $display-line-height; | |
} | |
.display-2 { | |
@include font-size($display2-size); | |
font-weight: $display2-weight; | |
line-height: $display-line-height; | |
} | |
.display-3 { | |
@include font-size($display3-size); | |
font-weight: $display3-weight; | |
line-height: $display-line-height; | |
} | |
.display-4 { | |
@include font-size($display4-size); | |
font-weight: $display4-weight; | |
line-height: $display-line-height; | |
} | |
// | |
// 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: $spacer; | |
@include font-size($blockquote-font-size); | |
} | |
.blockquote-footer { | |
display: block; | |
@include font-size($blockquote-small-font-size); | |
color: $blockquote-small-color; | |
&::before { | |
content: "\2014\00A0"; // em dash, nbsp | |
} | |
} | |
// 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 / 2; | |
line-height: 1; | |
} | |
.figure-caption { | |
@include font-size($figure-caption-font-size); | |
color: $figure-caption-color; | |
} | |
// Container widths | |
// | |
// Set the container width, and override it for fixed navbars in media queries. | |
@if $enable-grid-classes { | |
// Single container class with breakpoint max-widths | |
.container { | |
@include make-container(); | |
@include make-container-max-widths(); | |
} | |
// 100% wide container at all breakpoints | |
.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-container-#{$breakpoint} { | |
max-width: $container-max-width; | |
} | |
// Extend each breakpoint which is smaller or equal to the current breakpoint | |
$extend-breakpoint: true; | |
@each $name, $width in $grid-breakpoints { | |
@if ($extend-breakpoint) { | |
.container#{breakpoint-infix($name, $grid-breakpoints)} { | |
@extend %responsive-container-#{$breakpoint}; | |
} | |
// Once the current breakpoint is reached, stop extending | |
@if ($breakpoint == $name) { | |
$extend-breakpoint: false; | |
} | |
} | |
} | |
} | |
} | |
} | |
// Row | |
// | |
// Rows contain your columns. | |
@if $enable-grid-classes { | |
.row { | |
@include make-row(); | |
} | |
// Remove the negative margin from default .row, then the horizontal padding | |
// from all immediate children columns (to prevent runaway style inheritance). | |
.no-gutters { | |
margin-right: 0; | |
margin-left: 0; | |
> .col, | |
> [class*="col-"] { | |
padding-right: 0; | |
padding-left: 0; | |
} | |
} | |
} | |
// Columns | |
// | |
// Common styles for small and large grid columns | |
@if $enable-grid-classes { | |
@include make-grid-columns(); | |
} | |
// | |
// Basic Bootstrap table | |
// | |
.table { | |
width: 100%; | |
margin-bottom: $spacer; | |
color: $table-color; | |
vertical-align: $table-cell-vertical-align; | |
background-color: $table-bg; // Reset for nesting within parents with `background-color`. | |
th, | |
td { | |
padding: $table-cell-padding; | |
border-bottom: $table-border-width solid $table-border-color; | |
} | |
tbody { | |
vertical-align: inherit; | |
} | |
thead th { | |
vertical-align: bottom; | |
border-bottom-color: $table-head-border-color; | |
} | |
tbody + tbody { | |
border-top: (2 * $table-border-width) solid $table-border-color; | |
} | |
} | |
// | |
// Condensed table w/ half padding | |
// | |
.table-sm { | |
th, | |
td { | |
padding: $table-cell-padding-sm; | |
} | |
} | |
// Border versions | |
// | |
// Add or remove borders all around the table and between all the columns. | |
.table-bordered { | |
border: $table-border-width solid $table-border-color; | |
th, | |
td { | |
border: $table-border-width solid $table-border-color; | |
} | |
thead { | |
th, | |
td { | |
border-bottom-width: 2 * $table-border-width; | |
} | |
} | |
} | |
.table-borderless { | |
th, | |
td, | |
thead th, | |
tbody + tbody { | |
border: 0; | |
} | |
} | |
// Zebra-striping | |
// | |
// Default zebra-stripe styles (alternating gray and transparent backgrounds) | |
.table-striped { | |
tbody tr:nth-of-type(#{$table-striped-order}) { | |
background-color: $table-accent-bg; | |
} | |
} | |
// Hover effect | |
// | |
// Placed here since it has to come after the potential zebra striping | |
.table-hover { | |
tbody tr { | |
&:hover { | |
color: $table-hover-color; | |
background-color: $table-hover-bg; | |
} | |
} | |
} | |
// Table backgrounds | |
// | |
// Exact selectors below required to override `.table-striped` and prevent | |
// inheritance to nested tables. | |
@each $color, $value in $theme-colors { | |
@include table-row-variant($color, color-level($value, $table-bg-level), color-level($value, $table-border-level)); | |
} | |
@include table-row-variant(active, $table-active-bg); | |
// Dark styles | |
// | |
// Same table markup, but inverted color scheme: dark background and light text. | |
// stylelint-disable-next-line no-duplicate-selectors | |
.table { | |
.thead-dark { | |
th { | |
color: $table-dark-color; | |
background-color: $table-dark-bg; | |
border-color: $table-dark-border-color; | |
} | |
} | |
.thead-light { | |
th { | |
color: $table-head-color; | |
background-color: $table-head-bg; | |
border-color: $table-border-color; | |
} | |
} | |
} | |
.table-dark { | |
color: $table-dark-color; | |
background-color: $table-dark-bg; | |
th, | |
td, | |
thead th { | |
border-color: $table-dark-border-color; | |
} | |
&.table-bordered { | |
border: 0; | |
} | |
&.table-striped { | |
tbody tr:nth-of-type(#{$table-striped-order}) { | |
background-color: $table-dark-accent-bg; | |
} | |
} | |
&.table-hover { | |
tbody tr { | |
&:hover { | |
color: $table-dark-hover-color; | |
background-color: $table-dark-hover-bg; | |
} | |
} | |
} | |
} | |
// Responsive tables | |
// | |
// Generate series of `.table-responsive-*` classes for configuring the screen | |
// size of where your table will overflow. | |
.table-responsive { | |
@each $breakpoint in map-keys($grid-breakpoints) { | |
$next: breakpoint-next($breakpoint, $grid-breakpoints); | |
$infix: breakpoint-infix($next, $grid-breakpoints); | |
&#{$infix} { | |
@include media-breakpoint-down($breakpoint) { | |
display: block; | |
width: 100%; | |
overflow-x: auto; | |
-webkit-overflow-scrolling: touch; | |
// Prevent double border on horizontal scroll due to use of `display: block;` | |
> .table-bordered { | |
border: 0; | |
} | |
} | |
} | |
} | |
} | |
// | |
// Labels | |
// | |
// For use with horizontal and inline forms, when you need the label (or legend) | |
// text to align with the form controls. | |
.col-form-label { | |
padding-top: add($input-padding-y, $input-border-width); | |
padding-bottom: add($input-padding-y, $input-border-width); | |
margin-bottom: 0; // Override the `<label>/<legend>` default | |
@include font-size(inherit); // Override the `<legend>` default | |
line-height: $input-line-height; | |
} | |
.col-form-label-lg { | |
padding-top: 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); | |
} | |
.col-form-label-sm { | |
padding-top: 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); | |
} | |
// | |
// Textual form controls | |
// | |
.form-control { | |
display: block; | |
width: 100%; | |
min-height: $input-height; | |
padding: $input-padding-y $input-padding-x; | |
font-family: $input-font-family; | |
@include font-size($input-font-size); | |
font-weight: $input-font-weight; | |
line-height: $input-line-height; | |
color: $input-color; | |
background-color: $input-bg; | |
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. | |
@include border-radius($input-border-radius, 0); | |
@include box-shadow($input-box-shadow); | |
@include transition($input-transition); | |
// Unstyle the caret on `<select>`s in IE10+. | |
&::-ms-expand { | |
background-color: transparent; | |
border: 0; | |
} | |
// 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; | |
// Avoid using mixin so we can pass custom focus shadow properly | |
@if $enable-shadows { | |
box-shadow: $input-box-shadow, $input-focus-box-shadow; | |
} @else { | |
box-shadow: $input-focus-box-shadow; | |
} | |
} | |
// Placeholder | |
&::placeholder { | |
color: $input-placeholder-color; | |
// Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526. | |
opacity: 1; | |
} | |
// Disabled and read-only 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, | |
&[readonly] { | |
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; | |
} | |
} | |
// 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; | |
&.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); | |
} | |
.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); | |
} | |
.form-control-color { | |
max-width: 3rem; | |
padding: $input-padding-y; | |
} | |
.form-control-color::-moz-color-swatch { | |
@include border-radius($input-border-radius); | |
} | |
.form-control-color::-webkit-color-swatch { | |
@include border-radius($input-border-radius); | |
} | |
// Select | |
// | |
// Replaces the browser default select with a custom one, mostly pulled from | |
// https://primer.github.io/. | |
.form-select { | |
display: inline-block; | |
width: 100%; | |
height: $form-select-height; | |
padding: $form-select-padding-y ($form-select-padding-x + $form-select-indicator-padding) $form-select-padding-y $form-select-padding-x; | |
font-family: $form-select-font-family; | |
@include font-size($form-select-font-size); | |
font-weight: $form-select-font-weight; | |
line-height: $form-select-line-height; | |
color: $form-select-color; | |
vertical-align: middle; | |
background: $form-select-bg escape-svg($form-select-indicator) $form-select-background; | |
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); | |
appearance: none; | |
&:focus { | |
border-color: $form-select-focus-border-color; | |
outline: 0; | |
@if $enable-shadows { | |
box-shadow: $form-select-box-shadow, $form-select-focus-box-shadow; | |
} @else { | |
box-shadow: $form-select-focus-box-shadow; | |
} | |
&::-ms-value { | |
// For visual consistency with other platforms/browsers, | |
// suppress the default white text on blue background highlight given to | |
// the selected option text when the (still closed) <select> receives focus | |
// in IE and (under certain conditions) Edge. | |
// See https://github.com/twbs/bootstrap/issues/19398. | |
color: $input-color; | |
background-color: $input-bg; | |
} | |
} | |
&[multiple], | |
&[size]:not([size="1"]) { | |
height: auto; | |
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; | |
} | |
// Hides the default caret in IE11 | |
&::-ms-expand { | |
display: none; | |
} | |
// Remove outline from select box in FF | |
&:-moz-focusring { | |
color: transparent; | |
text-shadow: 0 0 0 $form-select-color; | |
} | |
} | |
.form-select-sm { | |
height: $form-select-height-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); | |
} | |
.form-select-lg { | |
height: $form-select-height-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); | |
} | |
// | |
// Check/radio | |
// | |
.form-check { | |
display: block; | |
min-height: $form-check-min-height; | |
padding-left: $form-check-padding-left; | |
margin-bottom: $form-check-margin-bottom; | |
.form-check-input { | |
float: left; | |
margin-left: $form-check-padding-left * -1; | |
} | |
} | |
.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 | |
vertical-align: top; | |
background-color: $form-check-input-bg; | |
border: $form-check-input-border; | |
appearance: none; | |
color-adjust: exact; // Keep themed appearance for print | |
&[type="checkbox"] { | |
@include border-radius($form-check-input-border-radius); | |
} | |
&[type="radio"] { | |
@include 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; | |
background-repeat: $form-check-input-checked-bg-repeat; | |
background-position: $form-check-input-checked-bg-position; | |
background-size: $form-check-input-checked-bg-size; | |
border-color: $form-check-input-checked-border-color; | |
&[type="checkbox"] { | |
@if $enable-gradients { | |
background-image: escape-svg($form-check-input-checked-bg-image), linear-gradient(180deg, lighten($form-check-input-checked-bg-color, 10%), $form-check-input-checked-bg-color); | |
background-size: $form-check-input-checked-bg-size, auto; | |
} @else { | |
background-image: escape-svg($form-check-input-checked-bg-image); | |
} | |
} | |
&[type="radio"] { | |
@if $enable-gradients { | |
background-image: escape-svg($form-check-radio-checked-bg-image), linear-gradient(180deg, lighten($form-check-input-checked-bg-color, 10%), $form-check-input-checked-bg-color); | |
background-size: $form-check-input-checked-bg-size, auto; | |
} @else { | |
background-image: escape-svg($form-check-radio-checked-bg-image); | |
} | |
} | |
} | |
&[type="checkbox"]:indeterminate { | |
background-color: $form-check-input-indeterminate-bg-color; | |
background-repeat: $form-check-input-indeterminate-bg-repeat; | |
background-position: $form-check-input-indeterminate-bg-position; | |
@if $enable-gradients { | |
background-image: escape-svg($form-check-input-indeterminate-bg-image), linear-gradient(180deg, lighten($form-check-input-checked-bg-color, 10%), $form-check-input-checked-bg-color); | |
background-size: $form-check-input-checked-bg-size, auto; | |
} @else { | |
background-image: escape-svg($form-check-input-indeterminate-bg-image); | |
background-size: $form-check-input-indeterminate-bg-size; | |
} | |
border-color: $form-check-input-indeterminate-border-color; | |
} | |
&:disabled { | |
pointer-events: none; | |
filter: none; | |
opacity: .5; | |
} | |
// Use disabled attribute in addition of :disabled pseudo-class | |
// See: https://github.com/twbs/bootstrap/issues/28247 | |
&[disabled], | |
&:disabled { | |
~ .form-check-label { | |
opacity: .5; | |
} | |
} | |
} | |
.form-check-label { | |
margin-bottom: 0; | |
cursor: $form-check-label-cursor; | |
} | |
// | |
// Switch | |
// | |
.form-switch { | |
padding-left: $form-switch-padding-left; | |
.form-check-input { | |
width: $form-switch-width; | |
margin-left: $form-switch-padding-left * -1; | |
background-image: escape-svg($form-switch-bg-image); | |
background-repeat: no-repeat; | |
background-position: left center; | |
background-size: $form-switch-bg-size; // Get a 1px separation | |
@include border-radius($form-switch-border-radius); | |
color-adjust: exact; // Keep themed appearance for print | |
// Todo: Figure out how to tackle these, with or without mixin? | |
// transition: $form-switch-transition; | |
// transition-property: $form-switch-transition-property; | |
&:focus { | |
background-image: escape-svg($form-switch-focus-bg-image); | |
} | |
&:checked { | |
background-position: $form-switch-checked-bg-position; | |
@if $enable-gradients { | |
background-image: escape-svg($form-switch-checked-bg-image), linear-gradient(180deg, $form-check-input-checked-bg-color, lighten($form-check-input-checked-bg-color, 10%)); | |
background-size: $form-switch-bg-size, auto; | |
} @else { | |
background-image: escape-svg($form-switch-checked-bg-image); | |
} | |
} | |
} | |
} | |
.form-check-inline { | |
display: inline-block; | |
margin-right: $form-check-inline-margin-right; | |
} | |
.form-file { | |
position: relative; | |
display: inline-block; | |
width: 100%; | |
height: $form-file-height; | |
margin-bottom: 0; | |
} | |
.form-file-input { | |
position: relative; | |
z-index: 2; | |
width: 100%; | |
height: $form-file-height; | |
margin: 0; | |
opacity: 0; | |
// Separate rules for :focus and :focus-within as IE doesn't support the latter, and | |
// thus ignores the entire ruleset. See https://github.com/twbs/bootstrap/pull/29036. | |
&:focus ~ .form-file-label { | |
border-color: $form-file-focus-border-color; | |
box-shadow: $form-file-focus-box-shadow; | |
} | |
&:focus-within ~ .form-file-label { | |
border-color: $form-file-focus-border-color; | |
box-shadow: $form-file-focus-box-shadow; | |
} | |
// Use disabled attribute in addition of :disabled pseudo-class | |
// See: https://github.com/twbs/bootstrap/issues/28247 | |
&[disabled] ~ .form-file-label .form-file-text, | |
&:disabled ~ .form-file-label .form-file-text { | |
background-color: $form-file-disabled-bg; | |
border-color: $form-file-disabled-border-color; | |
} | |
} | |
.form-file-label { | |
position: absolute; | |
top: 0; | |
right: 0; | |
left: 0; | |
z-index: 1; | |
display: flex; | |
height: $form-file-height; | |
border-color: $form-file-border-color; | |
@include border-radius($form-file-border-radius); | |
@include box-shadow($form-file-box-shadow); | |
} | |
.form-file-text { | |
display: block; | |
flex-grow: 1; | |
padding: $form-file-padding-y $form-file-padding-x; | |
overflow: hidden; | |
font-family: $form-file-font-family; | |
font-weight: $form-file-font-weight; | |
line-height: $form-file-line-height; | |
color: $form-file-color; | |
text-overflow: ellipsis; | |
white-space: nowrap; | |
background-color: $form-file-bg; | |
border-color: inherit; | |
border-style: solid; | |
border-width: $form-file-border-width; | |
@include border-left-radius(inherit); | |
} | |
.form-file-button { | |
display: block; | |
flex-shrink: 0; | |
padding: $form-file-padding-y $form-file-padding-x; | |
margin-left: -$form-file-border-width; | |
line-height: $form-file-line-height; | |
color: $form-file-button-color; | |
@include gradient-bg($form-file-button-bg); | |
border-color: inherit; | |
border-style: solid; | |
border-width: $form-file-border-width; | |
@include border-right-radius(inherit); | |
} | |
// Range | |
// | |
// Style range inputs the same across browsers. Vendor-specific rules for pseudo | |
// elements cannot be mixed. As such, there are no shared styles for focus or | |
// active states on prefixed selectors. | |
.form-range { | |
width: 100%; | |
height: add($form-range-thumb-height, $form-range-thumb-focus-box-shadow-width * 2); | |
padding: 0; // Need to reset padding | |
background-color: transparent; | |
appearance: none; | |
&:focus { | |
outline: none; | |
// 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; } | |
&::-ms-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) / 2; // Webkit specific | |
@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); | |
appearance: none; | |
&: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 { | |
width: $form-range-thumb-width; | |
height: $form-range-thumb-height; | |
@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); | |
appearance: none; | |
&: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); | |
} | |
&::-ms-thumb { | |
width: $form-range-thumb-width; | |
height: $form-range-thumb-height; | |
margin-top: 0; // Edge specific | |
margin-right: $form-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden. | |
margin-left: $form-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden. | |
@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); | |
appearance: none; | |
&:active { | |
@include gradient-bg($form-range-thumb-active-bg); | |
} | |
} | |
&::-ms-track { | |
width: $form-range-track-width; | |
height: $form-range-track-height; | |
color: transparent; | |
cursor: $form-range-track-cursor; | |
background-color: transparent; | |
border-color: transparent; | |
border-width: $form-range-thumb-height / 2; | |
@include box-shadow($form-range-track-box-shadow); | |
} | |
&::-ms-fill-lower { | |
background-color: $form-range-track-bg; | |
@include border-radius($form-range-track-border-radius); | |
} | |
&::-ms-fill-upper { | |
margin-right: 15px; // arbitrary? | |
background-color: $form-range-track-bg; | |
@include border-radius($form-range-track-border-radius); | |
} | |
&:disabled { | |
pointer-events: none; | |
&::-webkit-slider-thumb { | |
background-color: $form-range-thumb-disabled-bg; | |
} | |
&::-moz-range-thumb { | |
background-color: $form-range-thumb-disabled-bg; | |
} | |
&::-ms-thumb { | |
background-color: $form-range-thumb-disabled-bg; | |
} | |
} | |
} | |
// Form grid | |
// | |
// Special replacement for our grid system's `.row` for tighter form layouts. | |
@if $enable-grid-classes { | |
.form-row { | |
display: flex; | |
flex-wrap: wrap; | |
margin-right: -$form-grid-gutter-width / 2; | |
margin-left: -$form-grid-gutter-width / 2; | |
> .col, | |
> [class*="col-"] { | |
padding-right: $form-grid-gutter-width / 2; | |
padding-left: $form-grid-gutter-width / 2; | |
} | |
} | |
} | |
// Inline forms | |
// | |
// Make forms appear inline(-block) by adding the `.form-inline` class. Inline | |
// forms begin stacked on extra small (mobile) devices and then go inline when | |
// viewports reach <768px. | |
.form-inline { | |
display: flex; | |
flex-flow: row wrap; | |
align-items: center; // Prevent shorter elements from growing to same height as others (e.g., small buttons growing to normal sized button height) | |
// Because we use flex, the initial sizing of checkboxes is collapsed and | |
// doesn't occupy the full-width (which is what we want for xs grid tier), | |
// so we force that here. | |
.form-check { | |
width: 100%; | |
} | |
// Kick in the inline | |
@include media-breakpoint-up(sm) { | |
label { | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
margin-bottom: 0; | |
} | |
.form-control { | |
display: inline-block; | |
width: auto; // Prevent labels from stacking above inputs | |
vertical-align: middle; | |
} | |
// Make static controls behave like regular ones | |
.form-control-plaintext { | |
display: inline-block; | |
} | |
.input-group, | |
.form-select { | |
width: auto; | |
} | |
// Remove default margin on radios/checkboxes that were used for stacking, and | |
// then undo the floating of radios and checkboxes to match. | |
.form-check { | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
width: auto; | |
padding-left: 0; | |
} | |
.form-check-input { | |
position: relative; | |
flex-shrink: 0; | |
margin-top: 0; | |
margin-right: $form-check-input-margin-x; | |
margin-left: 0; | |
} | |
} | |
} | |
// stylelint-disable selector-no-qualifying-type | |
// | |
// Base styles | |
// | |
.input-group { | |
position: relative; | |
display: flex; | |
flex-wrap: wrap; // For form validation feedback | |
align-items: stretch; | |
width: 100%; | |
> .form-control, | |
> .form-select, | |
> .form-file { | |
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 | |
margin-bottom: 0; | |
+ .form-control, | |
+ .form-select, | |
+ .form-file { | |
margin-left: -$input-border-width; | |
} | |
} | |
// Bring the "active" form control to the top of surrounding elements | |
> .form-control:focus, | |
> .form-select:focus, | |
> .form-file .form-file-input:focus ~ .form-file-label { | |
z-index: 3; | |
} | |
// Bring the custom file input above the label | |
> .form-file .form-file-input:focus { | |
z-index: 4; | |
} | |
> .form-control, | |
> .form-select { | |
&:not(:last-child) { @include border-right-radius(0); } | |
&:not(:first-child) { @include border-left-radius(0); } | |
} | |
// Custom file inputs have more complex markup, thus requiring different | |
// border-radius overrides. | |
> .form-file { | |
display: flex; | |
align-items: center; | |
&:not(:last-child) .form-file-label { @include border-right-radius(0); } | |
&:not(:first-child) .form-file-label { @include border-left-radius(0); } | |
} | |
} | |
// Prepend and append | |
// | |
// While it requires one extra layer of HTML for each, dedicated prepend and | |
// append elements allow us to 1) be less clever, 2) simplify our selectors, and | |
// 3) support HTML5 form validation. | |
.input-group-prepend, | |
.input-group-append { | |
display: flex; | |
// 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; | |
&:focus { | |
z-index: 3; | |
} | |
} | |
.btn + .btn, | |
.btn + .input-group-text, | |
.input-group-text + .input-group-text, | |
.input-group-text + .btn { | |
margin-left: -$input-border-width; | |
} | |
} | |
.input-group-prepend { margin-right: -$input-border-width; } | |
.input-group-append { margin-left: -$input-border-width; } | |
// Textual addons | |
// | |
// 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-padding-y $input-padding-x; | |
margin-bottom: 0; // Allow use of <label> elements by overriding our default margin-bottom | |
@include font-size($input-font-size); // Match inputs | |
font-weight: $font-weight-normal; | |
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 { | |
min-height: $input-height-lg; | |
} | |
.input-group-lg > .form-select { | |
height: $input-height-lg; | |
} | |
.input-group-lg > .form-control, | |
.input-group-lg > .form-select, | |
.input-group-lg > .input-group-prepend > .input-group-text, | |
.input-group-lg > .input-group-append > .input-group-text, | |
.input-group-lg > .input-group-prepend > .btn, | |
.input-group-lg > .input-group-append > .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 { | |
min-height: $input-height-sm; | |
} | |
.input-group-sm > .form-select { | |
height: $input-height-sm; | |
} | |
.input-group-sm > .form-control, | |
.input-group-sm > .form-select, | |
.input-group-sm > .input-group-prepend > .input-group-text, | |
.input-group-sm > .input-group-append > .input-group-text, | |
.input-group-sm > .input-group-prepend > .btn, | |
.input-group-sm > .input-group-append > .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; | |
} | |
// Prepend and append 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. | |
.input-group > .input-group-prepend > .btn, | |
.input-group > .input-group-prepend > .input-group-text, | |
.input-group > .input-group-append:not(:last-child) > .btn, | |
.input-group > .input-group-append:not(:last-child) > .input-group-text, | |
.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle), | |
.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) { | |
@include border-right-radius(0); | |
} | |
.input-group > .input-group-append > .btn, | |
.input-group > .input-group-append > .input-group-text, | |
.input-group > .input-group-prepend:not(:first-child) > .btn, | |
.input-group > .input-group-prepend:not(:first-child) > .input-group-text, | |
.input-group > .input-group-prepend:first-child > .btn:not(:first-child), | |
.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) { | |
@include border-left-radius(0); | |
} | |
// Form validation | |
// | |
// Provide feedback to users when form field values are valid or invalid. Works | |
// primarily for client-side validation via scoped `:invalid` and `:valid` | |
// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for | |
// server-side validation. | |
@each $state, $data in $form-validation-states { | |
@include form-validation-state($state, map-get($data, color), map-get($data, icon)); | |
} | |
// | |
// Base styles | |
// | |
.btn { | |
display: inline-block; | |
font-family: $btn-font-family; | |
font-weight: $btn-font-weight; | |
line-height: $btn-line-height; | |
color: $body-color; | |
text-align: center; | |
white-space: $btn-white-space; | |
vertical-align: middle; | |
cursor: if($enable-pointer-cursor-for-buttons, pointer, null); | |
user-select: none; | |
background-color: transparent; | |
border: $btn-border-width solid transparent; | |
@include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-border-radius); | |
@include transition($btn-transition); | |
&:hover { | |
color: $body-color; | |
text-decoration: none; | |
} | |
&:focus, | |
&.focus { | |
outline: 0; | |
box-shadow: $btn-focus-box-shadow; | |
} | |
&:active, | |
&.active { | |
@include box-shadow($btn-active-box-shadow); | |
&:focus { | |
@include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow); | |
} | |
} | |
&:disabled, | |
&.disabled, | |
fieldset:disabled & { // stylelint-disable-line selector-no-qualifying-type | |
pointer-events: none; | |
opacity: $btn-disabled-opacity; | |
@include box-shadow(none); | |
} | |
} | |
// | |
// Alternate buttons | |
// | |
@each $color, $value in $theme-colors { | |
.btn-#{$color} { | |
@include button-variant($value, $value); | |
} | |
} | |
@each $color, $value in $theme-colors { | |
.btn-outline-#{$color} { | |
@include button-outline-variant($value); | |
} | |
} | |
// | |
// Link buttons | |
// | |
// Make a button look and behave like a link | |
.btn-link { | |
font-weight: $font-weight-normal; | |
color: $btn-link-color; | |
text-decoration: $link-decoration; | |
&:hover { | |
color: $btn-link-hover-color; | |
text-decoration: $link-hover-decoration; | |
} | |
&:focus, | |
&.focus { | |
text-decoration: $link-hover-decoration; | |
box-shadow: none; | |
} | |
&:disabled, | |
&.disabled { | |
color: $btn-link-disabled-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); | |
} | |
// | |
// Block button | |
// | |
.btn-block { | |
display: block; | |
width: 100%; | |
// Vertically space out multiple block buttons | |
+ .btn-block { | |
margin-top: $btn-block-spacing-y; | |
} | |
} | |
.fade { | |
@include transition($transition-fade); | |
&:not(.show) { | |
opacity: 0; | |
} | |
} | |
.collapse { | |
&:not(.show) { | |
display: none; | |
} | |
} | |
.collapsing { | |
height: 0; | |
overflow: hidden; | |
@include transition($transition-collapse); | |
} | |
// The dropdown wrapper (`<div>`) | |
.dropup, | |
.dropright, | |
.dropdown, | |
.dropleft { | |
position: relative; | |
} | |
.dropdown-toggle { | |
white-space: nowrap; | |
// Generate the caret automatically | |
@include caret(); | |
} | |
// The dropdown menu | |
.dropdown-menu { | |
position: absolute; | |
top: 100%; | |
left: 0; | |
z-index: $zindex-dropdown; | |
display: none; // none by default, but block on "open" of the menu | |
min-width: $dropdown-min-width; | |
padding: $dropdown-padding-y 0; | |
margin: $dropdown-spacer 0 0; // override default ul | |
@include font-size($dropdown-font-size); | |
color: $dropdown-color; | |
text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer) | |
list-style: none; | |
background-color: $dropdown-bg; | |
background-clip: padding-box; | |
border: $dropdown-border-width solid $dropdown-border-color; | |
@include border-radius($dropdown-border-radius); | |
@include box-shadow($dropdown-box-shadow); | |
} | |
@each $breakpoint in map-keys($grid-breakpoints) { | |
@include media-breakpoint-up($breakpoint) { | |
$infix: breakpoint-infix($breakpoint, $grid-breakpoints); | |
.dropdown-menu#{$infix}-left { | |
right: auto; | |
left: 0; | |
} | |
.dropdown-menu#{$infix}-right { | |
right: 0; | |
left: auto; | |
} | |
} | |
} | |
// 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 { | |
top: auto; | |
bottom: 100%; | |
margin-top: 0; | |
margin-bottom: $dropdown-spacer; | |
} | |
.dropdown-toggle { | |
@include caret(up); | |
} | |
} | |
.dropright { | |
.dropdown-menu { | |
top: 0; | |
right: auto; | |
left: 100%; | |
margin-top: 0; | |
margin-left: $dropdown-spacer; | |
} | |
.dropdown-toggle { | |
@include caret(right); | |
&::after { | |
vertical-align: 0; | |
} | |
} | |
} | |
.dropleft { | |
.dropdown-menu { | |
top: 0; | |
right: 100%; | |
left: auto; | |
margin-top: 0; | |
margin-right: $dropdown-spacer; | |
} | |
.dropdown-toggle { | |
@include caret(left); | |
&::before { | |
vertical-align: 0; | |
} | |
} | |
} | |
// When enabled Popper.js, reset basic dropdown position | |
// stylelint-disable-next-line no-duplicate-selectors | |
.dropdown-menu { | |
&[x-placement^="top"], | |
&[x-placement^="right"], | |
&[x-placement^="bottom"], | |
&[x-placement^="left"] { | |
right: auto; | |
bottom: auto; | |
} | |
} | |
// Dividers (basically an `<hr>`) within the dropdown | |
.dropdown-divider { | |
height: 0; | |
margin: $dropdown-divider-margin-y 0; | |
overflow: hidden; | |
border-top: 1px solid $dropdown-divider-bg; | |
} | |
// 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: $dropdown-item-padding-y $dropdown-item-padding-x; | |
clear: both; | |
font-weight: $font-weight-normal; | |
color: $dropdown-link-color; | |
text-align: inherit; // For `<button>`s | |
white-space: nowrap; // prevent links from randomly breaking onto new lines | |
background-color: transparent; // For `<button>`s | |
border: 0; // For `<button>`s | |
// Prevent dropdown overflow if there's no padding | |
// See https://github.com/twbs/bootstrap/pull/27703 | |
@if $dropdown-padding-y == 0 { | |
&:first-child { | |
@include border-top-radius($dropdown-inner-border-radius); | |
} | |
&:last-child { | |
@include border-bottom-radius($dropdown-inner-border-radius); | |
} | |
} | |
&:hover, | |
&:focus { | |
color: $dropdown-link-hover-color; | |
text-decoration: none; | |
@include gradient-bg($dropdown-link-hover-bg); | |
} | |
&.active, | |
&:active { | |
color: $dropdown-link-active-color; | |
text-decoration: none; | |
@include gradient-bg($dropdown-link-active-bg); | |
} | |
&.disabled, | |
&:disabled { | |
color: $dropdown-link-disabled-color; | |
pointer-events: none; | |
background-color: transparent; | |
// Remove CSS gradients if they're enabled | |
@if $enable-gradients { | |
background-image: none; | |
} | |
} | |
} | |
.dropdown-menu.show { | |
display: block; | |
} | |
// Dropdown section headers | |
.dropdown-header { | |
display: block; | |
padding: $dropdown-padding-y $dropdown-item-padding-x; | |
margin-bottom: 0; // for use with heading elements | |
@include font-size($font-size-sm); | |
color: $dropdown-header-color; | |
white-space: nowrap; // as with > li > a | |
} | |
// Dropdown text | |
.dropdown-item-text { | |
display: block; | |
padding: $dropdown-item-padding-y $dropdown-item-padding-x; | |
color: $dropdown-link-color; | |
} | |
// stylelint-disable selector-no-qualifying-type | |
// Make the div behave like a button | |
.btn-group, | |
.btn-group-vertical { | |
position: relative; | |
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 | |
&:hover, | |
&:focus, | |
&:active, | |
&.active { | |
z-index: 1; | |
} | |
} | |
} | |
// Optional: Group multiple button groups together for a toolbar | |
.btn-toolbar { | |
display: flex; | |
flex-wrap: wrap; | |
justify-content: flex-start; | |
.input-group { | |
width: auto; | |
} | |
} | |
.btn-group { | |
// Prevent double borders when buttons are next to each other | |
> .btn:not(:first-child), | |
> .btn-group:not(:first-child) { | |
margin-left: -$btn-border-width; | |
} | |
// Reset rounded corners | |
> .btn:not(:last-child):not(.dropdown-toggle), | |
> .btn-group:not(:last-child) > .btn { | |
@include border-right-radius(0); | |
} | |
> .btn:not(:first-child), | |
> .btn-group:not(:first-child) > .btn { | |
@include border-left-radius(0); | |
} | |
} | |
// Sizing | |
// | |
// Remix the default button sizing classes into new ones for easier manipulation. | |
.btn-group-sm > .btn { @extend .btn-sm; } | |
.btn-group-lg > .btn { @extend .btn-lg; } | |
// | |
// Split button dropdowns | |
// | |
.dropdown-toggle-split { | |
padding-right: $btn-padding-x * .75; | |
padding-left: $btn-padding-x * .75; | |
&::after, | |
.dropup &::after, | |
.dropright &::after { | |
margin-left: 0; | |
} | |
.dropleft &::before { | |
margin-right: 0; | |
} | |
} | |
.btn-sm + .dropdown-toggle-split { | |
padding-right: $btn-padding-x-sm * .75; | |
padding-left: $btn-padding-x-sm * .75; | |
} | |
.btn-lg + .dropdown-toggle-split { | |
padding-right: $btn-padding-x-lg * .75; | |
padding-left: $btn-padding-x-lg * .75; | |
} | |
// The clickable button for toggling the menu | |
// Set the same inset shadow as the :active state | |
.btn-group.show .dropdown-toggle { | |
@include box-shadow($btn-active-box-shadow); | |
// Show no shadow for `.btn-link` since it has no other button styles. | |
&.btn-link { | |
@include box-shadow(none); | |
} | |
} | |
// | |
// Vertical button groups | |
// | |
.btn-group-vertical { | |
flex-direction: column; | |
align-items: flex-start; | |
justify-content: center; | |
> .btn, | |
> .btn-group { | |
width: 100%; | |
} | |
> .btn:not(:first-child), | |
> .btn-group:not(:first-child) { | |
margin-top: -$btn-border-width; | |
} | |
// Reset rounded corners | |
> .btn:not(:last-child):not(.dropdown-toggle), | |
> .btn-group:not(:last-child) > .btn { | |
@include border-bottom-radius(0); | |
} | |
> .btn:not(:first-child), | |
> .btn-group:not(:first-child) > .btn { | |
@include border-top-radius(0); | |
} | |
} | |
// Checkbox and radio options | |
// | |
// In order to support the browser's form validation feedback, powered by the | |
// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use | |
// `display: none;` or `visibility: hidden;` as that also hides the popover. | |
// Simply visually hiding the inputs via `opacity` would leave them clickable in | |
// certain cases which is prevented by using `clip` and `pointer-events`. | |
// This way, we ensure a DOM element is visible to position the popover from. | |
// | |
// See https://github.com/twbs/bootstrap/pull/12794 and | |
// https://github.com/twbs/bootstrap/pull/14559 for more information. | |
.btn-group-toggle { | |
> .btn, | |
> .btn-group > .btn { | |
margin-bottom: 0; // Override default `<label>` value | |
input[type="radio"], | |
input[type="checkbox"] { | |
position: absolute; | |
clip: rect(0, 0, 0, 0); | |
pointer-events: none; | |
} | |
} | |
} | |
// Base class | |
// | |
// Kickstart any navigation component with a set of style resets. Works with | |
// `<nav>`s, `<ul>`s or `<ol>`s. | |
.nav { | |
display: flex; | |
flex-wrap: wrap; | |
padding-left: 0; | |
margin-bottom: 0; | |
list-style: none; | |
} | |
.nav-link { | |
display: block; | |
padding: $nav-link-padding-y $nav-link-padding-x; | |
&:hover, | |
&:focus { | |
text-decoration: none; | |
} | |
// Disabled state lightens text | |
&.disabled { | |
color: $nav-link-disabled-color; | |
pointer-events: none; | |
cursor: default; | |
} | |
} | |
// | |
// Tabs | |
// | |
.nav-tabs { | |
border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color; | |
.nav-item { | |
margin-bottom: -$nav-tabs-border-width; | |
} | |
.nav-link { | |
border: $nav-tabs-border-width solid transparent; | |
@include border-top-radius($nav-tabs-border-radius); | |
&:hover, | |
&:focus { | |
border-color: $nav-tabs-link-hover-border-color; | |
} | |
&.disabled { | |
color: $nav-link-disabled-color; | |
background-color: transparent; | |
border-color: transparent; | |
} | |
} | |
.nav-link.active, | |
.nav-item.show .nav-link { | |
color: $nav-tabs-link-active-color; | |
background-color: $nav-tabs-link-active-bg; | |
border-color: $nav-tabs-link-active-border-color; | |
} | |
.dropdown-menu { | |
// Make dropdown border overlap tab border | |
margin-top: -$nav-tabs-border-width; | |
// Remove the top rounded corners here since there is a hard edge above the menu | |
@include border-top-radius(0); | |
} | |
} | |
// | |
// Pills | |
// | |
.nav-pills { | |
.nav-link { | |
@include border-radius($nav-pills-border-radius); | |
} | |
.nav-link.active, | |
.show > .nav-link { | |
color: $nav-pills-link-active-color; | |
background-color: $nav-pills-link-active-bg; | |
} | |
} | |
// | |
// Justified variants | |
// | |
.nav-fill { | |
.nav-item { | |
flex: 1 1 auto; | |
text-align: center; | |
} | |
} | |
.nav-justified { | |
.nav-item { | |
flex-basis: 0; | |
flex-grow: 1; | |
text-align: center; | |
} | |
} | |
// Tabbable tabs | |
// | |
// Hide tabbable panes to start, show them when `.active` | |
.tab-content { | |
> .tab-pane { | |
display: none; | |
} | |
> .active { | |
display: block; | |
} | |
} | |
// Contents | |
// | |
// Navbar | |
// Navbar brand | |
// Navbar nav | |
// Navbar text | |
// Responsive navbar | |
// Navbar position | |
// Navbar themes | |
// Navbar | |
// | |
// Provide a static navbar from which we expand to create full-width, fixed, and | |
// other navbar variations. | |
.navbar { | |
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-top: $navbar-padding-y; | |
padding-right: $navbar-padding-x; // default: null | |
padding-bottom: $navbar-padding-y; | |
padding-left: $navbar-padding-x; // default: null | |
// 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; | |
flex-wrap: inherit; | |
align-items: center; | |
justify-content: space-between; | |
} | |
> .container, | |
> .container-fluid { | |
@extend %container-flex-properties; | |
} | |
@each $breakpoint, $container-max-width in $container-max-widths { | |
> .container#{breakpoint-infix($breakpoint, $container-max-widths)} { | |
@extend %container-flex-properties; | |
} | |
} | |
} | |
// Navbar brand | |
// | |
// Used for brand, project, or site names. | |
.navbar-brand { | |
padding-top: $navbar-brand-padding-y; | |
padding-bottom: $navbar-brand-padding-y; | |
margin-right: $navbar-brand-margin-right; | |
@include font-size($navbar-brand-font-size); | |
white-space: nowrap; | |
&:hover, | |
&:focus { | |
text-decoration: none; | |
} | |
} | |
// Navbar nav | |
// | |
// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`). | |
.navbar-nav { | |
display: flex; | |
flex-direction: column; // cannot use `inherit` to get the `.navbar`s value | |
padding-left: 0; | |
margin-bottom: 0; | |
list-style: none; | |
.nav-link { | |
padding-right: 0; | |
padding-left: 0; | |
} | |
.dropdown-menu { | |
position: static; | |
} | |
} | |
// Navbar text | |
// | |
// | |
.navbar-text { | |
padding-top: $nav-link-padding-y; | |
padding-bottom: $nav-link-padding-y; | |
} | |
// 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: 1 0 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: $navbar-toggler-padding-y $navbar-toggler-padding-x; | |
@include font-size($navbar-toggler-font-size); | |
line-height: 1; | |
background-color: transparent; // remove default button style | |
border: $border-width solid transparent; // remove default button style | |
@include border-radius($navbar-toggler-border-radius); | |
@include transition($navbar-toggler-transition); | |
&:hover { | |
text-decoration: none; | |
} | |
&:focus { | |
text-decoration: none; | |
outline: 0; | |
box-shadow: 0 0 0 $navbar-toggler-focus-width; | |
} | |
} | |
// Keep as a separate element so folks can easily override it with another icon | |
// or image file as needed. | |
.navbar-toggler-icon { | |
display: inline-block; | |
width: 1.5em; | |
height: 1.5em; | |
vertical-align: middle; | |
background-repeat: no-repeat; | |
background-position: center; | |
background-size: 100%; | |
} | |
// Generate series of `.navbar-expand-*` responsive classes for configuring | |
// where your navbar collapses. | |
.navbar-expand { | |
@each $breakpoint in map-keys($grid-breakpoints) { | |
$next: breakpoint-next($breakpoint, $grid-breakpoints); | |
$infix: breakpoint-infix($next, $grid-breakpoints); | |
&#{$infix} { | |
@include media-breakpoint-up($next) { | |
flex-wrap: nowrap; | |
justify-content: flex-start; | |
.navbar-nav { | |
flex-direction: row; | |
.dropdown-menu { | |
position: absolute; | |
} | |
.nav-link { | |
padding-right: $navbar-nav-link-padding-x; | |
padding-left: $navbar-nav-link-padding-x; | |
} | |
} | |
.navbar-collapse { | |
display: flex !important; // stylelint-disable-line declaration-no-important | |
// Changes flex-bases to auto because of an IE10 bug | |
flex-basis: auto; | |
} | |
.navbar-toggler { | |
display: none; | |
} | |
} | |
} | |
} | |
} | |
// Navbar themes | |
// | |
// Styles for switching between navbars with light or dark background. | |
// Dark links against a light background | |
.navbar-light { | |
.navbar-brand { | |
color: $navbar-light-brand-color; | |
&:hover, | |
&:focus { | |
color: $navbar-light-brand-hover-color; | |
} | |
} | |
.navbar-nav { | |
.nav-link { | |
color: $navbar-light-color; | |
&:hover, | |
&:focus { | |
color: $navbar-light-hover-color; | |
} | |
&.disabled { | |
color: $navbar-light-disabled-color; | |
} | |
} | |
.show > .nav-link, | |
.active > .nav-link, | |
.nav-link.show, | |
.nav-link.active { | |
color: $navbar-light-active-color; | |
} | |
} | |
.navbar-toggler { | |
color: $navbar-light-color; | |
border-color: $navbar-light-toggler-border-color; | |
} | |
.navbar-toggler-icon { | |
background-image: escape-svg($navbar-light-toggler-icon-bg); | |
} | |
.navbar-text { | |
color: $navbar-light-color; | |
a, | |
a:hover, | |
a:focus { | |
color: $navbar-light-active-color; | |
} | |
} | |
} | |
// White links against a dark background | |
.navbar-dark { | |
.navbar-brand { | |
color: $navbar-dark-brand-color; | |
&:hover, | |
&:focus { | |
color: $navbar-dark-brand-hover-color; | |
} | |
} | |
.navbar-nav { | |
.nav-link { | |
color: $navbar-dark-color; | |
&:hover, | |
&:focus { | |
color: $navbar-dark-hover-color; | |
} | |
&.disabled { | |
color: $navbar-dark-disabled-color; | |
} | |
} | |
.show > .nav-link, | |
.active > .nav-link, | |
.nav-link.show, | |
.nav-link.active { | |
color: $navbar-dark-active-color; | |
} | |
} | |
.navbar-toggler { | |
color: $navbar-dark-color; | |
border-color: $navbar-dark-toggler-border-color; | |
} | |
.navbar-toggler-icon { | |
background-image: escape-svg($navbar-dark-toggler-icon-bg); | |
} | |
.navbar-text { | |
color: $navbar-dark-color; | |
a, | |
a:hover, | |
a:focus { | |
color: $navbar-dark-active-color; | |
} | |
} | |
} | |
// | |
// Base styles | |
// | |
.card { | |
position: relative; | |
display: flex; | |
flex-direction: column; | |
min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106 | |
height: $card-height; | |
word-wrap: break-word; | |
background-color: $card-bg; | |
background-clip: border-box; | |
border: $card-border-width solid $card-border-color; | |
@include border-radius($card-border-radius); | |
> hr { | |
margin-right: 0; | |
margin-left: 0; | |
} | |
> .list-group:first-child { | |
.list-group-item:first-child { | |
@include border-top-radius($card-border-radius); | |
} | |
} | |
> .list-group:last-child { | |
.list-group-item:last-child { | |
@include border-bottom-radius($card-border-radius); | |
} | |
} | |
} | |
.card-body { | |
// Enable `flex-grow: 1` for decks and groups so that card blocks take up | |
// as much space as possible, ensuring footers are aligned to the bottom. | |
flex: 1 1 auto; | |
// Workaround for the image size bug in IE | |
// See: https://github.com/twbs/bootstrap/pull/28855 | |
min-height: 1px; | |
padding: $card-spacer-y $card-spacer-x; | |
color: $card-color; | |
} | |
.card-title { | |
margin-bottom: $card-title-spacer-y; | |
} | |
.card-subtitle { | |
margin-top: -$card-title-spacer-y / 2; | |
margin-bottom: 0; | |
} | |
.card-text:last-child { | |
margin-bottom: 0; | |
} | |
.card-link { | |
&:hover { | |
text-decoration: none; | |
} | |
+ .card-link { | |
margin-left: $card-spacer-x; | |
} | |
} | |
// | |
// Optional textual caps | |
// | |
.card-header { | |
padding: $card-cap-padding-y $card-cap-padding-x; | |
margin-bottom: 0; // Removes the default margin-bottom of <hN> | |
color: $card-cap-color; | |
background-color: $card-cap-bg; | |
border-bottom: $card-border-width solid $card-border-color; | |
&:first-child { | |
@include border-radius($card-inner-border-radius $card-inner-border-radius 0 0); | |
} | |
+ .list-group { | |
.list-group-item:first-child { | |
border-top: 0; | |
} | |
} | |
} | |
.card-footer { | |
padding: $card-cap-padding-y $card-cap-padding-x; | |
background-color: $card-cap-bg; | |
border-top: $card-border-width solid $card-border-color; | |
&:last-child { | |
@include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius); | |
} | |
} | |
// | |
// Header navs | |
// | |
.card-header-tabs { | |
margin-right: -$card-cap-padding-x / 2; | |
margin-bottom: -$card-cap-padding-y; | |
margin-left: -$card-cap-padding-x / 2; | |
border-bottom: 0; | |
@if $nav-tabs-link-active-bg != $card-bg { | |
.nav-link.active { | |
background-color: $card-bg; | |
border-bottom-color: $card-bg; | |
} | |
} | |
} | |
.card-header-pills { | |
margin-right: -$card-cap-padding-x / 2; | |
margin-left: -$card-cap-padding-x / 2; | |
} | |
// Card image | |
.card-img-overlay { | |
position: absolute; | |
top: 0; | |
right: 0; | |
bottom: 0; | |
left: 0; | |
padding: $card-img-overlay-padding; | |
} | |
.card-img, | |
.card-img-top, | |
.card-img-bottom { | |
flex-shrink: 0; // For IE: https://github.com/twbs/bootstrap/issues/29396 | |
width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch | |
} | |
.card-img, | |
.card-img-top { | |
@include border-top-radius($card-inner-border-radius); | |
} | |
.card-img, | |
.card-img-bottom { | |
@include border-bottom-radius($card-inner-border-radius); | |
} | |
// Card deck | |
.card-deck { | |
.card { | |
margin-bottom: $card-deck-margin; | |
} | |
@include media-breakpoint-up(sm) { | |
display: flex; | |
flex-flow: row wrap; | |
margin-right: -$card-deck-margin; | |
margin-left: -$card-deck-margin; | |
.card { | |
// Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4 | |
flex: 1 0 0%; | |
margin-right: $card-deck-margin; | |
margin-bottom: 0; // Override the default | |
margin-left: $card-deck-margin; | |
} | |
} | |
} | |
// | |
// Card groups | |
// | |
.card-group { | |
// The child selector allows nested `.card` within `.card-group` | |
// to display properly. | |
> .card { | |
margin-bottom: $card-group-margin; | |
} | |
@include media-breakpoint-up(sm) { | |
display: flex; | |
flex-flow: row wrap; | |
// The child selector allows nested `.card` within `.card-group` | |
// to display properly. | |
> .card { | |
// Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4 | |
flex: 1 0 0%; | |
margin-bottom: 0; | |
+ .card { | |
margin-left: 0; | |
border-left: 0; | |
} | |
// Handle rounded corners | |
@if $enable-rounded { | |
&:not(:last-child) { | |
@include border-right-radius(0); | |
.card-img-top, | |
.card-header { | |
// stylelint-disable-next-line property-blacklist | |
border-top-right-radius: 0; | |
} | |
.card-img-bottom, | |
.card-footer { | |
// stylelint-disable-next-line property-blacklist | |
border-bottom-right-radius: 0; | |
} | |
} | |
&:not(:first-child) { | |
@include border-left-radius(0); | |
.card-img-top, | |
.card-header { | |
// stylelint-disable-next-line property-blacklist | |
border-top-left-radius: 0; | |
} | |
.card-img-bottom, | |
.card-footer { | |
// stylelint-disable-next-line property-blacklist | |
border-bottom-left-radius: 0; | |
} | |
} | |
} | |
} | |
} | |
} | |
// | |
// Accordion | |
// | |
.accordion { | |
> .card { | |
overflow: hidden; | |
&:not(:last-of-type) { | |
border-bottom: 0; | |
@include border-bottom-radius(0); | |
} | |
&:not(:first-of-type) { | |
@include border-top-radius(0); | |
} | |
> .card-header { | |
@include border-radius(0); | |
margin-bottom: -$card-border-width; | |
} | |
} | |
} | |
.breadcrumb { | |
display: flex; | |
flex-wrap: wrap; | |
padding: $breadcrumb-padding-y $breadcrumb-padding-x; | |
margin-bottom: $breadcrumb-margin-bottom; | |
@include font-size($breadcrumb-font-size); | |
list-style: none; | |
background-color: $breadcrumb-bg; | |
@include border-radius($breadcrumb-border-radius); | |
} | |
.breadcrumb-item { | |
display: flex; | |
// The separator between breadcrumbs (by default, a forward-slash: "/") | |
+ .breadcrumb-item { | |
padding-left: $breadcrumb-item-padding-x; | |
&::before { | |
display: inline-block; // Suppress underlining of the separator in modern browsers | |
padding-right: $breadcrumb-item-padding-x; | |
color: $breadcrumb-divider-color; | |
content: escape-svg($breadcrumb-divider); | |
} | |
} | |
// IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built | |
// without `<ul>`s. The `::before` pseudo-element generates an element | |
// *within* the .breadcrumb-item and thereby inherits the `text-decoration`. | |
// | |
// To trick IE into suppressing the underline, we give the pseudo-element an | |
// underline and then immediately remove it. | |
+ .breadcrumb-item:hover::before { | |
text-decoration: underline; | |
} | |
// stylelint-disable-next-line no-duplicate-selectors | |
+ .breadcrumb-item:hover::before { | |
text-decoration: none; | |
} | |
&.active { | |
color: $breadcrumb-active-color; | |
} | |
} | |
.pagination { | |
display: flex; | |
@include list-unstyled(); | |
} | |
.page-link { | |
position: relative; | |
display: block; | |
color: $pagination-color; | |
background-color: $pagination-bg; | |
border: $pagination-border-width solid $pagination-border-color; | |
&:hover { | |
z-index: 2; | |
color: $pagination-hover-color; | |
text-decoration: none; | |
background-color: $pagination-hover-bg; | |
border-color: $pagination-hover-border-color; | |
} | |
&:focus { | |
z-index: 3; | |
outline: $pagination-focus-outline; | |
box-shadow: $pagination-focus-box-shadow; | |
} | |
} | |
.page-item { | |
&:not(:first-child) .page-link { | |
margin-left: $pagination-margin-left; | |
} | |
&.active .page-link { | |
z-index: 3; | |
color: $pagination-active-color; | |
background-color: $pagination-active-bg; | |
border-color: $pagination-active-border-color; | |
} | |
&.disabled .page-link { | |
color: $pagination-disabled-color; | |
pointer-events: none; | |
background-color: $pagination-disabled-bg; | |
border-color: $pagination-disabled-border-color; | |
} | |
} | |
// | |
// Sizing | |
// | |
@include pagination-size($pagination-padding-y, $pagination-padding-x, null, $pagination-border-radius); | |
.pagination-lg { | |
@include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $border-radius-lg); | |
} | |
.pagination-sm { | |
@include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $border-radius-sm); | |
} | |
// Base class | |
// | |
// Requires one of the contextual, color modifier classes for `color` and | |
// `background-color`. | |
.badge { | |
display: inline-block; | |
padding: $badge-padding-y $badge-padding-x; | |
@include font-size($badge-font-size); | |
font-weight: $badge-font-weight; | |
line-height: 1; | |
color: $badge-color; | |
text-align: center; | |
white-space: nowrap; | |
vertical-align: baseline; | |
@include border-radius($badge-border-radius); | |
// Empty badges collapse automatically | |
&:empty { | |
display: none; | |
} | |
} | |
// Quick fix for badges in buttons | |
.btn .badge { | |
position: relative; | |
top: -1px; | |
} | |
// | |
// Base styles | |
// | |
.alert { | |
position: relative; | |
padding: $alert-padding-y $alert-padding-x; | |
margin-bottom: $alert-margin-bottom; | |
border: $alert-border-width solid transparent; | |
@include border-radius($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; | |
} | |
// Dismissible alerts | |
// | |
// Expand the right padding and account for the close button's positioning. | |
.alert-dismissible { | |
padding-right: $close-font-size + $alert-padding-x * 2; | |
// Adjust close link position | |
.close { | |
position: absolute; | |
top: 0; | |
right: 0; | |
padding: $alert-padding-y $alert-padding-x; | |
color: inherit; | |
} | |
} | |
// Alternate styles | |
// | |
// Generate contextual modifier classes for colorizing the alert. | |
@each $color, $value in $theme-colors { | |
.alert-#{$color} { | |
@include alert-variant(color-level($value, $alert-bg-level), color-level($value, $alert-border-level), color-level($value, $alert-color-level)); | |
} | |
} | |
// Disable animation if transitions are disabled | |
@if $enable-transitions { | |
@keyframes progress-bar-stripes { | |
0% { background-position-x: $progress-height; } | |
} | |
} | |
.progress { | |
display: flex; | |
height: $progress-height; | |
overflow: hidden; // force rounded corners by cropping it | |
@include font-size($progress-font-size); | |
background-color: $progress-bg; | |
@include border-radius($progress-border-radius); | |
@include box-shadow($progress-box-shadow); | |
} | |
.progress-bar { | |
display: flex; | |
flex-direction: column; | |
justify-content: center; | |
overflow: hidden; | |
color: $progress-bar-color; | |
text-align: center; | |
white-space: nowrap; | |
background-color: $progress-bar-bg; | |
@include transition($progress-bar-transition); | |
} | |
.progress-bar-striped { | |
@include gradient-striped(); | |
background-size: $progress-height $progress-height; | |
} | |
@if $enable-transitions { | |
.progress-bar-animated { | |
animation: progress-bar-stripes $progress-bar-animation-timing; | |
@if $enable-prefers-reduced-motion-media-query { | |
@media (prefers-reduced-motion: reduce) { | |
animation: none; | |
} | |
} | |
} | |
} | |
// Base class | |
// | |
// Easily usable on <ul>, <ol>, or <div>. | |
.list-group { | |
display: flex; | |
flex-direction: column; | |
// No need to set list-style: none; since .list-group-item is block level | |
padding-left: 0; // reset padding because ul and ol | |
margin-bottom: 0; | |
} | |
// 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: $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: $list-group-action-hover-color; | |
text-decoration: none; | |
background-color: $list-group-hover-bg; | |
} | |
&:active { | |
color: $list-group-action-active-color; | |
background-color: $list-group-action-active-bg; | |
} | |
} | |
// Individual list items | |
// | |
// Use on `li`s or `div`s within the `.list-group` parent. | |
.list-group-item { | |
position: relative; | |
display: block; | |
padding: $list-group-item-padding-y $list-group-item-padding-x; | |
margin-bottom: 0; // for <label> variations | |
color: $list-group-color; | |
background-color: $list-group-bg; | |
border: $list-group-border-width solid $list-group-border-color; | |
&:first-child { | |
@include border-top-radius($list-group-border-radius); | |
} | |
&:last-child { | |
@include border-bottom-radius($list-group-border-radius); | |
} | |
&.disabled, | |
&:disabled { | |
color: $list-group-disabled-color; | |
pointer-events: none; | |
background-color: $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: $list-group-active-color; | |
background-color: $list-group-active-bg; | |
border-color: $list-group-active-border-color; | |
} | |
& + & { | |
border-top-width: 0; | |
&.active { | |
margin-top: -$list-group-border-width; | |
border-top-width: $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 { | |
@include border-bottom-left-radius($list-group-border-radius); | |
@include border-top-right-radius(0); | |
} | |
&:last-child { | |
@include border-top-right-radius($list-group-border-radius); | |
@include border-bottom-left-radius(0); | |
} | |
&.active { | |
margin-top: 0; | |
} | |
& + .list-group-item { | |
border-top-width: $list-group-border-width; | |
border-left-width: 0; | |
&.active { | |
margin-left: -$list-group-border-width; | |
border-left-width: $list-group-border-width; | |
} | |
} | |
} | |
} | |
} | |
} | |
// Flush list items | |
// | |
// Remove borders and border-radius to keep list group items edge-to-edge. Most | |
// useful within other components (e.g., cards). | |
.list-group-flush { | |
.list-group-item { | |
border-right-width: 0; | |
border-left-width: 0; | |
@include border-radius(0); | |
&:first-child { | |
border-top-width: 0; | |
} | |
} | |
&:last-child { | |
.list-group-item:last-child { | |
border-bottom-width: 0; | |
} | |
} | |
} | |
// Contextual variants | |
// | |
// Add modifier classes to change text and background color on individual items. | |
// Organizationally, this must come after the `:hover` states. | |
@each $color, $value in $theme-colors { | |
@include list-group-item-variant($color, color-level($value, -9), color-level($value, 6)); | |
} | |
.close { | |
@include font-size($close-font-size); | |
font-weight: $close-font-weight; | |
line-height: 1; | |
color: $close-color; | |
text-shadow: $close-text-shadow; | |
opacity: .5; | |
// Override <a>'s hover style | |
&:hover { | |
color: $close-color; | |
text-decoration: none; | |
} | |
&:hover, | |
&:focus { | |
opacity: .75; | |
} | |
&:disabled, | |
&.disabled { | |
pointer-events: none; | |
} | |
} | |
// Additional properties for button version | |
// iOS requires the button element instead of an anchor tag. | |
// If you want the anchor version, it requires `href="#"`. | |
// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile | |
// stylelint-disable-next-line selector-no-qualifying-type | |
button.close { | |
padding: 0; | |
background-color: transparent; | |
border: 0; | |
appearance: none; | |
} | |
.toast { | |
max-width: $toast-max-width; | |
overflow: hidden; // cheap rounded corners on nested items | |
@include font-size($toast-font-size); | |
color: $toast-color; | |
background-color: $toast-background-color; | |
background-clip: padding-box; | |
border: $toast-border-width solid $toast-border-color; | |
box-shadow: $toast-box-shadow; | |
backdrop-filter: blur(10px); | |
opacity: 0; | |
@include border-radius($toast-border-radius); | |
&:not(:last-child) { | |
margin-bottom: $toast-padding-x; | |
} | |
&.showing { | |
opacity: 1; | |
} | |
&.show { | |
display: block; | |
opacity: 1; | |
} | |
&.hide { | |
display: none; | |
} | |
} | |
.toast-header { | |
display: flex; | |
align-items: center; | |
padding: $toast-padding-y $toast-padding-x; | |
color: $toast-header-color; | |
background-color: $toast-header-background-color; | |
background-clip: padding-box; | |
border-bottom: $toast-border-width solid $toast-header-border-color; | |
} | |
.toast-body { | |
padding: $toast-padding-x; // apply to both vertical and horizontal | |
} | |
// .modal-open - body class for killing the scroll | |
// .modal - container to scroll within | |
// .modal-dialog - positioning shell for the actual modal | |
// .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; | |
top: 0; | |
left: 0; | |
z-index: $zindex-modal; | |
display: none; | |
width: 100%; | |
height: 100%; | |
overflow: hidden; | |
// 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: $modal-dialog-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 & { | |
@include transition($modal-transition); | |
transform: $modal-fade-transform; | |
} | |
.modal.show & { | |
transform: $modal-show-transform; | |
} | |
// When trying to close, animate focus to scale | |
.modal.modal-static & { | |
transform: $modal-scale-transform; | |
} | |
} | |
.modal-dialog-scrollable { | |
display: flex; // IE10/11 | |
max-height: subtract(100%, $modal-dialog-margin * 2); | |
.modal-content { | |
max-height: subtract(100vh, $modal-dialog-margin * 2); // IE10/11 | |
overflow: hidden; | |
} | |
.modal-header, | |
.modal-footer { | |
flex-shrink: 0; | |
} | |
.modal-body { | |
overflow-y: auto; | |
} | |
} | |
.modal-dialog-centered { | |
display: flex; | |
align-items: center; | |
min-height: subtract(100%, $modal-dialog-margin * 2); | |
// Ensure `modal-dialog-centered` extends the full height of the view (IE10/11) | |
&::before { | |
display: block; // IE10 | |
height: subtract(100vh, $modal-dialog-margin * 2); | |
content: ""; | |
} | |
// Ensure `.modal-body` shows scrollbar (IE10/11) | |
&.modal-dialog-scrollable { | |
flex-direction: column; | |
justify-content: center; | |
height: 100%; | |
.modal-content { | |
max-height: none; | |
} | |
&::before { | |
content: none; | |
} | |
} | |
} | |
// 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: $modal-content-color; | |
pointer-events: auto; | |
background-color: $modal-content-bg; | |
background-clip: padding-box; | |
border: $modal-content-border-width solid $modal-content-border-color; | |
@include border-radius($modal-content-border-radius); | |
@include box-shadow($modal-content-box-shadow-xs); | |
// Remove focus outline from opened modal | |
outline: 0; | |
} | |
// 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; } | |
} | |
// Modal header | |
// Top section of the modal w/ title and dismiss | |
.modal-header { | |
display: flex; | |
align-items: flex-start; // so the close btn always stays on the upper right corner | |
justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends | |
padding: $modal-header-padding; | |
border-bottom: $modal-header-border-width solid $modal-header-border-color; | |
@include border-top-radius($modal-content-inner-border-radius); | |
.close { | |
padding: $modal-header-padding; | |
// auto on the left force icon to the right even when there is no .modal-title | |
margin: (-$modal-header-padding-y) (-$modal-header-padding-x) (-$modal-header-padding-y) auto; | |
} | |
} | |
// Title text within header | |
.modal-title { | |
margin-bottom: 0; | |
line-height: $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: $modal-inner-padding; | |
} | |
// Footer (for actions) | |
.modal-footer { | |
display: flex; | |
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: $modal-inner-padding - $modal-footer-margin-between / 2; | |
border-top: $modal-footer-border-width solid $modal-footer-border-color; | |
@include border-bottom-radius($modal-content-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: $modal-footer-margin-between / 2; | |
} | |
} | |
// 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 | |
.modal-dialog { | |
max-width: $modal-md; | |
margin: $modal-dialog-margin-y-sm-up auto; | |
} | |
.modal-dialog-scrollable { | |
max-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2); | |
.modal-content { | |
max-height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2); | |
} | |
} | |
.modal-dialog-centered { | |
min-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2); | |
&::before { | |
height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2); | |
} | |
} | |
.modal-content { | |
@include box-shadow($modal-content-box-shadow-sm-up); | |
} | |
.modal-sm { max-width: $modal-sm; } | |
} | |
@include media-breakpoint-up(lg) { | |
.modal-lg, | |
.modal-xl { | |
max-width: $modal-lg; | |
} | |
} | |
@include media-breakpoint-up(xl) { | |
.modal-xl { max-width: $modal-xl; } | |
} | |
// Base class | |
.tooltip { | |
position: absolute; | |
z-index: $zindex-tooltip; | |
display: block; | |
margin: $tooltip-margin; | |
// 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($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: $tooltip-opacity; } | |
.tooltip-arrow { | |
position: absolute; | |
display: block; | |
width: $tooltip-arrow-width; | |
height: $tooltip-arrow-height; | |
&::before { | |
position: absolute; | |
content: ""; | |
border-color: transparent; | |
border-style: solid; | |
} | |
} | |
} | |
.bs-tooltip-top { | |
padding: $tooltip-arrow-height 0; | |
.tooltip-arrow { | |
bottom: 0; | |
&::before { | |
top: 0; | |
border-width: $tooltip-arrow-height ($tooltip-arrow-width / 2) 0; | |
border-top-color: $tooltip-arrow-color; | |
} | |
} | |
} | |
.bs-tooltip-right { | |
padding: 0 $tooltip-arrow-height; | |
.tooltip-arrow { | |
left: 0; | |
width: $tooltip-arrow-height; | |
height: $tooltip-arrow-width; | |
&::before { | |
right: 0; | |
border-width: ($tooltip-arrow-width / 2) $tooltip-arrow-height ($tooltip-arrow-width / 2) 0; | |
border-right-color: $tooltip-arrow-color; | |
} | |
} | |
} | |
.bs-tooltip-bottom { | |
padding: $tooltip-arrow-height 0; | |
.tooltip-arrow { | |
top: 0; | |
&::before { | |
bottom: 0; | |
border-width: 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height; | |
border-bottom-color: $tooltip-arrow-color; | |
} | |
} | |
} | |
.bs-tooltip-left { | |
padding: 0 $tooltip-arrow-height; | |
.tooltip-arrow { | |
right: 0; | |
width: $tooltip-arrow-height; | |
height: $tooltip-arrow-width; | |
&::before { | |
left: 0; | |
border-width: ($tooltip-arrow-width / 2) 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height; | |
border-left-color: $tooltip-arrow-color; | |
} | |
} | |
} | |
.bs-tooltip-auto { | |
&[x-placement^="top"] { | |
@extend .bs-tooltip-top; | |
} | |
&[x-placement^="right"] { | |
@extend .bs-tooltip-right; | |
} | |
&[x-placement^="bottom"] { | |
@extend .bs-tooltip-bottom; | |
} | |
&[x-placement^="left"] { | |
@extend .bs-tooltip-left; | |
} | |
} | |
// Wrapper for the tooltip content | |
.tooltip-inner { | |
max-width: $tooltip-max-width; | |
padding: $tooltip-padding-y $tooltip-padding-x; | |
color: $tooltip-color; | |
text-align: center; | |
background-color: $tooltip-bg; | |
@include border-radius($tooltip-border-radius); | |
} | |
.popover { | |
position: absolute; | |
top: 0; | |
left: 0; | |
z-index: $zindex-popover; | |
display: block; | |
max-width: $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($popover-font-size); | |
// Allow breaking very long words so they don't overflow the popover's bounds | |
word-wrap: break-word; | |
background-color: $popover-bg; | |
background-clip: padding-box; | |
border: $popover-border-width solid $popover-border-color; | |
@include border-radius($popover-border-radius); | |
@include box-shadow($popover-box-shadow); | |
.popover-arrow { | |
position: absolute; | |
display: block; | |
width: $popover-arrow-width; | |
height: $popover-arrow-height; | |
margin: 0 $popover-border-radius; | |
&::before, | |
&::after { | |
position: absolute; | |
display: block; | |
content: ""; | |
border-color: transparent; | |
border-style: solid; | |
} | |
} | |
} | |
.bs-popover-top { | |
margin-bottom: $popover-arrow-height; | |
> .popover-arrow { | |
bottom: subtract(-$popover-arrow-height, $popover-border-width); | |
&::before { | |
bottom: 0; | |
border-width: $popover-arrow-height ($popover-arrow-width / 2) 0; | |
border-top-color: $popover-arrow-outer-color; | |
} | |
&::after { | |
bottom: $popover-border-width; | |
border-width: $popover-arrow-height ($popover-arrow-width / 2) 0; | |
border-top-color: $popover-arrow-color; | |
} | |
} | |
} | |
.bs-popover-right { | |
margin-left: $popover-arrow-height; | |
> .popover-arrow { | |
left: subtract(-$popover-arrow-height, $popover-border-width); | |
width: $popover-arrow-height; | |
height: $popover-arrow-width; | |
margin: $popover-border-radius 0; // make sure the arrow does not touch the popover's rounded corners | |
&::before { | |
left: 0; | |
border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 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-right-color: $popover-arrow-color; | |
} | |
} | |
} | |
.bs-popover-bottom { | |
margin-top: $popover-arrow-height; | |
> .popover-arrow { | |
top: subtract(-$popover-arrow-height, $popover-border-width); | |
&::before { | |
top: 0; | |
border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2); | |
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-bottom-color: $popover-arrow-color; | |
} | |
} | |
// This will remove the popover-header's border just below the arrow | |
.popover-header::before { | |
position: absolute; | |
top: 0; | |
left: 50%; | |
display: block; | |
width: $popover-arrow-width; | |
margin-left: -$popover-arrow-width / 2; | |
content: ""; | |
border-bottom: $popover-border-width solid $popover-header-bg; | |
} | |
} | |
.bs-popover-left { | |
margin-right: $popover-arrow-height; | |
> .popover-arrow { | |
right: subtract(-$popover-arrow-height, $popover-border-width); | |
width: $popover-arrow-height; | |
height: $popover-arrow-width; | |
margin: $popover-border-radius 0; // make sure the arrow does not touch the popover's rounded corners | |
&::before { | |
right: 0; | |
border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $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-left-color: $popover-arrow-color; | |
} | |
} | |
} | |
.bs-popover-auto { | |
&[x-placement^="top"] { | |
@extend .bs-popover-top; | |
} | |
&[x-placement^="right"] { | |
@extend .bs-popover-right; | |
} | |
&[x-placement^="bottom"] { | |
@extend .bs-popover-bottom; | |
} | |
&[x-placement^="left"] { | |
@extend .bs-popover-left; | |
} | |
} | |
// Offset the popover to account for the popover arrow | |
.popover-header { | |
padding: $popover-header-padding-y $popover-header-padding-x; | |
margin-bottom: 0; // Reset the default from Reboot | |
@include font-size($font-size-base); | |
color: $popover-header-color; | |
background-color: $popover-header-bg; | |
border-bottom: $popover-border-width solid darken($popover-header-bg, 5%); | |
@include border-top-radius($popover-inner-border-radius); | |
&:empty { | |
display: none; | |
} | |
} | |
.popover-body { | |
padding: $popover-body-padding-y $popover-body-padding-x; | |
color: $popover-body-color; | |
} | |
// Notes on the classes: | |
// | |
// 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically) | |
// even when their scroll action started on a carousel, but for compatibility (with Firefox) | |
// we're preventing all actions instead | |
// 2. The .carousel-item-left and .carousel-item-right is used to indicate where | |
// the active slide is heading. | |
// 3. .active.carousel-item is the current slide. | |
// 4. .active.carousel-item-left and .active.carousel-item-right is the current | |
// slide in its in-transition state. Only one of these occurs at a time. | |
// 5. .carousel-item-next.carousel-item-left and .carousel-item-prev.carousel-item-right | |
// is the upcoming slide in transition. | |
.carousel { | |
position: relative; | |
} | |
.carousel.pointer-event { | |
touch-action: pan-y; | |
} | |
.carousel-inner { | |
position: relative; | |
width: 100%; | |
overflow: hidden; | |
@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-left), | |
.active.carousel-item-right { | |
transform: translateX(100%); | |
} | |
.carousel-item-prev:not(.carousel-item-right), | |
.active.carousel-item-left { | |
transform: translateX(-100%); | |
} | |
// | |
// Alternate transitions | |
// | |
.carousel-fade { | |
.carousel-item { | |
opacity: 0; | |
transition-property: opacity; | |
transform: none; | |
} | |
.carousel-item.active, | |
.carousel-item-next.carousel-item-left, | |
.carousel-item-prev.carousel-item-right { | |
z-index: 1; | |
opacity: 1; | |
} | |
.active.carousel-item-left, | |
.active.carousel-item-right { | |
z-index: 0; | |
opacity: 0; | |
@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; | |
color: $carousel-control-color; | |
text-align: center; | |
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; | |
@if $enable-gradients { | |
background-image: linear-gradient(90deg, rgba($black, .25), rgba($black, .001)); | |
} | |
} | |
.carousel-control-next { | |
right: 0; | |
@if $enable-gradients { | |
background-image: linear-gradient(270deg, rgba($black, .25), rgba($black, .001)); | |
} | |
} | |
// 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: no-repeat 50% / 100% 100%; | |
} | |
.carousel-control-prev-icon { | |
background-image: escape-svg($carousel-control-prev-icon-bg); | |
} | |
.carousel-control-next-icon { | |
background-image: escape-svg($carousel-control-next-icon-bg); | |
} | |
// Optional indicator pips | |
// | |
// Add an ordered list with the following class and add a list item 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-left: 0; // override <ol> default | |
// Use the .carousel-control's width as margin so we don't overlay those | |
margin-right: $carousel-control-width; | |
margin-left: $carousel-control-width; | |
list-style: none; | |
li { | |
box-sizing: content-box; | |
flex: 0 1 auto; | |
width: $carousel-indicator-width; | |
height: $carousel-indicator-height; | |
margin-right: $carousel-indicator-spacer; | |
margin-left: $carousel-indicator-spacer; | |
text-indent: -999px; | |
cursor: pointer; | |
background-color: $carousel-indicator-active-bg; | |
background-clip: padding-box; | |
// 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 | |
// | |
// | |
.carousel-caption { | |
position: absolute; | |
right: (100% - $carousel-caption-width) / 2; | |
bottom: $carousel-caption-spacer; | |
left: (100% - $carousel-caption-width) / 2; | |
padding-top: $carousel-caption-padding-y; | |
padding-bottom: $carousel-caption-padding-y; | |
color: $carousel-caption-color; | |
text-align: center; | |
} | |
// | |
// Rotating border | |
// | |
@keyframes spinner-border { | |
to { transform: rotate(360deg); } | |
} | |
.spinner-border { | |
display: inline-block; | |
width: $spinner-width; | |
height: $spinner-height; | |
vertical-align: text-bottom; | |
border: $spinner-border-width solid currentColor; | |
border-right-color: transparent; | |
// stylelint-disable-next-line property-blacklist | |
border-radius: 50%; | |
animation: spinner-border $spinner-animation-speed linear infinite; | |
} | |
.spinner-border-sm { | |
width: $spinner-width-sm; | |
height: $spinner-height-sm; | |
border-width: $spinner-border-width-sm; | |
} | |
// | |
// Growing circle | |
// | |
@keyframes spinner-grow { | |
0% { | |
transform: scale(0); | |
} | |
50% { | |
opacity: 1; | |
} | |
} | |
.spinner-grow { | |
display: inline-block; | |
width: $spinner-width; | |
height: $spinner-height; | |
vertical-align: text-bottom; | |
background-color: currentColor; | |
// stylelint-disable-next-line property-blacklist | |
border-radius: 50%; | |
opacity: 0; | |
animation: spinner-grow $spinner-animation-speed linear infinite; | |
} | |
.spinner-grow-sm { | |
width: $spinner-width-sm; | |
height: $spinner-height-sm; | |
} | |
@if $enable-gradients { | |
@each $color, $value in $theme-colors { | |
@include bg-gradient-variant(".bg-gradient-#{$color}", $value); | |
} | |
} | |
.clearfix { | |
@include clearfix(); | |
} | |
@each $color, $value in $theme-colors { | |
.link-#{$color} { | |
color: $value; | |
@if $emphasized-link-hover-darken-percentage != 0 { | |
&:hover, | |
&:focus { | |
color: darken($value, $emphasized-link-hover-darken-percentage); | |
} | |
} | |
} | |
} | |
// Credit: Nicolas Gallagher and SUIT CSS. | |
.embed-responsive { | |
position: relative; | |
width: 100%; | |
&::before { | |
display: block; | |
content: ""; | |
} | |
.embed-responsive-item, | |
iframe, | |
embed, | |
object, | |
video { | |
position: absolute; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
border: 0; | |
} | |
} | |
@each $key, $ratio in $embed-responsive-aspect-ratios { | |
.embed-responsive-#{$key} { | |
&::before { | |
padding-top: percentage(map-get($ratio, y) / map-get($ratio, x)); | |
} | |
} | |
} | |
// Shorthand | |
.fixed-top { | |
position: fixed; | |
top: 0; | |
right: 0; | |
left: 0; | |
z-index: $zindex-fixed; | |
} | |
.fixed-bottom { | |
position: fixed; | |
right: 0; | |
bottom: 0; | |
left: 0; | |
z-index: $zindex-fixed; | |
} | |
// Responsive sticky top | |
@supports (position: sticky) { | |
@each $breakpoint in map-keys($grid-breakpoints) { | |
@include media-breakpoint-up($breakpoint) { | |
$infix: breakpoint-infix($breakpoint, $grid-breakpoints); | |
.sticky#{$infix}-top { | |
position: sticky; | |
top: 0; | |
z-index: $zindex-sticky; | |
} | |
} | |
} | |
} | |
// | |
// Screenreaders | |
// | |
.sr-only, | |
.sr-only-focusable:not(:focus) { | |
@include sr-only(); | |
} | |
// | |
// Stretched link | |
// | |
.stretched-link { | |
&::#{$stretched-link-pseudo-element} { | |
position: absolute; | |
top: 0; | |
right: 0; | |
bottom: 0; | |
left: 0; | |
z-index: $stretched-link-z-index; | |
content: ""; | |
} | |
} | |
// | |
// Text truncation | |
// | |
.text-truncate { | |
@include text-truncate(); | |
} | |
// Loop over each breakpoint | |
@each $breakpoint in map-keys($grid-breakpoints) { | |
// 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); | |
} | |
} | |
} | |
} | |
// Print utilities | |
@media print { | |
@each $key, $utility in $utilities { | |
// The utility can be disabled with `false`, thus check if the utility is a map first | |
// Then check if the utility needs print styles | |
@if type-of($utility) == "map" and map-get($utility, print) == true { | |
@include generate-utility($utility, "-print"); | |
} | |
} | |
} | |
/*! | |
* Bootstrap v4.3.1 (https://getbootstrap.com/) | |
* Copyright 2011-2020 The Bootstrap Authors | |
* Copyright 2011-2020 Twitter, Inc. | |
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | |
*/ | |
// Configuration | |
// Layout & components | |
// Helpers | |
// Utilities | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment