Use a chain when one color passes through a short, ordered pipeline whose stages are meaningful together. Use a palette transformation when the same operation must be applied consistently to several named colors.
Make the working and delivery spaces visible
A readable chain follows four phases:
- parse or receive the source;
- convert into coordinates suited to the edits;
- apply related immutable changes;
- convert and serialize for the consumer.
Convert once when exact channel work and relative operations belong in the same perceptual space:
use PhpColor\Color\Color;
$button = Color::parse('#3b82f6')
->to('oklch')
->withChannel('l', 0.65)
->desaturate(0.03)
->rotateHue(-4)
->withAlpha(0.9)
->to('srgb');
echo $button->toCss();
use PhpColor\Color\Color;
$button = Color::parse('#3b82f6')
->to('oklch')
->withChannel('l', 0.65)
->desaturate(0.03)
->rotateHue(-4)
->withAlpha(0.9)
->to('srgb');
echo $button->toCss();
The output is rgb(71 144 237 / 0.9). Every method returns a new object, so the original #3b82f6 value remains available.
Order operations by meaning
Color operations do not generally commute. Rotating hue and then converting to sRGB can clip a different result than clipping first and rotating later. Setting an exact channel before a relative adjustment also differs from applying the same steps in reverse.
Keep related perceptual edits in Oklch or Oklab, postpone narrow delivery formats until the end, and name intermediate values when a stage needs its own test or explanation. A long fluent chain hides decisions; split it when reviewers can no longer state what each stage guarantees.
The final serialized value is the production boundary. Reparse and repeat any material contrast, gamut, or distance check after formatting.
Continue with Choose a normalization boundary, Transform a complete palette, or ColorInterface.