Last active
February 4, 2021 16:30
-
-
Save graygilmore/8d5e2b2dbc620804f33b to your computer and use it in GitHub Desktop.
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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 hover($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 { | |
/* Test if we can find a color with a better contrast */ | |
@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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment