Use grayscale when color should stop carrying information while perceptual lightness remains close. Use inversion when the project explicitly needs an RGB negative. Inversion is not a general light-theme-to-dark-theme transformation.
Compare what each operation preserves
| Operation | Model | Preserves | Typical use |
|---|---|---|---|
grayscale() |
Set Oklch chroma to zero | Oklch lightness and alpha | Monochrome previews and color-independent review |
invert() |
Replace each encoded sRGB channel with 1 - channel |
Alpha and source object type | Image-like negative or explicit channel inversion |
use PhpColor\Color\Color;
$base = Color::parse('#3b82f6');
$gray = $base->grayscale();
$inverse = $base->invert();
echo $gray->toHex().PHP_EOL;
echo $inverse->toHex().PHP_EOL;
use PhpColor\Color\Color;
$base = Color::parse('#3b82f6');
$gray = $base->grayscale();
$inverse = $base->invert();
echo $gray->toHex().PHP_EOL;
echo $inverse->toHex().PHP_EOL;
The output is:
#878787
#c47d09
#878787
#c47d09
Keep theme and accessibility decisions separate
Neither result guarantees the original foreground-background contrast. Grayscale colors that looked distinct by hue may converge, while inversion can change luminance relationships unpredictably.
For complete themes, transform the named palette and recheck every semantic pair instead of inverting each token. Continue with Convert colors to grayscale, Invert color channels, or Simulate a palette for deuteranopia when the goal is accessibility review rather than removing color.