= 0 && $luminance < 0.45; } /** * WCAG contrast ratio between two colours. * * @param string $first * @param string $second * @return float 1-21, or 0 when either colour cannot be read. */ public static function contrast($first, $second): float { $firstLuminance = self::luminance($first); $secondLuminance = self::luminance($second); if ($firstLuminance < 0 || $secondLuminance < 0) { return 0.0; } $lighter = max($firstLuminance, $secondLuminance); $darker = min($firstLuminance, $secondLuminance); return ($lighter + 0.05) / ($darker + 0.05); } /** * Pick whichever of two text colours reads better on a background. * * @param string $background * @param string $light * @param string $dark * @return string */ public static function readableOn($background, string $light = '#ffffff', string $dark = '#1f2937'): string { return self::contrast($background, $light) >= self::contrast($background, $dark) ? $light : $dark; } /** * Nudge a colour toward white. * * @param string $color * @param int $percent * @return string */ public static function lighten($color, int $percent): string { return self::mix('#ffffff', $color, $percent); } /** * Nudge a colour toward black. * * @param string $color * @param int $percent * @return string */ public static function darken($color, int $percent): string { return self::mix('#000000', $color, $percent); } /** * Move a colour away from the surface it sits on, so it stays visible on * a light or a dark background without the caller knowing which it has. * * @param string $color * @param string $background * @param int $percent * @return string */ public static function awayFrom($color, $background, int $percent): string { return self::isDark($background) ? self::lighten($color, $percent) : self::darken($color, $percent); } }