mirror of
https://github.com/twbs/bootstrap.git
synced 2025-08-30 00:29:52 +02:00
Use WCAG contrast algo (#30168)
This commit is contained in:
@@ -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; }
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user