pub trait Wcag21RelativeContrast: Sized {
    type Scalar: Real + Add<Self::Scalar, Output = Self::Scalar> + Div<Self::Scalar, Output = Self::Scalar> + PartialCmp + MinMax;

    // Required method
    fn relative_luminance(self) -> LinLuma<D65, Self::Scalar>;

    // Provided methods
    fn relative_contrast(self, other: Self) -> Self::Scalar { ... }
    fn has_min_contrast_text(
        self,
        other: Self,
    ) -> <Self::Scalar as HasBoolMask>::Mask { ... }
    fn has_min_contrast_large_text(
        self,
        other: Self,
    ) -> <Self::Scalar as HasBoolMask>::Mask { ... }
    fn has_enhanced_contrast_text(
        self,
        other: Self,
    ) -> <Self::Scalar as HasBoolMask>::Mask { ... }
    fn has_enhanced_contrast_large_text(
        self,
        other: Self,
    ) -> <Self::Scalar as HasBoolMask>::Mask { ... }
    fn has_min_contrast_graphics(
        self,
        other: Self,
    ) -> <Self::Scalar as HasBoolMask>::Mask { ... }
}
Expand description

Calculate and check the WCAG 2.1 relative contrast and relative luminance.

W3C’s Web Content Accessibility Guidelines (WCAG) 2.1 suggest a method to calculate accessible contrast ratios of text and background colors for those with low vision or color vision deficiencies, and for contrast of colors used in user interface graphics objects.

These criteria come with a couple of caveats:

  • sRGB is assumed as the presentation color space, which is why it’s only implemented for a limited set of Rgb and Luma spaces.
  • The contrast ratio is not considered entirely consistent with the perceived contrast. WCAG 3.x is supposed to provide a better measurement.

Because of the inconsistency with perceived contrast, these methods are more suitable as hints and for mechanical verification of standards compliance, than for accurate analysis. Remember to not only rely on the numbers, but to also test your interfaces with actual people in actual situations for the best results.

The following example checks the contrast ratio of two colors in sRGB format:

use std::str::FromStr;
use palette::{Srgb, color_difference::Wcag21RelativeContrast};

// the rustdoc "DARK" theme background and text colors
let background: Srgb<f32> = Srgb::from(0x353535).into_format();
let foreground = Srgb::from_str("#ddd")?.into_format();

assert!(background.has_enhanced_contrast_text(foreground));

Required Associated Types§

source

type Scalar: Real + Add<Self::Scalar, Output = Self::Scalar> + Div<Self::Scalar, Output = Self::Scalar> + PartialCmp + MinMax

The scalar type used for luminance and contrast.

Required Methods§

source

fn relative_luminance(self) -> LinLuma<D65, Self::Scalar>

Returns the WCAG 2.1 relative luminance of self.

The relative luminance is a value between 0 and 1, where 0 is the darkest black and 1 is the lightest white. This is the same as clamped LinLuma, meaning that the typical implementation of this method would be self.into_color().

Provided Methods§

source

fn relative_contrast(self, other: Self) -> Self::Scalar

Returns the WCAG 2.1 relative luminance contrast between self and other.

A return value of, for example, 4 represents a contrast ratio of 4:1 between the lightest and darkest of the two colors. The range is from 1:1 to 21:1, and a higher contrast ratio is generally desirable.

This method is independent of the order of the colors, so a.relative_contrast(b) and b.relative_contrast(a) would return the same value.

source

fn has_min_contrast_text( self, other: Self, ) -> <Self::Scalar as HasBoolMask>::Mask

Verify the contrast between two colors satisfies SC 1.4.3. Contrast is at least 4.5:1 (Level AA).

This applies for meaningful text, such as body text. Font sizes of 18 points or lager, or 14 points when bold, are considered large and can be checked with has_min_contrast_large_text instead.

Success Criterion 1.4.3 Contrast (Minimum) (Level AA)

source

fn has_min_contrast_large_text( self, other: Self, ) -> <Self::Scalar as HasBoolMask>::Mask

Verify the contrast between two colors satisfies SC 1.4.3 for large text. Contrast is at least 3:1 (Level AA).

This applies for meaningful large text, such as headings. Font sizes of 18 points or lager, or 14 points when bold, are considered large.

Success Criterion 1.4.3 Contrast (Minimum) (Level AA)

source

fn has_enhanced_contrast_text( self, other: Self, ) -> <Self::Scalar as HasBoolMask>::Mask

Verify the contrast between two colors satisfies SC 1.4.6. Contrast is at least 7:1 (Level AAA).

This applies for meaningful text, such as body text. Font sizes of 18 points or lager, or 14 points when bold, are considered large and can be checked with has_enhanced_contrast_large_text instead.

Success Criterion 1.4.6 Contrast (Enhanced) (Level AAA)

source

fn has_enhanced_contrast_large_text( self, other: Self, ) -> <Self::Scalar as HasBoolMask>::Mask

Verify the contrast between two colors satisfies SC 1.4.6 for large text. Contrast is at least 4.5:1 (Level AAA).

This applies for meaningful large text, such as headings. Font sizes of 18 points or lager, or 14 points when bold, are considered large.

Success Criterion 1.4.6 Contrast (Enhanced) (Level AAA)

source

fn has_min_contrast_graphics( self, other: Self, ) -> <Self::Scalar as HasBoolMask>::Mask

Verify the contrast between two colors satisfies SC 1.4.11 for graphical objects. Contrast is at least 3:1 (Level AA).

This applies for any graphical object that aren’t text, such as meaningful images and interactive user interface elements.

Success Criterion 1.4.11 Non-text Contrast (Level AA)

Object Safety§

This trait is not object safe.

Implementors§

source§

impl<S, T> Wcag21RelativeContrast for Luma<S, T>
where Self: IntoColor<Luma<Linear<D65>, T>>, S: LumaStandard<WhitePoint = D65>, T: Real + Add<T, Output = T> + Div<T, Output = T> + PartialCmp + MinMax,

source§

impl<S, T> Wcag21RelativeContrast for Rgb<S, T>
where Self: IntoColor<Luma<Linear<D65>, T>>, S: RgbStandard<Space = Srgb>, T: Real + Add<T, Output = T> + Div<T, Output = T> + PartialCmp + MinMax,