Resolve relative colors

Derive a concrete color from source channels and visible channel math, including an origin supplied by context.

Relative expression oklch(from var(--brand)
calc(l + 0.1) c h / alpha)
Origin and channel math
--brand
#806eae
l
l + 0.1
c / h / alpha
unchanged
Concrete result OklchColor oklch(0.681141 0.0979163 296.154)
#9e8cce

Resolve the origin, then derive its channels

Without --brand, non-strict resolution retains a deferred RelativeColor.

Make the relative operation visible

The origin resolves first. The expression then adds 0.1 to lightness while passing chroma, hue, and alpha through unchanged.

<?php

use PhpColor\Color\Css\CssColor;
use PhpColor\Color\Css\CssContext;

$expression = CssColor::relative(
    'oklch', CssColor::var('--brand'),
    ['l' => 'calc(l + 0.1)', 'c' => 'c', 'h' => 'h'],
    'alpha',
);
$color = CssColor::resolve(
    $expression,
    CssContext::light(['--brand' => '#806eae']),
);

echo $color->toCss(); // oklch(0.681141 0.0979163 296.154)
echo $color->toHex(); // #9e8cce
use PhpColor\Color\Css\CssColor; use PhpColor\Color\Css\CssContext; $expression = CssColor::relative( 'oklch', CssColor::var('--brand'), ['l' => 'calc(l + 0.1)', 'c' => 'c', 'h' => 'h'], 'alpha', ); $color = CssColor::resolve( $expression, CssContext::light(['--brand' => '#806eae']), ); echo $color->toCss(); // oklch(0.681141 0.0979163 296.154) echo $color->toHex(); // #9e8cce

Use the implemented relative-color grammar

Use this workflow when the origin is deferred. Use Color::parse() for a self-contained relative expression, or instance methods for a concrete PHP color.

Channel order must match the target function. Numeric calc() supports arithmetic, parentheses, percentages, and available channel names.

CSS units, none, min(), max(), clamp(), and the complete browser grammar are not supported.

A deferred relative expression containing var() does not round-trip through CssColor::parse() in v1.

Choose a next step

Derive a color from the channels you receive