Ja, ich bin’s wieder mit demselben Thema. Nachdem ich bereits angemerkt habe, die eigene SCSS-Farbkontrastfunktion zu korrigieren und wie du eine WCAG-2-konforme SCSS-Farbkontrastfunktion mit scssphp verwenden kannst, bemerkte eine Kollegin, dass diese Funktion in manchen Fällen falsche Ergebnisse lieferte.

Leider ist es nicht einfach, eine korrekte und WCAG-2-konforme Implementierung zu finden, die dasselbe Ergebnis wie der WebAIM contrast checker zurückgibt. Am Ende hat es eine Weile gebraucht, um die Bibliothek php-contrast von @breadthe zu finden, die die Berechnung richtig durchführt.

Sie ist ähnlich zu den Funktionen, die ich bereits gezeigt habe. Anstatt aber den Unterschied zwischen zwei Helligkeiten in absoluten Zahlen zu vergleichen, vergleicht diese Funktion sie anders, wodurch das richtige Kontrastverhältnis rauskommt.

In PHP kannst du sie so verwenden:

/**
 * Calculate the contrast between two colors and return either a light or dark
 * contrast color.
 * 
 * @param	string		$hex_color The color to test
 * @param	string		$dark The dark color
 * @param	string		$light The light color
 * @return	string The dark or the light color
 */
function get_color_contrast_color( string $hex_color, string $dark = '#000', string $light = '#fff' ): string {
	if ( empty( $hex_color ) ) {
		return $light;
	}
	
	$background_luminance = \get_luminance( $hex_color );
	$color_luminance = \get_luminance( $dark );
	$contrast_ratio = ( \max( $color_luminance, $background_luminance ) + .05 ) / ( \min( $color_luminance, $background_luminance ) + .05 );
	
	// if contrast is more than 4.5, return black color
	if ( $contrast_ratio >= 4.5 ) {
		return $dark;
	}
	
	return $light;
}

/**
 * Calculate luminance of a color.
 * 
 * @see		https://github.com/breadthe/php-contrast/blob/master/src/HexColorPair.php#L92-L112
 * 
 * @param	string	$color Hex color with 6 or 8 digits
 * @return	float Color luminance
 */
function get_luminance( string $color ): float {
	// Get decimal values
	$red = \base_convert( \substr( $color, 1, 2 ), 16, 10 );
	$green = \base_convert( \substr( $color, 3, 2 ), 16, 10 );
	$blue = \base_convert( \substr( $color, 5, 2 ), 16, 10 );
	
	// Get sRGB values
	$red_srgb = $red / 255;
	$green_srgb = $green / 255;
	$blue_srgb = $blue / 255;
	
	// Calculate luminance
	$r = ( $red_srgb <= .03928 ) ? $red_srgb / 12.92 : \pow( ( ( $red_srgb + .055 ) / 1.055 ), 2.4 );
	$g = ( $green_srgb <= .03928 ) ? $green_srgb / 12.92 : \pow( ( ( $green_srgb + .055 ) / 1.055 ), 2.4 );
	$b = ( $blue_srgb <= .03928 ) ? $blue_srgb / 12.92 : \pow( ( ( $blue_srgb + .055 ) / 1.055 ), 2.4 );
	
	return .2126 * $r + .7152 * $g + .0722 * $b;
}Code-Sprache: PHP (php)

Die Hilfsfunktion get_luminance ist praktisch dieselbe wie bereits in meinen zwei genannten Artikeln oben. In der Funktion get_color_contrast_color verwende ich die Helligkeit der gegebenen Farbe und vergleiche sie mit jener der dunklen Farbe. Wenn das Kontrastverhältnis höher als 4,5 ist, gebe ich die dunkle Farbe zurück, da das Kontrastverhältnis ausreichend ist, um WCAG-2-konform zu sein. Andernfalls gebe ich die helle Farbe zurück.

In SCSS kannst du sie so verwenden:

@use "sass:math";

@function de-gamma($n) {
	@if $n <= 0.03928 {
		@return math.div($n, 12.92);
	}
	@else {
		@return math.pow((math.div(($n + .055), 1.055)), 2.4);
	}
}

@function luminance($c) {
	$rlin: de-gamma(math.div(red($c), 255));
	$glin: de-gamma(math.div(green($c), 255));
	$blin: de-gamma(math.div(blue($c), 255));
	
	@return 0.2126 * $rlin + 0.7152 * $glin + 0.0722 * $blin;
}

@function contrast-color($color, $dark: #000, $light: #fff) {
	@if $color == null {
		@return null;
	}
	@else {
		$color-luminance: luminance($color);
		$dark-luminance: luminance($dark);
		
		@if (math.div(math.max($color-luminance, $dark-luminance) + .05, math.min($color-luminance, $dark-luminance) + .05) >= 4.5) {
			@return $light;
		}
		@else {
			@return $dark;
		}
	}
}Code-Sprache: SCSS (scss)

Bitte bedenke, dass diese Funktion nicht immer eine Farbe mit ausreichendem Kontrastverhältnis zurückgibt, je nachdem, welche Farben angegeben sind. Es gibt lediglich die dunkle Farbe zurück, wenn das Kontrastverhältnis zur eigentlichen Farbe einen bestimmten Grenzwert überschreitet und sonst die helle Farbe.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert