Last active
April 19, 2017 21:33
-
-
Save bradyhullopeter/7936d00776ba77370f79cba54179533e to your computer and use it in GitHub Desktop.
Sass functions for testing WCAG color compliance
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
// ---- | |
// Sass (v3.4.21) | |
// Compass (v1.0.3) | |
// ---- | |
/// @access private | |
@function gcd($a, $b) { | |
@if ($b != 0) { | |
@return gcd($b, $a % $b); | |
} @else { | |
@return abs($a); | |
} | |
} | |
/// @access private | |
@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; | |
} | |
/// @access private | |
@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; | |
} | |
/// @access private | |
@function getLuminance($color) { | |
$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); | |
} | |
/// @access private | |
@function getContrastRatio($color1, $color2) { | |
$luminance1: getLuminance($color1) + .05; | |
$luminance2: getLuminance($color2) + .05; | |
$ratio: $luminance1 / $luminance2; | |
@if $luminance2 > $luminance1 { | |
$ratio: 1 / $ratio; | |
} | |
$ratio: round($ratio * 10) / 10; | |
@return $ratio; | |
} | |
/// @access private | |
@function getBrightness($color) { | |
$blue: blue($color); | |
$red: red($color); | |
$green: green($color); | |
$percievedBrightness: ($red * 299 + $green * 587 + $blue * 114) / 1000; | |
@return $percievedBrightness; | |
} | |
/// @access private | |
@function getBrightnessDiff($color1, $color2) { | |
// https://www.w3.org/TR/AERT#color-contrast | |
$rtn: round(abs(getBrightness($color1) - getBrightness($color2))); | |
@return $rtn; | |
} | |
/// @access private | |
@function getColorDiff($color1, $color2) { | |
// https://www.w3.org/TR/AERT#color-contrast | |
$color1-blue: blue($color1); | |
$color1-red: red($color1); | |
$color1-green: green($color1); | |
$color2-blue: blue($color2); | |
$color2-red: red($color2); | |
$color2-green: green($color2); | |
$rtn: (max($color1-red, $color2-red) - min($color1-red, $color2-red)) + (max($color1-green, $color2-green) - min($color1-green, $color2-green)) + (max($color1-blue, $color2-blue) - min($color1-blue, $color2-blue)); | |
@return $rtn; | |
} | |
/// @access public | |
@function isColorDiffCompliant($color1, $color2) { | |
$diff: getColorDiff($color1, $color2); | |
@if ($diff < 500) { | |
@return false; | |
} @else { | |
@return true; | |
} | |
} | |
/// @access public | |
@function isBrightnessCompliant($color1, $color2) { | |
$brightness: getBrightnessDiff($color1, $color2); | |
@if ($brightness < 125) { | |
@return false; | |
} @else { | |
@return true; | |
} | |
} | |
/// access public | |
@function isColorCompliant($color1, $color2) { | |
@if (isBrightnessCompliant($color1, $color2) && isColorDiffCompliant($color1, $color2)) { | |
@return true; | |
} @else { | |
@return false; | |
} | |
} | |
/// access public | |
@function isWcagLargeAACompliant($color1, $color2) { | |
@if (getContrastRatio($color1, $color2) < 3) { | |
@return false; | |
} @else { | |
@return true; | |
} | |
} | |
/// access public | |
@function isWcagLargeAAACompliant($color1, $color2) { | |
@if (getContrastRatio($color1, $color2) >= 4.5) { | |
@return false; | |
} @else { | |
@return true; | |
} | |
} | |
/// access public | |
@function isWcagStandardAACompliant($color1, $color2) { | |
@if (getContrastRatio($color1, $color2) < 4.5) { | |
@return false; | |
} @else { | |
@return true; | |
} | |
} | |
/// access public | |
@function isWcagStandardAAACompliant($color1, $color2) { | |
@if (getContrastRatio($color1, $color2) >= 7) { | |
@return false; | |
} @else { | |
@return true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment