Accessibility (WCAG)
Best Text Color
bestGradientTextColor(colors, options?)
Returns '#000000' or '#ffffff' — whichever achieves the best minimum contrast across all gradient stops.
import { bestGradientTextColor } from 'css-magic-gradient'
// Two-color gradient (backward-compatible)
bestGradientTextColor('#1a1a2e', '#e94560')
// → '#ffffff'
// Multi-stop gradient
bestGradientTextColor(['#1a1a2e', '#c0357a', '#e94560'])
// → '#ffffff'
// Detailed result with per-color scores
const detail = bestGradientTextColor(['#1a1a2e', '#e94560'], { detailed: true })
// → { recommended: '#ffffff', black: { contrast: 1.8, wcag: 'fail' }, white: { contrast: 9.3, wcag: 'AAA' } }Contrast Ratio
gradientContrastRatio(textColor, colors)
Returns the minimum WCAG contrast ratio of a text color against the gradient. Samples 11 evenly distributed points along the gradient.
import { gradientContrastRatio } from 'css-magic-gradient'
// Two colors (backward-compatible)
gradientContrastRatio('#ffffff', '#1a1a2e', '#e94560')
// → minimum ratio across all sampled points
// Array of stops
gradientContrastRatio('#ffffff', ['#1a1a2e', '#c0357a', '#e94560'])WCAG Report
gradientWcagLevel(textColor, colors)
Returns a detailed GradientWcagReport with the worst-case WCAG level, minimum contrast, and positions that fail the AA threshold.
import { gradientWcagLevel } from 'css-magic-gradient'
const report = gradientWcagLevel('#ffffff', '#1a1a2e', '#e94560')
// → {
// level: 'AAA',
// minContrast: 8.4,
// problematicStops: [] // positions (0–1) where contrast < 4.5
// }
// With a gradient that has a weak midpoint:
const report2 = gradientWcagLevel('#ffffff', ['#ffffff', '#aaaaaa', '#3498db'])
// → { level: 'fail', minContrast: 1.07, problematicStops: [0, 0.09, 0.18, …] }GradientWcagReport
level
WcagLevel
Worst WCAG level found across all sampled stops.
minContrast
number
Minimum contrast ratio along the gradient.
problematicStops
number[]
Fractional positions (0–1) where contrast < 4.5.
Accessible Gradient
createAccessibleGradient(baseColor, textColor, options?)
Auto-adjusts gradient stops until textColor achieves the target WCAG level.
import { createAccessibleGradient } from 'css-magic-gradient'
// Default: adjusts lightness in 5% steps until AA is met
createAccessibleGradient('#3498db', '#ffffff', {
targetLevel: 'AA',
})
// Adjust saturation instead
createAccessibleGradient('#3498db', '#ffffff', {
targetLevel: 'AAA',
adjustmentStrategy: 'saturation',
})
// Adjust both lightness and saturation
createAccessibleGradient('#c0357a', '#000000', {
adjustmentStrategy: 'both',
direction: 'to right',
})AccessibleGradientOptions
direction
string · default: 'to bottom'
CSS direction keyword.
angle
number
Angle in degrees.
targetLevel
'AAA' | 'AA' | 'AA-large' · default: 'AA'
Minimum WCAG contrast level.
adjustmentStrategy
'lightness' | 'saturation' | 'both' · default: 'lightness'
How color stops are adjusted.
interpolation
ColorInterpolation
CSS Color Level 4 interpolation.
repeating
boolean · default: false
Use repeating-linear-gradient.
Re-exported from color-value-tools
The gradient* functions above are this package's own gradient-aware WCAG utilities. color-value-tools (the package's one runtime dependency) already ships single-color equivalents — css-magic-gradient re-exports them directly, so a consumer doesn't need to install color-value-tools separately just to check a single background/foreground pair.
import { bestTextColor, wcagLevel, contrastRatio, isDark } from 'css-magic-gradient'bestTextColor(background)
(background: string) => '#000000' | '#ffffff'
The single-color equivalent of bestGradientTextColor — picks black or white for the best contrast against one background color, not a gradient's full set of stops.
bestTextColor('#1a1a2e') // → '#ffffff'contrastRatio(a, b)
(a: string, b: string) => number
WCAG contrast ratio between two flat colors.
contrastRatio('#ffffff', '#1a1a2e') // → 15.8wcagLevel(foreground, background)
(foreground: string, background: string) => WcagLevel
WCAG level ('AAA' | 'AA' | 'AA-large' | 'fail') for one foreground/background pair.
wcagLevel('#ffffff', '#1a1a2e') // → 'AAA'isDark(color, threshold?)
(color: string, threshold?: number) => boolean
Whether a color is perceptually dark. threshold defaults to 0.5.
isDark('#1a1a2e') // → true