Color Desaturator
Generate a 5-step desaturation series for hover, active, focus, and disabled states. The interaction-state generator.
The Interaction State Problem Every Design System Hits
A typical button has at least five visual states: default, hover, active (pressed), focus, and disabled. Most design systems pick the default color carefully, then guess at the others by darkening or lightening with a percentage that feels right. The result is interaction states that work fine in isolation but feel slightly off when the user moves through them in sequence: the hover state is too close to the default, the disabled state is too dark, or the focus state competes visually with the default. The systematic fix is to generate the interaction states from the default using a consistent perceptual rule: each state moves a fixed amount in OKLCH lightness and chroma, calibrated so the steps feel proportional regardless of which base color you started with. Tailwind v4, Radix Themes, and most contemporary design systems do this internally. Color Desaturator exposes the same generator as a standalone tool, so you can plug in any brand color and get a five-step series ready to paste into design tokens or a stylesheet.
How the Five States Are Computed
Default is the input color unchanged, the brand color or palette anchor. Hover shifts the OKLCH lightness slightly (typically +0.04 for dark backgrounds, -0.04 for light backgrounds) and leaves chroma alone, which produces a hover effect that feels like the button is reacting rather than changing color. Active shifts lightness in the opposite direction from hover (typically -0.04 from default on dark backgrounds), simulating the pressed-button effect. Focus boosts chroma slightly (+0.02) without changing lightness, which adds visual prominence without making the button look like a different button; this state pairs well with a focus ring as a redundant indicator. Disabled drops chroma significantly (-0.10 minimum) and reduces lightness contrast, which is the perceptual rule for unactionable elements. The values are tunable with sliders if your design system uses different state deltas, and the output is a copy-ready CSS variable block or a JavaScript object suitable for design token configuration.
Pairing With Other State Decisions
Interaction states cover the color change; they do not cover the other indicators a good design system uses. For focus, the OKLCH chroma boost is one signal but a focus ring (outline) is the other, and both should be present for accessibility. For disabled, the color desaturation is supplemented with a pointer-events: none or aria-disabled attribute and reduced opacity. For hover and active, the color shift is usually paired with a subtle transform or shadow change. The output of this tool feeds into the color side of the system; the motion, focus ring, and accessibility attributes are independent decisions documented in the Contrast Checker and the Focus Order Visualizer. For a complete dark mode setup, run the desaturator separately for dark mode and light mode versions of the same brand color, since the optimal state deltas differ slightly between the two modes due to the perceived contrast difference at low and high lightness levels.
Frequently Asked Questions
Why five states instead of three?+
Three states (default, hover, disabled) covers the basics but misses two important cases. Active (pressed) provides feedback that the click registered before the action completes. Focus is required for keyboard navigation and accessibility compliance. A design system with five states feels noticeably more polished than one with three because every interaction has a dedicated visual response.
Are the default state deltas WCAG-compliant?+
The default deltas preserve contrast above 4.5-to-1 against typical backgrounds for the default and hover states, but the active state can dip below in low-lightness ranges and the disabled state intentionally drops below to signal unavailability. Always run the generated palette through the Contrast Checker against your specific backgrounds before shipping.
Can I generate this for a full palette at once?+
This tool generates a five-state series for one input color. For a full palette where every shade needs its own five states, run the tool once per palette anchor and combine the results in your design token configuration. A batch version is on the roadmap.
How is this different from Color Shade Generator?+
Color Shade Generator produces a tint and shade series across a wide lightness range, which is the right tool for building a 50-to-950 numeric palette scale. Color Desaturator produces the specific five-step series for UI interaction states, which uses smaller deltas and includes a chroma drop for the disabled state. The two tools are complementary: use Shade Generator for the palette anchors, then Desaturator for the interaction states per anchor.
Does the math work for dark mode too?+
Yes. The lightness deltas flip sign automatically depending on whether the input is closer to white or to black, so a hover state lightens dark-mode buttons and darkens light-mode buttons consistently. The chroma deltas are direction-independent and apply the same way to both modes.
Can I customize the state deltas?+
Yes. Sliders let you tune each delta independently. Common variations: increasing the hover delta to make hover states more obvious in marketing-focused design systems, decreasing the active delta to make the pressed state more subtle, and increasing the disabled chroma drop to make unavailable elements more recessive. The default values match typical 2026 design system conventions but every system has tuning preferences.
What CSS does the output produce?+
Five named CSS custom properties by default: --color-default, --color-hover, --color-active, --color-focus, and --color-disabled. The toggle lets you rename them to match your design token convention. A separate output panel shows the same values as a JavaScript object for design token configuration files used by Style Dictionary, Theo, and similar tools.
How do these states interact with prefers-reduced-motion?+
The color changes themselves are not motion and are unaffected by prefers-reduced-motion. The accompanying animations (typical transitions on the button for the color change) should respect prefers-reduced-motion by either disabling the transition or shortening it significantly. The tool does not generate transition CSS, but the recommended pattern is a 150ms ease transition on the color property, wrapped in a prefers-reduced-motion media query.
Built by Derek Giordano · Part of Ultimate Design Tools
Privacy Policy · Terms of Service