I'm using SASS and bootstrap the new version V5 as CSS Framework in some of my academic project in color part I stuck because the color functions not working as I expected I will explain where is the issue with images in next lines.
first of all take a look to the current result :
as you can see in current result it's an alert component with orange in background and border color but the issue the text it should be white not black but in this example is black I want to change the color to be with dynamicly without using any custom css only editing the bootstrap color functions to be white color instead of black color.
What I expected :
Live Example on codepen
Live Example
My FullCode :
$_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;
@function color-contrast($background, $color-contrast-dark: $color-contrast-dark, $color-contrast-light: $color-contrast-light, $min-contrast-ratio: $min-contrast-ratio) {
$foregrounds: $color-contrast-light, $color-contrast-dark, $white, $black;
$max-ratio: 0;
$max-ratio-color: null;
@each $color in $foregrounds {
$contrast-ratio: contrast-ratio($background, $color);
@if $contrast-ratio > $min-contrast-ratio {
@return $color;
} @else if $contrast-ratio > $max-ratio {
$max-ratio: $contrast-ratio;
$max-ratio-color: $color;
}
}
@warn "Found no color leading to #{$min-contrast-ratio}:1 contrast ratio against #{$background}...";
@return $max-ratio-color;
}
@function contrast-ratio($background, $foreground: $color-contrast-light) {
$l1: luminance($background);
$l2: luminance(opaque($background, $foreground));
@return if($l1 > $l2, ($l1 + .05) / ($l2 + .05), ($l2 + .05) / ($l1 + .05));
}
@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);
}
@function opaque($background, $foreground) {
@return mix(rgba($foreground, 1), $background, opacity($foreground) * 100);
}
@function tint-color($color, $weight) {
@return mix(white, $color, $weight);
}
@function shade-color($color, $weight) {
@return mix(black, $color, $weight);
}
@function shift-color($color, $weight) {
@return if($weight > 0, shade-color($color, $weight), tint-color($color, -$weight));
}
$white: #ffffff !default;
$black: #000000 !default;
$min-contrast-ratio: 4.5 !default;
$color-contrast-dark: $black !default;
$color-contrast-light: $white !default;
$orange: #FFB74D !default;
$orange-50: tint-color($orange, 90%) !default;
$orange-100: tint-color($orange, 70%) !default;
$orange-200: tint-color($orange, 50%) !default;
$orange-300: tint-color($orange, 30%) !default;
$orange-400: tint-color($orange, 10%) !default;
$orange-500: $orange !default;
$orange-600: shade-color($orange, 20%) !default;
$orange-700: shade-color($orange, 40%) !default;
$orange-800: shade-color($orange, 60%) !default;
$orange-900: shade-color($orange, 80%) !default;
$theme-colors: () !default;
$theme-colors: map-merge(
(
"orange-50": $orange-50,
"orange-100": $orange-100,
"orange-200": $orange-200,
"orange-300": $orange-300,
"orange-400": $orange-400,
"orange-500": $orange-500,
"orange-600": $orange-600,
"orange-700": $orange-700,
"orange-800": $orange-800,
"orange-900": $orange-900
),
$theme-colors
);
@mixin alert-variant(
$background,
$border,
$color: color-contrast($background)
) {
color: $color;
background-color: $background;
border-color: $border;
}
@each $color, $value in $theme-colors {
.alert-#{$color} {
@include alert-variant($value, $value);
}
}
Sass Set Color Functions An RGB color value is specified with: rgb(red, green, blue). Each parameter defines the intensity of that color and can be an integer between 0 and 255, or a percentage value (from 0% to 100%). Sets a color using the Red-Green-Blue-Alpha (RGBA) model.
Bootstrap includes a handful of Sass maps, key value pairs that make it easier to generate families of related CSS. We use Sass maps for our colors, grid breakpoints, and more. Just like Sass variables, all Sass maps include the ! default flag and can be overridden and extended.
Override Variables Bootstrap has its own “_variables. scss” in the “scss” folder, which contains all variables used in Bootstrap. Now, add the “abstracts” name folder in your scss folder and create “_custom-variables. scss” in that folder.
You will need to change the value of the $min-contrast-ratio
variable to a lower value.
By default, Bootstrap v5 sets 4.5
as the default value as the recommend WCAG [ISO-9241-3] and [ANSI-HFES-100-1988], especially for elderly people or those with vision loss.
https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html
In your case, change the contrast ratio to a lower value but be aware that users with low vision or cognitive impairments may not be able to read your text.
Adding $min-contrast-ratio: 2.5;
to your code will override the default making the text in your code white.
// Variables
$min-contrast-ratio: 2.5;
// Bootstrap
$_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;
@function color-contrast($background, $color-contrast-dark: $color-contrast-dark, $color-contrast-light: $color-contrast-light, $min-contrast-ratio: $min-contrast-ratio) {
$foregrounds: $color-contrast-light, $color-contrast-dark, $white, $black;
$max-ratio: 0;
$max-ratio-color: null;
@each $color in $foregrounds {
$contrast-ratio: contrast-ratio($background, $color);
@if $contrast-ratio > $min-contrast-ratio {
@return $color;
} @else if $contrast-ratio > $max-ratio {
$max-ratio: $contrast-ratio;
$max-ratio-color: $color;
}
}
@warn "Found no color leading to #{$min-contrast-ratio}:1 contrast ratio against #{$background}...";
@return $max-ratio-color;
}
@function contrast-ratio($background, $foreground: $color-contrast-light) {
$l1: luminance($background);
$l2: luminance(opaque($background, $foreground));
@return if($l1 > $l2, ($l1 + .05) / ($l2 + .05), ($l2 + .05) / ($l1 + .05));
}
@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);
}
@function opaque($background, $foreground) {
@return mix(rgba($foreground, 1), $background, opacity($foreground) * 100);
}
@function tint-color($color, $weight) {
@return mix(white, $color, $weight);
}
@function shade-color($color, $weight) {
@return mix(black, $color, $weight);
}
@function shift-color($color, $weight) {
@return if($weight > 0, shade-color($color, $weight), tint-color($color, -$weight));
}
$white: #ffffff !default;
$black: #000000 !default;
$min-contrast-ratio: 4.5 !default;
$color-contrast-dark: $black !default;
$color-contrast-light: $white !default;
$orange: #fd7e14 !default;
$orange-50: tint-color($orange, 90%) !default;
$orange-100: tint-color($orange, 70%) !default;
$orange-200: tint-color($orange, 50%) !default;
$orange-300: tint-color($orange, 30%) !default;
$orange-400: tint-color($orange, 10%) !default;
$orange-500: $orange !default;
$orange-600: shade-color($orange, 20%) !default;
$orange-700: shade-color($orange, 40%) !default;
$orange-800: shade-color($orange, 60%) !default;
$orange-900: shade-color($orange, 80%) !default;
$theme-colors: () !default;
$theme-colors: map-merge(
(
"orange": $orange
),
$theme-colors
);
@mixin alert-variant(
$background,
$border,
$color: color-contrast($background)
) {
color: $color;
background-color: $background;
border-color: $border;
}
@each $color, $value in $theme-colors {
.alert-#{$color} {
@include alert-variant($value, $value);
padding: 15px 10px;
font-size: 1rem;
text-align: center;
margin-bottom: 15px;
}
}
Alternatively, you may add the extra parameters to the color-contrast
function if you don't want to affect the minimum contrast ratio directly or globally.
@mixin alert-variant(
$background,
$border,
$color: color-contrast(
$background,
$color-contrast-dark, // Black text
$color-contrast-light, // White text
2.5 // minimum contrast ratio
)
) {
color: $color;
background-color: $background;
border-color: $border;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With