Saturon LogoSaturon

🚧 This documentation covers a pre-1.0 release. Expect breaking changes.

Guides & Tutorials

Accessibility & Color Difference Checks

Ensure your colors are readable and accessible using contrast() and deltaE*() methods to check contrast and perceptible color differences.

Saturon provides two complementary tools for accessibility and color analysis:

ToolPurposeBest for
contrast()WCAG 2.1 contrast ratio (1-21)Text on background (AA/AAA compliance)
deltaE*()Perceptual color difference (ΔE)Design consistency, brand colors, subtle variations

WCAG Contrast Ratio - Color.prototype.contrast() [contrast]

The contrast() method computes the WCAG 2.1 contrast ratio between two colors using relative luminance in xyz-d65. A ratio of ≥4.5 is required for normal text (AA), and ≥7 for AAA.

When to Use

  • Validate text over background
  • Check button states, links, icons
  • Automate accessibility audits

Syntax

contrast(other: Color | string): number

Example: Text Accessibility Check

import { Color } from "saturon";

const bg = Color.from("#1a1a1a"); // dark background
const text = Color.from("#e0e0e0"); // light gray text
const primary = Color.from("#0088cc"); // blue accent

console.log(text.contrast(bg)); // ~13.2 → PASS (AAA)
console.log(primary.contrast(bg)); // ~4.5  → PASS (AA)
console.log(bg.contrast(text)); // same as above (symmetric)

Threshold Helper

function isAccessible(textColor: Color, bgColor: Color, level: "AA" | "AAA" = "AA") {
    const ratio = textColor.contrast(bgColor);
    const threshold = level === "AAA" ? 7 : 4.5;
    return { ratio, pass: ratio >= threshold };
}

console.log(isAccessible(text, bg, "AAA")); // { ratio: 13.2, pass: true }

Perceptual Color Difference - Color.prototype.deltaE*() Methods [deltaE]

Use ΔE to measure how different two colors appear to the human eye. Saturon supports four formulas:

MethodAccuracySpeedUse Case
deltaEOK()High (OKLAB)FastGeneral design, UI, branding
deltaE76()LowFastestLegacy, simple checks
deltaE94()MediumFastImproved over 76
deltaE2000()HighestSlowerPrint, textiles, critical matching

Interpretation of ΔE Values

ΔE RangePerception
≤ 1.0Not perceptible
1-2Perceptible by experts
2-10Noticeable difference
≥ 10Clearly different

Fast, perceptually uniform, and scaled so ΔE ≈ 2 = Just Noticeable Difference (JND).

const brand = Color.from("#ff5733");
const variant = Color.from("#ff6b47");

console.log(brand.deltaEOK(variant)); // e.g., 3.4 → barely noticeable

deltaE2000() - Gold Standard for Precision

Use when maximum accuracy is required (e.g., color-critical workflows).

console.log(brand.deltaE2000(variant)); // e.g., 3.5 → slightly more accurate

Practical Use Cases

1. Ensure Brand Color Variants Are Subtle

function isBrandSafe(base: Color, variant: Color, maxDE = 3) {
    return base.deltaEOK(variant) <= maxDE;
}

const primary = Color.from("#0066cc");
const hover = Color.from("#0070cc");

console.log(isBrandSafe(primary, hover)); // true (ΔE = 2.7)

2. Detect Accidental Color Duplication

const palette = ["#ff5733", "#ff6b47", "#ff8040", "#33b5e5", "#00c851", "#ffbb33"].map((c) => Color.from(c));

for (let i = 0; i < palette.length; i++) {
    for (let j = i + 1; j < palette.length; j++) {
        const de = palette[i].deltaEOK(palette[j]);
        if (de < 5) {
            console.warn(`Colors ${i} and ${j} are too similar (ΔE = ${de.toFixed(1)})`);
        }
    }
}

3. Auto-Adjust Text Color for Readability

function getAccessibleText(bgColor: Color) {
    const light = Color.from("#ffffff");
    const dark = Color.from("#000000");

    const lightContrast = light.contrast(bgColor);
    const darkContrast = dark.contrast(bgColor);

    return lightContrast > darkContrast ? light : dark;
}

const bg = Color.from("#f39c12");
const text = getAccessibleText(bg);
console.log(text.to("hex-color")); // #000000 (dark text on orange)

Choosing the Right Tool

GoalUse
Text is readable?contrast() + WCAG thresholds
Are two swatches visually distinct?deltaEOK() (ΔE > 5)
Match print proof to screen?deltaE2000()
Quick brand check?deltaEOK()

Summary

MethodOutputPerceptual?Speed
contrast()1-21NoFast
deltaEOK()ΔE (~0-100)YesFast
deltaE2000()ΔE (~0-100)YesSlower