konradmichalik / php-color
A small, framework-agnostic PHP library for color conversion, luminance, contrast and deterministic string-to-color hashing.
Requires
- php: ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0
Requires (Dev)
- armin/editorconfig-cli: ^2.0
- ergebnis/composer-normalize: ^2.42
- konradmichalik/php-cs-fixer-preset: ^0.2.0
- phpstan/phpstan: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- phpunit/phpunit: ^11.0 || ^12.0
- rector/rector: ^2.0
This package is auto-updated.
Last update: 2026-06-19 12:01:07 UTC
README
Color
A small, framework-agnostic PHP library for color conversion, luminance, contrast and deterministic string-to-color hashing. No runtime dependencies.
🚀 Features
- Immutable
Colorvalue object withRgbandHslcompanions - Lossless conversion between hex, RGB and HSL
- Multi-format string parsing via
fromString()/tryFromString() - CSS
rgb()/rgba()output with optional alpha channel - WCAG 2.x relative luminance and contrast ratio
optimalTextColor()— pick readable text color for any background- Deterministic string → color hashing (SHA-256/HSL or CRC32)
🔥 Installation
composer require konradmichalik/php-color
⚡ Usage
Conversion
use KonradMichalik\Color\Color; $color = Color::fromHex('#3366cc'); $color->toRgb(); // Rgb(51, 102, 204) $color->toHsl(); // Hsl(220.0, 60.0, 50.0) $color->toHex(); // "#3366cc" Color::fromRgb(51, 102, 204)->toHex(); // "#3366cc" Color::fromHsl(220, 60, 50)->toHex(); // "#3366cc" $color->withLightness(85)->toHex(); // a lighter variant (HSL space) $color->scaleRgb(0.5)->toHex(); // halve each RGB channel → "#1a3366" $color->darken(0.5)->toHex(); // alias for scaleRgb()
scaleRgb() multiplies every RGB channel by the factor (clamped to 0–255),
while withLightness() works in HSL space — use scaleRgb() for plain
per-channel brightness math. darken() is an alias. Factors below 0.0 throw
InvalidColorValue:
use KonradMichalik\Color\ColorHasher; ColorHasher::crc32()->hash($string)->scaleRgb(0.5)->toHex(); // darkened avatar color
Short hex (#abc), missing # and surrounding whitespace are all accepted.
Invalid values throw KonradMichalik\Color\Exception\InvalidColorValue.
Parsing arbitrary strings
fromString() accepts hex, rgb(r, g, b) and hsl(h, s%, l%) in one call —
whitespace is ignored, prefixes are case-insensitive and the HSL percent signs
are optional:
Color::fromString('#ff0000'); // red Color::fromString('f00'); // red Color::fromString('rgb(255, 0, 0)'); // red Color::fromString('hsl(0, 100%, 50%)'); // red Color::fromString('HSL(0,100,50)'); // red
Use tryFromString() for fallbacks — it returns null instead of throwing:
Color::tryFromString($userInput) ?? Color::fromHex('#cccccc');
CSS output with alpha
$rgb = Color::fromHex('#ff0000')->toRgb(); $rgb->toCssString(); // "rgb(255, 0, 0)" $rgb->toCssString(0.8); // "rgba(255, 0, 0, 0.8)" Color::fromHex('#ff0000')->toRgbaString(0.8); // "rgba(255, 0, 0, 0.8)"
The model stays RGB-only; alpha is an output concern. Values outside 0.0–1.0
throw KonradMichalik\Color\Exception\InvalidColorValue.
Contrast & readable text
$background = Color::fromHex('#222222'); $background->relativeLuminance(); // 0.0185… $background->contrastRatio(Color::fromHex('#fff')); // 15.9… $background->isDark(); // true $background->optimalTextColor()->toHex(); // "#ffffff"
optimalTextColor() returns whichever candidate (black/white by default, or two
custom colors) has the higher contrast against the background.
Deterministic colors from strings
Great for avatar backgrounds or tag colors — the same input always yields the same color:
use KonradMichalik\Color\ColorHasher; $hasher = ColorHasher::hsl(); // balanced SHA-256 → HSL (recommended) $hasher->hash('konrad@example.com'); // stable Color $hasher = ColorHasher::hsl(saturation: 70, lightness: 45); $hasher = ColorHasher::crc32(); // lightweight CRC32 → hex
Need a custom mapping? Implement KonradMichalik\Color\Hashing\HashStrategy and
pass it to new ColorHasher($strategy).
🧑💻 Contributing
Please have a look at CONTRIBUTING.md.
📄 License
This project is licensed under GPL-2.0-or-later.