~avalos/devault-css

devault-css/scss/contrast.scss -rw-r--r-- 4.1 KiB
f1ef5a23avalos t 5 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
SCSS Color Methods for Accessibility
================================================================================
Adjust given colors to ensure that those color combination provide sufficient
contrast.
@version 0.1
@link http://eye48.com/go/scsscontrast
@license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License (LGPL)
@author Michael Haschke, http://michael.haschke.biz/
Usage
--------------------------------------------------------------------------------
Import contrast.scss first, then use method ``color_adjust_contrast_AERT``.
```(scss)
@import 'libs/contrast';
.my-element {
    background-color: #eee;
    color: color_adjust_contrast_AERT(#ccc, #eee); // get grey with good contrast on #eee
}
```
How it works
--------------------------------------------------------------------------------
It tests for sufficent difference on brightness and color of two values. If it
is not enough contrats regarding test formulas of accessible guidelines then one
color is adjusted on lightness and saturation.
Methods using calculations from:
* "Techniques For Accessibility Evaluation And Repair Tools (AERT)" working draft,
  @see http://www.w3.org/TR/AERT#color-contrast
* TODO: add methods to test with WCAG2 formulas
*/

// -- AERT ----------------------------------------------------------------

@function color_adjust_contrast_AERT(
                            $color_adjust,
                            $color_keep,
                            $lightness_change_value:1,
                            $saturation_change_value:1,
                            $brightness_min: 50,
                            $difference_min: 450)
{

    @if (color_test_contrast_AERT($color_adjust, $color_keep, $brightness_min, $difference_min) == true)
    {
        @return $color_adjust;
    }

    $color_save: $color_adjust;
    $S: saturation($color_adjust);
    $L: lightness($color_adjust);
    
    $foundresult: false;
    @while(($foundresult == false) and ($S > 0 or ($L > 0 and $L < 100)))
    {
        $color_adjust: desaturate($color_adjust, $saturation_change_value);
        
        $S: $S - $saturation_change_value;
        @if (lightness($color_keep) > lightness($color_adjust))
        {
             $color_adjust: darken($color_adjust, $lightness_change_value);
             $L: $L - $lightness_change_value;
        }
        @else
        {
             $color_adjust: lighten($color_adjust, $lightness_change_value);
             $L: $L + $lightness_change_value;
        }
        $foundresult: color_test_contrast_AERT($color_adjust, $color_keep, $brightness_min, $difference_min);
    }
    
    @if ($foundresult == false)
    {
        @debug $color_save + " was adjusted to " + $color_adjust + " but this is not enough contrast to " + $color_keep + " (AERT).";
    }
    
    @return $color_adjust;
}

@function color_test_contrast_AERT($color_1, $color_2, $brightness_min: 75, $difference_min: 500)
{
    $difference_brightness: math_absolute(color_brightness_AERT($color_1) - color_brightness_AERT($color_2));
    $difference_color: color_difference_AERT($color_1, $color_2);
    
    @if (($difference_brightness < $brightness_min) or ($difference_color < $difference_min))
    {
        @return false;
    }
    @else
    {
        @return true;
    }
}

@function color_brightness_AERT($color)
{
    $r: red($color);
    $g: green($color);
    $b: blue($color);
    
    @return (($r * 299) + ($g * 587) + ($b * 114)) / 1000;
}

@function color_difference_AERT($color1, $color2)
{
    $r1: red($color1);
    $g1: green($color1);
    $b1: blue($color1);
    
    $r2: red($color2);
    $g2: green($color2);
    $b2: blue($color2);
    
    @return (math_max($r1, $r2) - math_min($r1, $r2)) + (math_max($g1, $g2) - math_min($g1, $g2)) + (math_max($b1, $b2) - math_min($b1, $b2));
}

// -- math stuff ----------------------------------------------------------

@function math_max($value1, $value2)
{
    @if ($value1 > $value2) { @return $value1; }
    @return $value2;
}

@function math_min($value1, $value2)
{
    @if ($value1 < $value2) { @return $value1; }
    @return $value2;
}

@function math_absolute($value)
{
    @if ($value > 0) { @return $value; }
    @return $value * -1;
}