Build resolution contexts

Provide variables, theme, and current color before resolving expressions.

Build a context from values the server is authorized to know. Variables, theme, and currentColor are dependencies, not defaults PHPColor can discover from a stylesheet or DOM.

Choose strictness at the output boundary

Boundary Useful mode Missing context result
Final email, PDF, or static export Strict Fail instead of shipping unresolved required values
Browser CSS generation Non-strict Preserve expressions the browser can resolve
Incremental preview Non-strict Resolve known values and expose what remains

Build a resolution context

CssContext supplies CSS custom properties, a color scheme, strictness, and currentColor:

use PhpColor\Color\Css\CssContext;

$context = new CssContext(
    variables: [
        '--brand' => '#2563eb',
        '--surface' => '#ffffff',
    ],
    colorScheme: 'light',
    strict: true,
    currentColor: '#111827',
);
use PhpColor\Color\Css\CssContext; $context = new CssContext( variables: [ '--brand' => '#2563eb', '--surface' => '#ffffff', ], colorScheme: 'light', strict: true, currentColor: '#111827', );

Variable keys include their leading --. Values are CSS color strings that PHPColor parses when the variable is resolved.

For the common theme cases, use CssContext::light() or CssContext::dark():

$light = CssContext::light(['--brand' => '#2563eb']);
$dark = CssContext::dark(['--brand' => '#60a5fa'], '#f9fafb');
$light = CssContext::light(['--brand' => '#2563eb']); $dark = CssContext::dark(['--brand' => '#60a5fa'], '#f9fafb');

Contexts are readonly. withVar() and withCurrentColor() return new contexts instead of modifying the original.

Resolve an expression

Pass the expression and context to CssColor::resolve():

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

$expression = CssColor::parse('var(--brand, #2563eb)');
$result = CssColor::resolve(
    $expression,
    CssContext::light(['--brand' => '#1d4ed8']),
);

if ($result instanceof ColorInterface) {
    echo $result->toHex();
}
use PhpColor\Color\ColorInterface; use PhpColor\Color\Css\CssColor; use PhpColor\Color\Css\CssContext; $expression = CssColor::parse('var(--brand, #2563eb)'); $result = CssColor::resolve( $expression, CssContext::light(['--brand' => '#1d4ed8']), ); if ($result instanceof ColorInterface) { echo $result->toHex(); }

Resolution returns ColorInterface|CssResolvableInterface. In non-strict mode, missing context leaves the unresolved expression intact:

$result = CssColor::resolve(
    CssColor::parse('var(--missing)'),
    new CssContext(),
);

echo $result->toCss();
// var(--missing)
$result = CssColor::resolve( CssColor::parse('var(--missing)'), new CssContext(), ); echo $result->toCss(); // var(--missing)

This partial-resolution behavior is intentional. Check the return type before calling methods that exist only on concrete colors.

Keep context local and immutable

Contexts are readonly so one resolution cannot silently change the next. Derive a new context with withVar() or withCurrentColor() for a nested component or token set.

Strict mode does not turn PHPColor into a browser engine. It can reject missing variables or currentColor, but it does not discover cascade values, inspect media queries, or decide browser support.

Continue with Resolve custom properties, Resolve contextual CSS colors, or CssContext.