449 lines
10 KiB
SCSS
449 lines
10 KiB
SCSS
/*
|
|
The Ultimate Hover Color Function
|
|
@author Gray Gilmore - http://code.graygilmore.com
|
|
|
|
The goal of this Sass function is provide a hover color that works
|
|
with any color on any background. No longer do we need to bundle
|
|
hover color options with our themes, let Sassy McSasserson take care
|
|
of that for you.
|
|
|
|
The hover color, seen in this demo as "After" text, must be visible in
|
|
all situations and, hopefully, pass the WCAG 2.0 contrast ratio [1]
|
|
formula (4.5:1).
|
|
|
|
[1] http://www.w3.org/TR/2008/REC-WCAG20-20081211/#visual-audio-contrast-contrast
|
|
|
|
contrast-ratio() help from @davidkaneda
|
|
|
|
|
|
## Usage ##
|
|
|
|
a {
|
|
color: $link-color;
|
|
|
|
&:hover {
|
|
color: hover($background-color, $link-color);
|
|
}
|
|
}
|
|
|
|
button {
|
|
background: $button-background;
|
|
color: $button-color;
|
|
|
|
&:hover {
|
|
background: hover($background-color, $button-background);
|
|
}
|
|
}
|
|
|
|
## End Usage ##
|
|
|
|
*/
|
|
|
|
@function color-luminance($value) {
|
|
@if $value <= 0.03928 {
|
|
@return $value / 12.92;
|
|
} @else {
|
|
@return ($value + 0.055)/1.055 * ($value + 0.055)/1.055;
|
|
}
|
|
}
|
|
|
|
@function luminosity($color) {
|
|
$r: color-luminance(red($color) / 255);
|
|
$g: color-luminance(green($color) / 255);
|
|
$b: color-luminance(blue($color) / 255);
|
|
|
|
@return 0.2126 * $r + 0.7152 * $g + 0.0722 * $b;
|
|
}
|
|
|
|
@function contrast-ratio($c1, $c2) {
|
|
$l1: luminosity($c1);
|
|
$l2: luminosity($c2);
|
|
|
|
@if $l2 > $l1 {
|
|
@return $l2 / $l1;
|
|
} @else {
|
|
@return $l1 / $l2;
|
|
}
|
|
}
|
|
|
|
@function contrast-color($background, $color) {
|
|
|
|
$style: '';
|
|
$hover-color: '';
|
|
$color-lightness: abs(lightness($color));
|
|
$background-lightness: abs(lightness($background));
|
|
$contrast: abs(contrast-ratio($background, $color));
|
|
|
|
@if $color-lightness == 100 {
|
|
/* White */
|
|
@if $background-lightness >= 90 {
|
|
$hover-color: darken($background, 15);
|
|
} @else {
|
|
$hover-color: mix($color, $background, 80);
|
|
}
|
|
} @else if $color-lightness == 0 {
|
|
/* Black */
|
|
@if $background-lightness < 10 {
|
|
$hover-color: lighten($background, 20);
|
|
} @else {
|
|
$hover-color: mix($color, $background, 60);
|
|
}
|
|
} @else if $background-lightness < $color-lightness {
|
|
/* Light text on dark background */
|
|
$style: 'lighten';
|
|
@if $color-lightness > 90 {
|
|
/* Color too light to lighten */
|
|
$hover-color: darken($color, 20);
|
|
$style: 'darken';
|
|
} @else {
|
|
$hover-color: lighten($color, 20);
|
|
}
|
|
|
|
} @else {
|
|
/* Dark text on light background */
|
|
$style: 'darken';
|
|
@if $color-lightness < 15 {
|
|
/* Color is too dark to further darken */
|
|
$hover-color: lighten($color, 20);
|
|
$style: 'lighten';
|
|
} @else {
|
|
$hover-color: darken($color, 20);
|
|
}
|
|
}
|
|
|
|
/*
|
|
Sometimes the $hover-color won't have enough contrast
|
|
with the background. We'll try to fix this below by
|
|
increasing our darken/lighten range by +/- 5
|
|
*/
|
|
|
|
/* Only test if the $color isn't white or black */
|
|
/*@if $color-lightness != 0 and $color-lightness != 100 {
|
|
$new-contrast: contrast-ratio($background, $hover-color);
|
|
@if $new-contrast < 8 {
|
|
@for $i from 15 to 25 {
|
|
@if $style == 'darken' {
|
|
$test-color: darken($color, $i);
|
|
} @else {
|
|
$test-color: lighten($color, $i);
|
|
}
|
|
$test-contrast: contrast-ratio($background, $test-color);
|
|
|
|
@if $test-contrast > $new-contrast {
|
|
$new-contrast: $test-contrast;
|
|
$hover-color: $test-color;
|
|
}
|
|
}
|
|
}
|
|
}*/
|
|
|
|
@return $hover-color;
|
|
}
|
|
|
|
|
|
// Precomputed linear color channel values, for use in contrast calculations.
|
|
// See https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests
|
|
//
|
|
// Algorithm, for c in 0 to 255:
|
|
// f(c) {
|
|
// c = c / 255;
|
|
// return c < 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
|
|
// }
|
|
//
|
|
// This lookup table is needed since there is no `pow` in SASS.
|
|
$linear-channel-values:
|
|
0
|
|
.0003035269835488375
|
|
.000607053967097675
|
|
.0009105809506465125
|
|
.00121410793419535
|
|
.0015176349177441874
|
|
.001821161901293025
|
|
.0021246888848418626
|
|
.0024282158683907
|
|
.0027317428519395373
|
|
.003035269835488375
|
|
.003346535763899161
|
|
.003676507324047436
|
|
.004024717018496307
|
|
.004391442037410293
|
|
.004776953480693729
|
|
.005181516702338386
|
|
.005605391624202723
|
|
.006048833022857054
|
|
.006512090792594475
|
|
.006995410187265387
|
|
.007499032043226175
|
|
.008023192985384994
|
|
.008568125618069307
|
|
.009134058702220787
|
|
.00972121732023785
|
|
.010329823029626936
|
|
.010960094006488246
|
|
.011612245179743885
|
|
.012286488356915872
|
|
.012983032342173012
|
|
.013702083047289686
|
|
.014443843596092545
|
|
.01520851442291271
|
|
.01599629336550963
|
|
.016807375752887384
|
|
.017641954488384078
|
|
.018500220128379697
|
|
.019382360956935723
|
|
.0202885630566524
|
|
.021219010376003555
|
|
.022173884793387385
|
|
.02315336617811041
|
|
.024157632448504756
|
|
.02518685962736163
|
|
.026241221894849898
|
|
.027320891639074894
|
|
.028426039504420793
|
|
.0295568344378088
|
|
.030713443732993635
|
|
.03189603307301153
|
|
.033104766570885055
|
|
.03433980680868217
|
|
.03560131487502034
|
|
.03688945040110004
|
|
.0382043715953465
|
|
.03954623527673284
|
|
.04091519690685319
|
|
.042311410620809675
|
|
.043735029256973465
|
|
.04518620438567554
|
|
.046665086336880095
|
|
.04817182422688942
|
|
.04970656598412723
|
|
.05126945837404324
|
|
.052860647023180246
|
|
.05448027644244237
|
|
.05612849004960009
|
|
.05780543019106723
|
|
.0595112381629812
|
|
.06124605423161761
|
|
.06301001765316767
|
|
.06480326669290577
|
|
.06662593864377289
|
|
.06847816984440017
|
|
.07036009569659588
|
|
.07227185068231748
|
|
.07421356838014963
|
|
.07618538148130785
|
|
.07818742180518633
|
|
.08021982031446832
|
|
.0822827071298148
|
|
.08437621154414882
|
|
.08650046203654976
|
|
.08865558628577294
|
|
.09084171118340768
|
|
.09305896284668745
|
|
.0953074666309647
|
|
.09758734714186246
|
|
.09989872824711389
|
|
.10224173308810132
|
|
.10461648409110419
|
|
.10702310297826761
|
|
.10946171077829933
|
|
.1119324278369056
|
|
.11443537382697373
|
|
.11697066775851084
|
|
.11953842798834562
|
|
.12213877222960187
|
|
.12477181756095049
|
|
.12743768043564743
|
|
.1301364766903643
|
|
.13286832155381798
|
|
.13563332965520566
|
|
.13843161503245183
|
|
.14126329114027164
|
|
.14412847085805777
|
|
.14702726649759498
|
|
.14995978981060856
|
|
.15292615199615017
|
|
.1559264637078274
|
|
.1589608350608804
|
|
.162029375639111
|
|
.1651321945016676
|
|
.16826940018969075
|
|
.1714411007328226
|
|
.17464740365558504
|
|
.17788841598362912
|
|
.18116424424986022
|
|
.184474994500441
|
|
.18782077230067787
|
|
.19120168274079138
|
|
.1946178304415758
|
|
.19806931955994886
|
|
.20155625379439707
|
|
.20507873639031693
|
|
.20863687014525575
|
|
.21223075741405523
|
|
.21586050011389926
|
|
.2195261997292692
|
|
.2232279573168085
|
|
.22696587351009836
|
|
.23074004852434915
|
|
.23455058216100522
|
|
.238397573812271
|
|
.24228112246555486
|
|
.24620132670783548
|
|
.25015828472995344
|
|
.25415209433082675
|
|
.2581828529215958
|
|
.26225065752969623
|
|
.26635560480286247
|
|
.2704977910130658
|
|
.27467731206038465
|
|
.2788942634768104
|
|
.2831487404299921
|
|
.2874408377269175
|
|
.29177064981753587
|
|
.2961382707983211
|
|
.3005437944157765
|
|
.3049873140698863
|
|
.30946892281750854
|
|
.31398871337571754
|
|
.31854677812509186
|
|
.32314320911295075
|
|
.3277780980565422
|
|
.33245153634617935
|
|
.33716361504833037
|
|
.3419144249086609
|
|
.3467040563550296
|
|
.35153259950043936
|
|
.3564001441459435
|
|
.3613067797835095
|
|
.3662525955988395
|
|
.3712376804741491
|
|
.3762621229909065
|
|
.38132601143253014
|
|
.386429433787049
|
|
.39157247774972326
|
|
.39675523072562685
|
|
.4019777798321958
|
|
.4072402119017367
|
|
.41254261348390375
|
|
.4178850708481375
|
|
.4232676699860717
|
|
.4286904966139066
|
|
.43415363617474895
|
|
.4396571738409188
|
|
.44520119451622786
|
|
.45078578283822346
|
|
.45641102318040466
|
|
.4620769996544071
|
|
.467783796112159
|
|
.47353149614800955
|
|
.4793201831008268
|
|
.4851499400560704
|
|
.4910208498478356
|
|
.4969329950608704
|
|
.5028864580325687
|
|
.5088813208549338
|
|
.5149176653765214
|
|
.5209955732043543
|
|
.5271151257058131
|
|
.5332764040105052
|
|
.5394794890121072
|
|
.5457244613701866
|
|
.5520114015120001
|
|
.5583403896342679
|
|
.5647115057049292
|
|
.5711248294648731
|
|
.5775804404296506
|
|
.5840784178911641
|
|
.5906188409193369
|
|
.5972017883637634
|
|
.6038273388553378
|
|
.6104955708078648
|
|
.6172065624196511
|
|
.6239603916750761
|
|
.6307571363461468
|
|
.6375968739940326
|
|
.6444796819705821
|
|
.6514056374198242
|
|
.6583748172794485
|
|
.665387298282272
|
|
.6724431569576875
|
|
.6795424696330938
|
|
.6866853124353135
|
|
.6938717612919899
|
|
.7011018919329731
|
|
.7083757798916868
|
|
.7156935005064807
|
|
.7230551289219693
|
|
.7304607400903537
|
|
.7379104087727308
|
|
.7454042095403874
|
|
.7529422167760779
|
|
.7605245046752924
|
|
.768151147247507
|
|
.7758222183174236
|
|
.7835377915261935
|
|
.7912979403326302
|
|
.799102738014409
|
|
.8069522576692516
|
|
.8148465722161012
|
|
.8227857543962835
|
|
.8307698767746546
|
|
.83879901174074
|
|
.846873231509858
|
|
.8549926081242338
|
|
.8631572134541023
|
|
.8713671191987972
|
|
.8796223968878317
|
|
.8879231178819663
|
|
.8962693533742664
|
|
.9046611743911496
|
|
.9130986517934192
|
|
.9215818562772946
|
|
.9301108583754237
|
|
.938685728457888
|
|
.9473065367331999
|
|
.9559733532492861
|
|
.9646862478944651
|
|
.9734452903984125
|
|
.9822505503331171
|
|
.9911020971138298
|
|
1;
|
|
|
|
/**
|
|
* Calculate the luminance for a color.
|
|
* See https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests
|
|
*/
|
|
@function luminance($color) {
|
|
$red: nth($linear-channel-values, red($color) + 1);
|
|
$green: nth($linear-channel-values, green($color) + 1);
|
|
$blue: nth($linear-channel-values, blue($color) + 1);
|
|
|
|
@return .2126 * $red + .7152 * $green + .0722 * $blue;
|
|
}
|
|
|
|
/**
|
|
* Calculate the contrast ratio between two colors.
|
|
* See https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests
|
|
*/
|
|
@function contrast($back, $front) {
|
|
$backLum: luminance($back) + .05;
|
|
$foreLum: luminance($front) + .05;
|
|
|
|
@return max($backLum, $foreLum) / min($backLum, $foreLum);
|
|
}
|
|
|
|
/**
|
|
* Determine whether to use dark or light text on top of given color.
|
|
* Returns black for dark text and white for light text.
|
|
*/
|
|
@function maximize-color-contrast($color) {
|
|
$lightContrast: contrast($color, white);
|
|
$darkContrast: contrast($color, black);
|
|
|
|
@if ($lightContrast > $darkContrast) {
|
|
@return white;
|
|
}
|
|
@else {
|
|
@return black;
|
|
}
|
|
} |