I'm looking for a concise way to compute the color contrast ratio between two UIColor
instances in Swift. I've found examples that are close but are overly complicated or outdated.
UIColor
extension with contrast ratio and luminanceThe following UIColor
extension includes a static and instance contrast ratio method. A bonus luminance method is included since it is used by the static contrastRatio(between:and:)
method.
import UIKit
extension UIColor {
static func contrastRatio(between color1: UIColor, and color2: UIColor) -> CGFloat {
// https://www.w3.org/TR/WCAG20-TECHS/G18.html#G18-tests
let luminance1 = color1.luminance()
let luminance2 = color2.luminance()
let luminanceDarker = min(luminance1, luminance2)
let luminanceLighter = max(luminance1, luminance2)
return (luminanceLighter + 0.05) / (luminanceDarker + 0.05)
}
func contrastRatio(with color: UIColor) -> CGFloat {
return UIColor.contrastRatio(between: self, and: color)
}
func luminance() -> CGFloat {
// https://www.w3.org/TR/WCAG20-TECHS/G18.html#G18-tests
let ciColor = CIColor(color: self)
func adjust(colorComponent: CGFloat) -> CGFloat {
return (colorComponent < 0.04045) ? (colorComponent / 12.92) : pow((colorComponent + 0.055) / 1.055, 2.4)
}
return 0.2126 * adjust(colorComponent: ciColor.red) + 0.7152 * adjust(colorComponent: ciColor.green) + 0.0722 * adjust(colorComponent: ciColor.blue)
}
}
// static method
let contrastRatio1 = UIColor.contrastRatio(between: UIColor.black, and: UIColor.white)
print(contrastRatio1) // 21.0
// instance method
let contrastRatio2 = UIColor.black.contrastRatio(with: UIColor.white)
print(contrastRatio2) // 21.0
Following these links:
For predefinite colorspace (like in iOS see this https://developer.apple.com/videos/play/wwdc2016/712/) and also in general the correct THRESHOLD value is 0.04045 and not 0.03928 (read more)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With