diff --git a/scss/_functions.scss b/scss/_functions.scss index ad0e7a6679ed..00179049c1a6 100644 --- a/scss/_functions.scss +++ b/scss/_functions.scss @@ -88,14 +88,43 @@ } // Color contrast -@function color-yiq($color, $dark: $yiq-text-dark, $light: $yiq-text-light) { - $r: red($color); - $g: green($color); - $b: blue($color); +// See https://github.com/twbs/bootstrap/pull/30168 - $yiq: (($r * 299) + ($g * 587) + ($b * 114)) / 1000; +// A list of pre-calculated numbers of pow(($value / 255 + .055) / 1.055, 2.4). (from 0 to 255) +// stylelint-disable-next-line scss/dollar-variable-default, scss/dollar-variable-pattern +$_luminance-list: .0008 .001 .0011 .0013 .0015 .0017 .002 .0022 .0025 .0027 .003 .0033 .0037 .004 .0044 .0048 .0052 .0056 .006 .0065 .007 .0075 .008 .0086 .0091 .0097 .0103 .011 .0116 .0123 .013 .0137 .0144 .0152 .016 .0168 .0176 .0185 .0194 .0203 .0212 .0222 .0232 .0242 .0252 .0262 .0273 .0284 .0296 .0307 .0319 .0331 .0343 .0356 .0369 .0382 .0395 .0409 .0423 .0437 .0452 .0467 .0482 .0497 .0513 .0529 .0545 .0561 .0578 .0595 .0612 .063 .0648 .0666 .0685 .0704 .0723 .0742 .0762 .0782 .0802 .0823 .0844 .0865 .0887 .0908 .0931 .0953 .0976 .0999 .1022 .1046 .107 .1095 .1119 .1144 .117 .1195 .1221 .1248 .1274 .1301 .1329 .1356 .1384 .1413 .1441 .147 .15 .1529 .1559 .159 .162 .1651 .1683 .1714 .1746 .1779 .1812 .1845 .1878 .1912 .1946 .1981 .2016 .2051 .2086 .2122 .2159 .2195 .2232 .227 .2307 .2346 .2384 .2423 .2462 .2502 .2542 .2582 .2623 .2664 .2705 .2747 .2789 .2831 .2874 .2918 .2961 .3005 .305 .3095 .314 .3185 .3231 .3278 .3325 .3372 .3419 .3467 .3515 .3564 .3613 .3663 .3712 .3763 .3813 .3864 .3916 .3968 .402 .4072 .4125 .4179 .4233 .4287 .4342 .4397 .4452 .4508 .4564 .4621 .4678 .4735 .4793 .4851 .491 .4969 .5029 .5089 .5149 .521 .5271 .5333 .5395 .5457 .552 .5583 .5647 .5711 .5776 .5841 .5906 .5972 .6038 .6105 .6172 .624 .6308 .6376 .6445 .6514 .6584 .6654 .6724 .6795 .6867 .6939 .7011 .7084 .7157 .7231 .7305 .7379 .7454 .7529 .7605 .7682 .7758 .7835 .7913 .7991 .807 .8148 .8228 .8308 .8388 .8469 .855 .8632 .8714 .8796 .8879 .8963 .9047 .9131 .9216 .9301 .9387 .9473 .956 .9647 .9734 .9823 .9911 1; - @return if($yiq >= $yiq-contrasted-threshold, $dark, $light); +@function color-contrast($background, $color-contrast-dark: $color-contrast-dark, $color-contrast-light: $color-contrast-light) { + $l1: luminance($background); + $l2: luminance(opaque($background, $color-contrast-light)); + + $contrast: if($l1 > $l2, ($l1 + .05) / ($l2 + .05), ($l2 + .05) / ($l1 + .05)); + + @return if($contrast < $min-contrast-ratio, $color-contrast-dark, $color-contrast-light); +} + +// Return WCAG2.0 relative luminance +// See https://www.w3.org/WAI/GL/wiki/Relative_luminance +// See https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests +@function luminance($color) { + $rgb: ( + "r": red($color), + "g": green($color), + "b": blue($color) + ); + + @each $name, $value in $rgb { + $value: if($value / 255 < .03928, $value / 255 / 12.92, nth($_luminance-list, $value + 1)); + $rgb: map-merge($rgb, ($name: $value)); + } + + @return (map-get($rgb, "r") * .2126) + (map-get($rgb, "g") * .7152) + (map-get($rgb, "b") * .0722); +} + +// Return opaque color +// opaque(#fff, rgba(0, 0, 0, .5)) => #808080 +@function opaque($background, $foreground) { + @return mix(rgba($foreground, 1), $background, opacity($foreground) * 100); } // Request a color level diff --git a/scss/_variables.scss b/scss/_variables.scss index 7818a09d8acb..5060a2066144 100644 --- a/scss/_variables.scss +++ b/scss/_variables.scss @@ -79,14 +79,15 @@ $theme-colors: ( ) !default; // Set a specific jump point for requesting color jumps -$theme-color-interval: 8% !default; +$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; +// The contrast ratio to reach against white, to determine if color changes from "light" to "dark". Acceptable values for WCAG 2.0 are 3, 4.5 and 7. +// See https://www.w3.org/TR/WCAG20/#visual-audio-contrast-contrast +$min-contrast-ratio: 3 !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; +// Customize the light and dark text colors for use in our color contrast function. +$color-contrast-dark: $gray-900 !default; +$color-contrast-light: $white !default; // fusv-disable $blue-100: tint-color($blue, 8) !default; diff --git a/scss/mixins/_buttons.scss b/scss/mixins/_buttons.scss index acf6b450c500..53a337ba0327 100644 --- a/scss/mixins/_buttons.scss +++ b/scss/mixins/_buttons.scss @@ -6,13 +6,13 @@ @mixin button-variant( $background, $border, - $color: color-yiq($background), + $color: color-contrast($background), $hover-background: darken($background, 7.5%), $hover-border: darken($border, 10%), - $hover-color: color-yiq($hover-background), + $hover-color: color-contrast($hover-background), $active-background: darken($background, 10%), $active-border: darken($border, 12.5%), - $active-color: color-yiq($active-background) + $active-color: color-contrast($active-background) ) { color: $color; @include gradient-bg($background); @@ -69,10 +69,10 @@ @mixin button-outline-variant( $color, - $color-hover: color-yiq($color), + $color-hover: color-contrast($color), $active-background: $color, $active-border: $color, - $active-color: color-yiq($active-background) + $active-color: color-contrast($active-background) ) { color: $color; border-color: $color; diff --git a/scss/mixins/_forms.scss b/scss/mixins/_forms.scss index 18735599421e..7abfd23bfb25 100644 --- a/scss/mixins/_forms.scss +++ b/scss/mixins/_forms.scss @@ -32,7 +32,7 @@ margin-top: .1rem; @include font-size($form-feedback-tooltip-font-size); line-height: $form-feedback-tooltip-line-height; - color: color-yiq($color); + color: color-contrast($color); background-color: rgba($color, $form-feedback-tooltip-opacity); @include border-radius($form-feedback-tooltip-border-radius); } diff --git a/site/assets/scss/_colors.scss b/site/assets/scss/_colors.scss index b698b807b572..fe0bf6c5b63c 100644 --- a/site/assets/scss/_colors.scss +++ b/site/assets/scss/_colors.scss @@ -4,116 +4,116 @@ @each $color, $value in $colors { .swatch-#{$color} { - color: color-yiq($value); + color: color-contrast($value); background-color: #{$value}; } } @each $color, $value in $grays { .swatch-#{$color} { - color: color-yiq($value); + color: color-contrast($value); background-color: #{$value}; } } // stylelint-disable declaration-block-single-line-max-declarations -.bd-blue-100 { color: color-yiq($blue-100); background-color: $blue-100; } -.bd-blue-200 { color: color-yiq($blue-200); background-color: $blue-200; } -.bd-blue-300 { color: color-yiq($blue-300); background-color: $blue-300; } -.bd-blue-400 { color: color-yiq($blue-400); background-color: $blue-400; } -.bd-blue-500 { color: color-yiq($blue-500); background-color: $blue-500; } -.bd-blue-600 { color: color-yiq($blue-600); background-color: $blue-600; } -.bd-blue-700 { color: color-yiq($blue-700); background-color: $blue-700; } -.bd-blue-800 { color: color-yiq($blue-800); background-color: $blue-800; } -.bd-blue-900 { color: color-yiq($blue-900); background-color: $blue-900; } +.bd-blue-100 { color: color-contrast($blue-100); background-color: $blue-100; } +.bd-blue-200 { color: color-contrast($blue-200); background-color: $blue-200; } +.bd-blue-300 { color: color-contrast($blue-300); background-color: $blue-300; } +.bd-blue-400 { color: color-contrast($blue-400); background-color: $blue-400; } +.bd-blue-500 { color: color-contrast($blue-500); background-color: $blue-500; } +.bd-blue-600 { color: color-contrast($blue-600); background-color: $blue-600; } +.bd-blue-700 { color: color-contrast($blue-700); background-color: $blue-700; } +.bd-blue-800 { color: color-contrast($blue-800); background-color: $blue-800; } +.bd-blue-900 { color: color-contrast($blue-900); background-color: $blue-900; } -.bd-indigo-100 { color: color-yiq($indigo-100); background-color: $indigo-100; } -.bd-indigo-200 { color: color-yiq($indigo-200); background-color: $indigo-200; } -.bd-indigo-300 { color: color-yiq($indigo-300); background-color: $indigo-300; } -.bd-indigo-400 { color: color-yiq($indigo-400); background-color: $indigo-400; } -.bd-indigo-500 { color: color-yiq($indigo-500); background-color: $indigo-500; } -.bd-indigo-600 { color: color-yiq($indigo-600); background-color: $indigo-600; } -.bd-indigo-700 { color: color-yiq($indigo-700); background-color: $indigo-700; } -.bd-indigo-800 { color: color-yiq($indigo-800); background-color: $indigo-800; } -.bd-indigo-900 { color: color-yiq($indigo-900); background-color: $indigo-900; } +.bd-indigo-100 { color: color-contrast($indigo-100); background-color: $indigo-100; } +.bd-indigo-200 { color: color-contrast($indigo-200); background-color: $indigo-200; } +.bd-indigo-300 { color: color-contrast($indigo-300); background-color: $indigo-300; } +.bd-indigo-400 { color: color-contrast($indigo-400); background-color: $indigo-400; } +.bd-indigo-500 { color: color-contrast($indigo-500); background-color: $indigo-500; } +.bd-indigo-600 { color: color-contrast($indigo-600); background-color: $indigo-600; } +.bd-indigo-700 { color: color-contrast($indigo-700); background-color: $indigo-700; } +.bd-indigo-800 { color: color-contrast($indigo-800); background-color: $indigo-800; } +.bd-indigo-900 { color: color-contrast($indigo-900); background-color: $indigo-900; } -.bd-purple-100 { color: color-yiq($purple-100); background-color: $purple-100; } -.bd-purple-200 { color: color-yiq($purple-200); background-color: $purple-200; } -.bd-purple-300 { color: color-yiq($purple-300); background-color: $purple-300; } -.bd-purple-400 { color: color-yiq($purple-400); background-color: $purple-400; } -.bd-purple-500 { color: color-yiq($purple-500); background-color: $purple-500; } -.bd-purple-600 { color: color-yiq($purple-600); background-color: $purple-600; } -.bd-purple-700 { color: color-yiq($purple-700); background-color: $purple-700; } -.bd-purple-800 { color: color-yiq($purple-800); background-color: $purple-800; } -.bd-purple-900 { color: color-yiq($purple-900); background-color: $purple-900; } +.bd-purple-100 { color: color-contrast($purple-100); background-color: $purple-100; } +.bd-purple-200 { color: color-contrast($purple-200); background-color: $purple-200; } +.bd-purple-300 { color: color-contrast($purple-300); background-color: $purple-300; } +.bd-purple-400 { color: color-contrast($purple-400); background-color: $purple-400; } +.bd-purple-500 { color: color-contrast($purple-500); background-color: $purple-500; } +.bd-purple-600 { color: color-contrast($purple-600); background-color: $purple-600; } +.bd-purple-700 { color: color-contrast($purple-700); background-color: $purple-700; } +.bd-purple-800 { color: color-contrast($purple-800); background-color: $purple-800; } +.bd-purple-900 { color: color-contrast($purple-900); background-color: $purple-900; } -.bd-pink-100 { color: color-yiq($pink-100); background-color: $pink-100; } -.bd-pink-200 { color: color-yiq($pink-200); background-color: $pink-200; } -.bd-pink-300 { color: color-yiq($pink-300); background-color: $pink-300; } -.bd-pink-400 { color: color-yiq($pink-400); background-color: $pink-400; } -.bd-pink-500 { color: color-yiq($pink-500); background-color: $pink-500; } -.bd-pink-600 { color: color-yiq($pink-600); background-color: $pink-600; } -.bd-pink-700 { color: color-yiq($pink-700); background-color: $pink-700; } -.bd-pink-800 { color: color-yiq($pink-800); background-color: $pink-800; } -.bd-pink-900 { color: color-yiq($pink-900); background-color: $pink-900; } +.bd-pink-100 { color: color-contrast($pink-100); background-color: $pink-100; } +.bd-pink-200 { color: color-contrast($pink-200); background-color: $pink-200; } +.bd-pink-300 { color: color-contrast($pink-300); background-color: $pink-300; } +.bd-pink-400 { color: color-contrast($pink-400); background-color: $pink-400; } +.bd-pink-500 { color: color-contrast($pink-500); background-color: $pink-500; } +.bd-pink-600 { color: color-contrast($pink-600); background-color: $pink-600; } +.bd-pink-700 { color: color-contrast($pink-700); background-color: $pink-700; } +.bd-pink-800 { color: color-contrast($pink-800); background-color: $pink-800; } +.bd-pink-900 { color: color-contrast($pink-900); background-color: $pink-900; } -.bd-red-100 { color: color-yiq($red-100); background-color: $red-100; } -.bd-red-200 { color: color-yiq($red-200); background-color: $red-200; } -.bd-red-300 { color: color-yiq($red-300); background-color: $red-300; } -.bd-red-400 { color: color-yiq($red-400); background-color: $red-400; } -.bd-red-500 { color: color-yiq($red-500); background-color: $red-500; } -.bd-red-600 { color: color-yiq($red-600); background-color: $red-600; } -.bd-red-700 { color: color-yiq($red-700); background-color: $red-700; } -.bd-red-800 { color: color-yiq($red-800); background-color: $red-800; } -.bd-red-900 { color: color-yiq($red-900); background-color: $red-900; } +.bd-red-100 { color: color-contrast($red-100); background-color: $red-100; } +.bd-red-200 { color: color-contrast($red-200); background-color: $red-200; } +.bd-red-300 { color: color-contrast($red-300); background-color: $red-300; } +.bd-red-400 { color: color-contrast($red-400); background-color: $red-400; } +.bd-red-500 { color: color-contrast($red-500); background-color: $red-500; } +.bd-red-600 { color: color-contrast($red-600); background-color: $red-600; } +.bd-red-700 { color: color-contrast($red-700); background-color: $red-700; } +.bd-red-800 { color: color-contrast($red-800); background-color: $red-800; } +.bd-red-900 { color: color-contrast($red-900); background-color: $red-900; } -.bd-orange-100 { color: color-yiq($orange-100); background-color: $orange-100; } -.bd-orange-200 { color: color-yiq($orange-200); background-color: $orange-200; } -.bd-orange-300 { color: color-yiq($orange-300); background-color: $orange-300; } -.bd-orange-400 { color: color-yiq($orange-400); background-color: $orange-400; } -.bd-orange-500 { color: color-yiq($orange-500); background-color: $orange-500; } -.bd-orange-600 { color: color-yiq($orange-600); background-color: $orange-600; } -.bd-orange-700 { color: color-yiq($orange-700); background-color: $orange-700; } -.bd-orange-800 { color: color-yiq($orange-800); background-color: $orange-800; } -.bd-orange-900 { color: color-yiq($orange-900); background-color: $orange-900; } +.bd-orange-100 { color: color-contrast($orange-100); background-color: $orange-100; } +.bd-orange-200 { color: color-contrast($orange-200); background-color: $orange-200; } +.bd-orange-300 { color: color-contrast($orange-300); background-color: $orange-300; } +.bd-orange-400 { color: color-contrast($orange-400); background-color: $orange-400; } +.bd-orange-500 { color: color-contrast($orange-500); background-color: $orange-500; } +.bd-orange-600 { color: color-contrast($orange-600); background-color: $orange-600; } +.bd-orange-700 { color: color-contrast($orange-700); background-color: $orange-700; } +.bd-orange-800 { color: color-contrast($orange-800); background-color: $orange-800; } +.bd-orange-900 { color: color-contrast($orange-900); background-color: $orange-900; } -.bd-yellow-100 { color: color-yiq($yellow-100); background-color: $yellow-100; } -.bd-yellow-200 { color: color-yiq($yellow-200); background-color: $yellow-200; } -.bd-yellow-300 { color: color-yiq($yellow-300); background-color: $yellow-300; } -.bd-yellow-400 { color: color-yiq($yellow-400); background-color: $yellow-400; } -.bd-yellow-500 { color: color-yiq($yellow-500); background-color: $yellow-500; } -.bd-yellow-600 { color: color-yiq($yellow-600); background-color: $yellow-600; } -.bd-yellow-700 { color: color-yiq($yellow-700); background-color: $yellow-700; } -.bd-yellow-800 { color: color-yiq($yellow-800); background-color: $yellow-800; } -.bd-yellow-900 { color: color-yiq($yellow-900); background-color: $yellow-900; } +.bd-yellow-100 { color: color-contrast($yellow-100); background-color: $yellow-100; } +.bd-yellow-200 { color: color-contrast($yellow-200); background-color: $yellow-200; } +.bd-yellow-300 { color: color-contrast($yellow-300); background-color: $yellow-300; } +.bd-yellow-400 { color: color-contrast($yellow-400); background-color: $yellow-400; } +.bd-yellow-500 { color: color-contrast($yellow-500); background-color: $yellow-500; } +.bd-yellow-600 { color: color-contrast($yellow-600); background-color: $yellow-600; } +.bd-yellow-700 { color: color-contrast($yellow-700); background-color: $yellow-700; } +.bd-yellow-800 { color: color-contrast($yellow-800); background-color: $yellow-800; } +.bd-yellow-900 { color: color-contrast($yellow-900); background-color: $yellow-900; } -.bd-green-100 { color: color-yiq($green-100); background-color: $green-100; } -.bd-green-200 { color: color-yiq($green-200); background-color: $green-200; } -.bd-green-300 { color: color-yiq($green-300); background-color: $green-300; } -.bd-green-400 { color: color-yiq($green-400); background-color: $green-400; } -.bd-green-500 { color: color-yiq($green-500); background-color: $green-500; } -.bd-green-600 { color: color-yiq($green-600); background-color: $green-600; } -.bd-green-700 { color: color-yiq($green-700); background-color: $green-700; } -.bd-green-800 { color: color-yiq($green-800); background-color: $green-800; } -.bd-green-900 { color: color-yiq($green-900); background-color: $green-900; } +.bd-green-100 { color: color-contrast($green-100); background-color: $green-100; } +.bd-green-200 { color: color-contrast($green-200); background-color: $green-200; } +.bd-green-300 { color: color-contrast($green-300); background-color: $green-300; } +.bd-green-400 { color: color-contrast($green-400); background-color: $green-400; } +.bd-green-500 { color: color-contrast($green-500); background-color: $green-500; } +.bd-green-600 { color: color-contrast($green-600); background-color: $green-600; } +.bd-green-700 { color: color-contrast($green-700); background-color: $green-700; } +.bd-green-800 { color: color-contrast($green-800); background-color: $green-800; } +.bd-green-900 { color: color-contrast($green-900); background-color: $green-900; } -.bd-teal-100 { color: color-yiq($teal-100); background-color: $teal-100; } -.bd-teal-200 { color: color-yiq($teal-200); background-color: $teal-200; } -.bd-teal-300 { color: color-yiq($teal-300); background-color: $teal-300; } -.bd-teal-400 { color: color-yiq($teal-400); background-color: $teal-400; } -.bd-teal-500 { color: color-yiq($teal-500); background-color: $teal-500; } -.bd-teal-600 { color: color-yiq($teal-600); background-color: $teal-600; } -.bd-teal-700 { color: color-yiq($teal-700); background-color: $teal-700; } -.bd-teal-800 { color: color-yiq($teal-800); background-color: $teal-800; } -.bd-teal-900 { color: color-yiq($teal-900); background-color: $teal-900; } +.bd-teal-100 { color: color-contrast($teal-100); background-color: $teal-100; } +.bd-teal-200 { color: color-contrast($teal-200); background-color: $teal-200; } +.bd-teal-300 { color: color-contrast($teal-300); background-color: $teal-300; } +.bd-teal-400 { color: color-contrast($teal-400); background-color: $teal-400; } +.bd-teal-500 { color: color-contrast($teal-500); background-color: $teal-500; } +.bd-teal-600 { color: color-contrast($teal-600); background-color: $teal-600; } +.bd-teal-700 { color: color-contrast($teal-700); background-color: $teal-700; } +.bd-teal-800 { color: color-contrast($teal-800); background-color: $teal-800; } +.bd-teal-900 { color: color-contrast($teal-900); background-color: $teal-900; } -.bd-cyan-100 { color: color-yiq($cyan-100); background-color: $cyan-100; } -.bd-cyan-200 { color: color-yiq($cyan-200); background-color: $cyan-200; } -.bd-cyan-300 { color: color-yiq($cyan-300); background-color: $cyan-300; } -.bd-cyan-400 { color: color-yiq($cyan-400); background-color: $cyan-400; } -.bd-cyan-500 { color: color-yiq($cyan-500); background-color: $cyan-500; } -.bd-cyan-600 { color: color-yiq($cyan-600); background-color: $cyan-600; } -.bd-cyan-700 { color: color-yiq($cyan-700); background-color: $cyan-700; } -.bd-cyan-800 { color: color-yiq($cyan-800); background-color: $cyan-800; } -.bd-cyan-900 { color: color-yiq($cyan-900); background-color: $cyan-900; } +.bd-cyan-100 { color: color-contrast($cyan-100); background-color: $cyan-100; } +.bd-cyan-200 { color: color-contrast($cyan-200); background-color: $cyan-200; } +.bd-cyan-300 { color: color-contrast($cyan-300); background-color: $cyan-300; } +.bd-cyan-400 { color: color-contrast($cyan-400); background-color: $cyan-400; } +.bd-cyan-500 { color: color-contrast($cyan-500); background-color: $cyan-500; } +.bd-cyan-600 { color: color-contrast($cyan-600); background-color: $cyan-600; } +.bd-cyan-700 { color: color-contrast($cyan-700); background-color: $cyan-700; } +.bd-cyan-800 { color: color-contrast($cyan-800); background-color: $cyan-800; } +.bd-cyan-900 { color: color-contrast($cyan-900); background-color: $cyan-900; } diff --git a/site/content/docs/4.3/getting-started/theming.md b/site/content/docs/4.3/getting-started/theming.md index dcaa593f104c..e6ed6c1982f8 100644 --- a/site/content/docs/4.3/getting-started/theming.md +++ b/site/content/docs/4.3/getting-started/theming.md @@ -191,14 +191,14 @@ In practice, you'd call the function and pass in two parameters: the name of the #### Color contrast -An additional function we include in Bootstrap is the color contrast function, `color-yiq`. It utilizes the [YIQ color space](https://en.wikipedia.org/wiki/YIQ) to automatically return a light (`#fff`) or dark (`#111`) contrast color based on the specified base color. This function is especially useful for mixins or loops where you're generating multiple classes. +An additional function we include in Bootstrap is the color contrast function, `color-contrast`. It utilizes the [WCAG 2.0 algorithm](https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests) for calculating contrast thresholds based on [relative luminance](https://www.w3.org/WAI/GL/wiki/Relative_luminance) in a `sRGB` colorspace to automatically return a light (`#fff`) or dark (`#111`) contrast color based on the specified base color. This function is especially useful for mixins or loops where you're generating multiple classes. For example, to generate color swatches from our `$theme-colors` map: {{< highlight scss >}} @each $color, $value in $theme-colors { .swatch-#{$color} { - color: color-yiq($value); + color: color-contrast($value); } } {{< /highlight >}} @@ -207,7 +207,7 @@ It can also be used for one-off contrast needs: {{< highlight scss >}} .custom-element { - color: color-yiq(#000); // returns `color: #fff` + color: color-contrast(#000); // returns `color: #fff` } {{< /highlight >}} @@ -215,10 +215,16 @@ You can also specify a base color with our color map functions: {{< highlight scss >}} .custom-element { - color: color-yiq($dark); // returns `color: #fff` + color: color-contrast($dark); // returns `color: #fff` } {{< /highlight >}} +{{< callout info >}} +##### Accessibility + +In order to meet [WCAG 2.0 accessibility standards for color contrast](https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html), authors **must** provide [a contrast ratio of at least 4.5:1](https://www.w3.org/WAI/WCAG20/quickref/20160105/Overview.php#visual-audio-contrast-contrast), with very few exceptions. +{{< /callout >}} + #### Escape SVG We use the `escape-svg` function to escape the `<`, `>` and `#` characters for SVG background images. diff --git a/site/content/docs/4.3/migration.md b/site/content/docs/4.3/migration.md index be953eca321b..e3d2e1b3beff 100644 --- a/site/content/docs/4.3/migration.md +++ b/site/content/docs/4.3/migration.md @@ -39,9 +39,12 @@ Changes to our source Sass files and compiled CSS. - The `theme-color-level()` function is renamed to `color-level()` and now accepts any color you want instead of only `$theme-color` colors. [See #29083](https://github.com/twbs/bootstrap/pull/29083) - `$enable-grid-classes` doesn't disable the generation of container classes anymore [See #29146](https://github.com/twbs/bootstrap/pull/29146) - Line heights are dropped from several components to simplify our codebase. The `button-size()` and `pagination-size()` do not accept line height parameters anymore. [See #29271](https://github.com/twbs/bootstrap/pull/29271) -- The `button-variant()` mixin now accepts 3 optional color parameters, for each button state, to override the color provided by `color-yiq()`. By default, these parameters will find which color provides more contrast against the button state's background color with `color-yiq()`. -- The `button-outline-variant()` mixin now accepts an additional argument, `$active-color`, for setting the button's active state text color. By default, this parameter will find which color provides more contrast against the button's active background color with `color-yiq()`. +- The `button-variant()` mixin now accepts 3 optional color parameters, for each button state, to override the color provided by `color-contrast()`. By default, these parameters will find which color provides more contrast against the button state's background color with `color-contrast()`. +- The `button-outline-variant()` mixin now accepts an additional argument, `$active-color`, for setting the button's active state text color. By default, this parameter will find which color provides more contrast against the button's active background color with `color-contrast()`. - Ditch the Sass map merges, which makes it easier to remove redundant values. Keep in mind you now have to define all values in the Sass maps like `$theme-colors`. Check out how to deal with Sass maps on the [theming documentation]({{< docsref "/getting-started/theming#maps-and-loops" >}}). +- `color-yiq()` function is renamed to `color-contrast()` since it's not related to YIQ colorspace anymore — [See #30168](https://github.com/twbs/bootstrap/pull/30168/) — and related variables are renamed alongside: + - `$yiq-contrasted-threshold` is renamed `$min-contrast-ratio`, + - `$yiq-text-dark` and `$yiq-text-light` are respectively renamed `$color-contrast-dark` and `$color-contrast-light`. ## JavaScript