diff --git a/CHANGELOG.md b/CHANGELOG.md index 70c96f19a85..8b6912cc787 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # [`master`](https://github.com/elastic/eui/tree/master) -- Modified drop shadow intensities and color. ([#607](https://github.com/elastic/eui/pull/607)) +- Modifying drop shadow intensities and color. ([607](https://github.com/elastic/eui/pull/607)) +- Add Sass color functions. Make `$euiColorWarning` color usage more accessible while still being "yellow". ([628](https://github.com/elastic/eui/pull/628)) - Removed extraneous `global_styling/mixins/_forms.scss` file and importing the correct files in the `filter_group.scss` and `combo_box.scss` files. ([#609](https://github.com/elastic/eui/pull/609)) **Bug fixes** diff --git a/src/components/button/_button.scss b/src/components/button/_button.scss index fbbafe0c014..b3cdb4f7e0e 100644 --- a/src/components/button/_button.scss +++ b/src/components/button/_button.scss @@ -78,21 +78,24 @@ $buttonTypes: ( // Create button modifiders based upon the map. @each $name, $color in $buttonTypes { .euiButton--#{$name} { - color: $color; + + @if ($name == 'ghost') { + // Ghost is unique and ALWAYS sits against a dark background. + color: $color; + } @else { + // Other colors need to check their contrast against the page background color. + color: makeHighContrastColor($color, $euiColorEmptyShade); + } + border-color: $color; &.euiButton--fill { background-color: $color; border-color: $color; - $textColor: #FFF; - @if ($name == 'ghost') { - $textColor: #000; - } @else if (lightness($euiTextColor) > 50) { - $textColor: $euiTextColor; - } + $fillTextColor: chooseLightOrDarkText($color, #FFF, #000); - color: $textColor; + color: $fillTextColor; &:enabled { &:hover, &:focus { @@ -102,7 +105,7 @@ $buttonTypes: ( } &:disabled .euiButton__spinner { - border-color: euiLoadingSpinnerBorderColors(transparentize($textColor, .3)); + border-color: euiLoadingSpinnerBorderColors(transparentize($fillTextColor, .3)); } } diff --git a/src/components/call_out/_call_out.scss b/src/components/call_out/_call_out.scss index b0ed06447b6..0bb0d2cbf11 100644 --- a/src/components/call_out/_call_out.scss +++ b/src/components/call_out/_call_out.scss @@ -11,17 +11,18 @@ $callOutTypes: ( primary: $euiColorPrimary, success: $euiColorSecondary, - warning: adjust-hue($euiColorWarning, 20%), + warning: $euiColorWarning, danger: $euiColorDanger, ); // Create button modifiders based upon the map. @each $name, $color in $callOutTypes { .euiCallOut--#{$name} { - border-color: $color; - background-color: tintOrShade($color, 90%, 70%); + $backgroundColor: tintOrShade($color, 90%, 70%); + $textColor: makeHighContrastColor($color, $backgroundColor); - $textColor: shadeOrTint($color, 30%, 70%); + border-color: $color; + background-color: $backgroundColor; .euiCallOutHeader__icon { fill: $textColor; diff --git a/src/components/text/_text_color.scss b/src/components/text/_text_color.scss index 8d9eab0abb6..3bffe2ffff0 100644 --- a/src/components/text/_text_color.scss +++ b/src/components/text/_text_color.scss @@ -12,11 +12,13 @@ $textColors: ( // Create color modifiers based on the map @each $name, $color in $textColors { .euiTextColor.euiTextColor--#{$name} { - color: $color !important; + + // The below function makes sure the color is accessible on our default background. + color: makeHighContrastColor($color, $euiColorEmptyShade) !important; // We need a blanket approach for coloring. It should overule everything. * { - color: $color !important; + color: makeHighContrastColor($color, $euiColorEmptyShade) !important; } } } diff --git a/src/global_styling/functions/_colors.scss b/src/global_styling/functions/_colors.scss new file mode 100644 index 00000000000..d87a17e5955 --- /dev/null +++ b/src/global_styling/functions/_colors.scss @@ -0,0 +1,88 @@ +// Mixes a provided color with white. +@function tint($color, $percent) { + @return mix(#fff, $color, $percent); +} + +// Mixes a provided color with black. +@function shade($color, $percent) { + @return mix(#000, $color, $percent); +} + +// For theming. Checks the text color and tells us whether it's light or dark. +// Based on that we either tint (add white) or shade (add black). +@function tintOrShade($color, $tint, $shade) { + @if (lightness($euiTextColor) > 50) { + @return shade($color, $shade); + } @else { + @return tint($color, $tint); + } +} + +// The reverse of the above +@function shadeOrTint($color, $shade, $tint) { + @if (lightness($euiTextColor) < 50) { + @return shade($color, $shade); + } @else { + @return tint($color, $tint); + } +} + +// Calculates luminance, which is better than brightness for checking colors +// pow, nth functions come from the _math.scss functions +@function luminance($color) { + // Formula: http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef + $rgba: red($color), green($color), blue($color); + $rgba2: (); + + @for $i from 1 through 3 { + $rgb: nth($rgba, $i); + $rgb: $rgb / 255; + + $rgb: if($rgb < .03928, $rgb / 12.92, pow(($rgb + .055) / 1.055, 2.4)); + + $rgba2: append($rgba2, $rgb); + } + + @return .2126 * nth($rgba2, 1) + .7152 * nth($rgba2, 2) + 0.0722 * nth($rgba2, 3); +} + +// Calculate contrast +@function contrastRatio($background, $foreground) { + $backgroundLum: luminance($background) + .05; + $foregroundLum: luminance($foreground) + .05; + + @return max($backgroundLum, $foregroundLum) / min($backgroundLum, $foregroundLum); +} + +// Given $color, decide whether $lightText or $darkText should be used as the text color +// ex: chooseLightOrDarkText(#EEE, #FFF, #000) would return #000 because it has +// a higher contrast than #FFF against a #EEE background. +@function chooseLightOrDarkText($background, $lightText, $darkText) { + $lightContrast: contrastRatio($background, $lightText); + $darkContrast: contrastRatio($background, $darkText); + + @if ($lightContrast > $darkContrast) { + @return $lightText; + } + @else { + @return $darkText; + } +} + +// Given a $foreground and a $background, make the $foreground AA accessibility by slightly +// adjusting it till the contrast is high enough + +// ex: makeContrastColor($lightPink, #FFF) would continually shade the pink until +// it had higher than 4.5 contrast on a white background. +@function makeHighContrastColor($foreground, $background) { + $contrast: contrastRatio($foreground, $background); + + $highContrastTextColor: $foreground; + + @while ($contrast < 4.5) { + $highContrastTextColor: shadeOrTint($highContrastTextColor, 5%, 5%); + $contrast: contrastRatio($highContrastTextColor, $euiColorEmptyShade); + } + + @return $highContrastTextColor; +} diff --git a/src/global_styling/functions/_index.scss b/src/global_styling/functions/_index.scss new file mode 100644 index 00000000000..de8260b2bba --- /dev/null +++ b/src/global_styling/functions/_index.scss @@ -0,0 +1,5 @@ +// Math needs to be first in the load order +@import 'math'; + +// Using math, we have functions to manipulate contrast / luminosity for accessibility +@import 'colors'; diff --git a/src/global_styling/functions/_math.scss b/src/global_styling/functions/_math.scss new file mode 100644 index 00000000000..0040dc3fb18 --- /dev/null +++ b/src/global_styling/functions/_math.scss @@ -0,0 +1,44 @@ +// Greatest common devisor +// From: http://rosettacode.org/wiki/Greatest_common_divisor#JavaScript +@function gcd($a, $b) { + @if ($b != 0) { + @return gcd($b, $a % $b); + } @else { + @return abs($a); + } +} + +// Handles decimal exponents by trying to convert them into a fraction and then +// use a nthRoot-algorithm for parts of the calculation +@function pow($base, $exponent, $prec: 12) { + @if (floor($exponent) != $exponent) { + $prec2 : pow(10, $prec); + $exponent: round($exponent * $prec2); + $denominator: gcd($exponent, $prec2); + @return nthRoot(pow($base, $exponent / $denominator), $prec2 / $denominator, $prec); + } + + $value: $base; + @if $exponent > 1 { + @for $i from 2 through $exponent { + $value: $value * $base; + } + } @else if $exponent < 1 { + @for $i from 0 through -$exponent { + $value: $value / $base; + } + } + + @return $value; +} + +// From: http://rosettacode.org/wiki/Nth_root#JavaScript +@function nthRoot($num, $n: 2, $prec: 12) { + $x: 1; + + @for $i from 0 through $prec { + $x: 1 / $n * (($n - 1) * $x + ($num / pow($x, $n - 1))); + } + + @return $x; +} diff --git a/src/global_styling/index.scss b/src/global_styling/index.scss index dbaf1a9869d..29729d85f7b 100644 --- a/src/global_styling/index.scss +++ b/src/global_styling/index.scss @@ -1,4 +1,13 @@ // Core + +// Functions need to be first, since we use them in our variables and mixin definitions +@import 'functions/index'; + +// Variables come next, and are used in some mixins @import 'variables/index'; + +// Mixins provide generic code expansion through helpers @import 'mixins/index'; + +// The reset file makes use of variables and mixins @import 'reset/index'; diff --git a/src/global_styling/variables/_colors.scss b/src/global_styling/variables/_colors.scss index b774ddf31d0..3400db5d572 100644 --- a/src/global_styling/variables/_colors.scss +++ b/src/global_styling/variables/_colors.scss @@ -1,31 +1,3 @@ -// Mixes a provided color with white. -@function tint($color, $percent) { - @return mix(#fff, $color, $percent); -} - -// Mixes a provided color with black. -@function shade($color, $percent) { - @return mix(#000, $color, $percent); -} - -// For theming. Checks the text color and tells us whether it's light or dark. -// Based on that we either tint or shade. -@function tintOrShade($color, $tint, $shade) { - @if (lightness($euiTextColor) > 50) { - @return shade($color, $shade); - } @else { - @return tint($color, $tint); - } -} - -@function shadeOrTint($color, $shade, $tint) { - @if (lightness($euiTextColor) < 50) { - @return shade($color, $shade); - } @else { - @return tint($color, $tint); - } -} - // Core $euiColorPrimary: #0079a5 !default; @@ -37,7 +9,7 @@ $euiColorGhost: #FFF !default; // Status $euiColorSuccess: $euiColorSecondary !default; $euiColorDanger: #A30000 !default; -$euiColorWarning: #CF3800 !default; +$euiColorWarning: #E5830E !default; // Grays $euiColorEmptyShade: #FFF !default; diff --git a/src/themes/eui/eui_colors_dark.scss b/src/themes/eui/eui_colors_dark.scss index 4c578239ad1..58302f0b16e 100644 --- a/src/themes/eui/eui_colors_dark.scss +++ b/src/themes/eui/eui_colors_dark.scss @@ -9,7 +9,7 @@ $euiColorDarkestShade: #F5F5F5; $euiColorFullShade: #FFF; $euiColorSlightHue: #494E51; $euiColorPrimary: #4da1c0; -$euiColorWarning: #e45c29; +$euiColorWarning: #c06c4c; $euiColorDanger: #bf4d4d; $euiTextColor: #DDD;