Skip to content

Accessibility ​

Accessibility (WCAG) ​

relativeLuminance(color) ​

number — 0–1

WCAG relative luminance, using the standard sRGB linearization formula.

contrastRatio(c1, c2) ​

number — 1–21

WCAG contrast ratio between two colors: (lighter + 0.05) / (darker + 0.05).

wcagLevel(fg, bg) ​

WcagLevel — 'AAA' | 'AA' | 'AA-large' | 'fail'

Classifies the contrast ratio between foreground and background against the WCAG thresholds (≥7 AAA, ≥4.5 AA, ≥3 AA-large, else fail).

bestTextColor(bg) ​

'#000000' | '#ffffff'

Picks whichever of pure black or pure white has the higher contrast ratio against bg.

bestContrastColor(bg, candidates) ​

string — the candidate with the highest contrast ratio against bg

Picks the most readable color from an arbitrary list of candidates, not just black/white.

bestContrastPalette(bg, palettes, opts?) ​

PaletteScore & { paletteIndex: number } — { paletteIndex, palette, minContrastRatio, avgContrastRatio }

Scores each of palettes (a list of candidate color arrays) as avgContrastRatio × 0.4 + minContrastRatio × 0.6 (a heavy penalty on the single worst color) and returns the highest-scoring one. opts.weights sets per-color weights (by position) used when averaging each palette's contrast ratios — default equal weight for every color.

ts
import { bestContrastPalette } from 'color-value-tools'

const result = bestContrastPalette('#1a1a2e', [
  ['#ffffff', '#f0f0f0', '#cccccc'],
  ['#ffff00', '#ffd700', '#ff8c00'],
])
// → { paletteIndex: 0, palette: [...], minContrastRatio: 10.62, avgContrastRatio: 14.22 }

isReadableOnBackground(text, bg, opts?) ​

{ readable, minContrastRatio, wcagLevel }

Checks readability against solid, semi-transparent, or gradient backgrounds. bg accepts a plain color string, a semi-transparent spec, or a multi-stop gradient — a semi-transparent background is alpha-composited onto its underlay before the ratio is computed, and a gradient is evaluated at every stop, using the worst (lowest) ratio. The returned wcagLevel is always derived from that same effective background color (the composited color for a semi-transparent spec, the worst-case stop for a gradient), so it never disagrees with minContrastRatio/readable. opts: { level?: 'AA' | 'AAA'; largeText?: boolean }, defaulting to level: 'AA', largeText: false.

ts
import { isReadableOnBackground } from 'color-value-tools'

// Solid background
isReadableOnBackground('#ffffff', '#3498db')
// → { readable: false, minContrastRatio: 3.15, wcagLevel: 'AA-large' }

// Semi-transparent overlay composited over white
isReadableOnBackground('#ffffff', {
  type: 'semi-transparent',
  color: 'rgba(52, 152, 219, 0.5)',
  underlay: '#f0f0f0',
})

// Gradient — worst stop is used for the result
isReadableOnBackground('#ffffff', {
  type: 'gradient',
  stops: ['#1a1a2e', '#e94560', '#f5a623'],
})

// AAA + large text
isReadableOnBackground('#000000', '#f0f0f0', { level: 'AAA', largeText: true })

isDark(color, threshold?) ​

boolean — true if relativeLuminance(color) is below threshold (default 0.5)

isLight(color, threshold?) ​

boolean — the inverse of isDark, same threshold default

Color Blindness Simulation ​

Simulates perception using Vienot 1999 matrices applied to linearized RGB.

simulateProtanopia(color) ​

string — a #rrggbb color

Simulates the absence of L-cones (red-blindness).

simulateDeuteranopia(color) ​

string — a #rrggbb color

Simulates the absence of M-cones (green-blindness).

simulateTritanopia(color) ​

string — a #rrggbb color

Simulates the absence of S-cones (blue-blindness).

simulateColorBlindness(color, type) ​

string — a #rrggbb color

Generic entry point that dispatches to one of the three functions above by type — 'protanopia' | 'deuteranopia' | 'tritanopia'.

ts
import { simulateColorBlindness } from 'color-value-tools'

simulateColorBlindness('#e74c3c', 'deuteranopia') // '#c0c941'
simulateColorBlindness('#3498db', 'protanopia') // '#6e6fcd'