rustyle_css/a11y/
contrast.rs

1//! Color contrast checking utilities
2//!
3//! Provides WCAG contrast checking and automatic color adjustments.
4
5use crate::css::Color;
6
7/// Calculate relative luminance of a color
8fn relative_luminance(color: &Color) -> f64 {
9    // Simplified implementation
10    // A full implementation would convert color to RGB and calculate luminance
11    match color {
12        Color::Rgb(r, g, b) => {
13            let r = *r as f64 / 255.0;
14            let g = *g as f64 / 255.0;
15            let b = *b as f64 / 255.0;
16
17            let r = if r <= 0.03928 {
18                r / 12.92
19            } else {
20                ((r + 0.055) / 1.055).powf(2.4)
21            };
22            let g = if g <= 0.03928 {
23                g / 12.92
24            } else {
25                ((g + 0.055) / 1.055).powf(2.4)
26            };
27            let b = if b <= 0.03928 {
28                b / 12.92
29            } else {
30                ((b + 0.055) / 1.055).powf(2.4)
31            };
32
33            0.2126 * r + 0.7152 * g + 0.0722 * b
34        }
35        _ => 0.5, // Default for other color types
36    }
37}
38
39/// Calculate contrast ratio between two colors
40pub fn contrast_ratio(foreground: &Color, background: &Color) -> f64 {
41    let l1 = relative_luminance(foreground);
42    let l2 = relative_luminance(background);
43
44    let lighter = l1.max(l2);
45    let darker = l1.min(l2);
46
47    (lighter + 0.05) / (darker + 0.05)
48}
49
50/// Check if contrast meets WCAG AA standard (4.5:1 for normal text, 3:1 for large text)
51pub fn meets_wcag_aa(foreground: &Color, background: &Color, large_text: bool) -> bool {
52    let ratio = contrast_ratio(foreground, background);
53    if large_text {
54        ratio >= 3.0
55    } else {
56        ratio >= 4.5
57    }
58}
59
60/// Check if contrast meets WCAG AAA standard (7:1 for normal text, 4.5:1 for large text)
61pub fn meets_wcag_aaa(foreground: &Color, background: &Color, large_text: bool) -> bool {
62    let ratio = contrast_ratio(foreground, background);
63    if large_text {
64        ratio >= 4.5
65    } else {
66        ratio >= 7.0
67    }
68}
69
70/// Adjust color to meet contrast requirements
71pub fn adjust_for_contrast(foreground: &mut Color, background: &Color, target_ratio: f64) {
72    // Simplified: would need to lighten/darken the color
73    // A full implementation would iteratively adjust the color
74    let current_ratio = contrast_ratio(foreground, background);
75    if current_ratio < target_ratio {
76        // Would adjust color here
77    }
78}