automated-a11y-sass
automated-a11y-sass copied to clipboard
Grey foreground skews to color of background.
Context: I was looking for an alternative to adjusting the foreground color to ensure it was accessible when I happened upon your article and this repo. When I substituted the old routine for yours, I noticed that the foreground color was shifted
a11y-color(#333333, #161315, 'AAA') yields #CE9292. That is, the foreground's color was shifted to conform to the background color.
Forgive me, but I'm not familiar enough with Sassmeister to give the example. But, I did a debug dump of the gray range. My "normal" approach would be to use something in the middle grey, then let the contrast routine force it in the correct direction. I do this because I have both a light & dark mode and prefer to set the background and have the text adjust accordingly.
The hex on the left is the FG going in. The hex on the right is the output. I stopped after #999 since #AAAAAA is an AAA compliant foreground to #161315
DEBUG: #111111 #d28f8f
DEBUG: #222222 #d09090
DEBUG: #333333 #ce9292
DEBUG: #444444 #cb9393
DEBUG: #555555 #c69494
DEBUG: #666666 #c19696
DEBUG: #777777 #bb9898
DEBUG: #888888 #b39b9b
DEBUG: #999999 #a79e9e
I focused down on the part of your code that steps through the luminance. scale-color()
is the culprit, with the first step being #333333
to #383737
finally to #ce9292
. However, when I use a different color, it seems to not make the same mistake, #338833
steps to #348d34
finally to #3db93d
. So, color me curious why grey can skew pink when saturation rises, but not other colors.
$fg: scale-color($fg, $lightness: $step, $saturation: $step/2);
It appears you're tweaking HSL, so I decided to set $saturation:0
instead; or rather remove it. That fixed it.
The saturation value ($step/2) was %1 for 38 iterations, changing the saturation +38%;
I think I fixed this ultimately by limiting the saturation step if the saturation was already in the gray area:
$sat-step: 0;
@if saturation($fg) > 10 {
$sat-step: $step/2
}
$fg: scale-color($fg, $lightness: $step, $saturation:$sat-step);
Wow, thanks for this! Very good insights, I'll see what I can do to make the corrections.
No worries. I'm disappointed the Sass team won't build something like this in. It looks like the last attempt was 2014 and the said "no" because it used HSL. :shrug:
However, I just ran into another random problem. Using the color #456ca1 put me into a continuous loop. True of my version of that step-through or yours. I "fixed" it by putting a counter that stopped if exceeds 288, which is the number of lines in your lookup. While loops should always have an escape valve.
Digging a bit more, #63573e is the base color, which is something I'm auto-calculating internally off of #456ca1. Either way, it appears there are some cases where colors will create a continuous loop absent a stop. It appears to be when the color contrast can never get to the correct ratio (7 in this case, the ratio of #456ca1 to #FFFFFF is 5.36, and to #000000 is 3.9. Good to know the color is not acceptable in my use case (WebAIM to the rescue). I went a little darker.
Sending more than one comment since I'm digging into your code. You are using the lookup because SASS has no pow() function. The "other" accessibility tool I had been using used one. The following code shows how they detected luminance:
@function pow($base, $exponents) {
$raised: 1;
@for $i from 1 through $exponents {
$raised: $raised * $base;
}
@return $raised;
}
@function luma($color){
// Thanks voxpelli for a very concise implementation of luminance measure in sass
// Adapted from: https://gist.github.com/voxpelli/6304812
$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));
$rgba2: append($rgba2, $rgb);
}
@return (.2126 * nth($rgba2, 1) + .7152 * nth($rgba2, 2) + 0.0722 * nth($rgba2, 3))*100;
}
Ultimately, I'm going back to the solution I found earlier. I did bring into it the innovation of stepping through @while instead of its prior @for iteration through iterations of 7 multiples.
https://gist.github.com/Merovex/ffdab61ea070e8aa45816c8e6138408f