🔧 ProgrammierungThree checks that were green for the wrong reason(16.09.2026 um 06:43 Uhr)
🔧 ProgrammierungTreat the Grader as Code, Not a Hidden Prompt(16.09.2026 um 06:49 Uhr)
🔧 Programmierung[Event Sourcing] Trying out Sekiban DCB: Implementation(16.09.2026 um 06:50 Uhr)
🔧 AI Nachrichten An LLM Is Not Your Backend — Here's What I Learned(16.09.2026 um 06:53 Uhr)
🔧 ProgrammierungA week of NVIDIA news is 5,718 articles. My filter kept 161(16.09.2026 um 06:55 Uhr)
🔧 ProgrammierungThree checks that were green for the wrong reason(16.09.2026 um 06:43 Uhr)
🔧 ProgrammierungTreat the Grader as Code, Not a Hidden Prompt(16.09.2026 um 06:49 Uhr)
🔧 Programmierung[Event Sourcing] Trying out Sekiban DCB: Implementation(16.09.2026 um 06:50 Uhr)
🔧 AI Nachrichten An LLM Is Not Your Backend — Here's What I Learned(16.09.2026 um 06:53 Uhr)
🔧 ProgrammierungA week of NVIDIA news is 5,718 articles. My filter kept 161(16.09.2026 um 06:55 Uhr)

🔧 Programmierung 🕛 vor 10 Monaten 6 Min Lesezeit
0

Introducing Saturon: A Grammar-Aware Runtime for CSS Color Level 5

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

CSS color has grown up beyond rgb() and hsl(). We now have Display P3, Oklab, OKLCH, relative colors, and color-mix(). These new tools are changing how designers and developers think about colors on the web.



Unfortunately, most JavaScript color libraries fall behind. Adding new syntax or spaces often takes months, leaving developers waiting for maintainers to catch up.



I wanted a different approach. Instead of shipping fixed utilities, I built Saturon: a runtime-extensible color engine that implements the entire <color> syntax as real JavaScript objects. That means you can:




  • Parse any valid CSS color string, even nested or experimental syntax.

  • Convert colors across all modern spaces with spec-accurate results.

  • Extend the system with custom spaces, functions, and syntax in a few lines.






⚙️ A True Engine, Not Just a Converter



Saturon isn’t just a bag of utilities, it’s a full grammar-aware engine. It understands the entire CSS <color> syntax, including Level 4 and Level 5 constructs:




CODE
<color> = <color-base> | currentColor | <system-color> |
<contrast-color()> | <device-cmyk()> | <light-dark()>

<color-base> = <hex-color> | <color-function> | <named-color> |
<color-mix()> | transparent

<color-function> = <rgb()> | <rgba()> |
<hsl()> | <hsla()> | <hwb()> |
<lab()> | <lch()> | <oklab()> | <oklch()> |
<color()>






That means it can parse wild expressions like:




CODE
color-mix(
in oklch longer hue,
color(
from hsl(240deg none calc(-infinity) / 0.5)
display-p3
r calc(g + b) 100 / alpha
),
rebeccapurple 20%
)






You’ll never write CSS that wild, but Saturon can parse it anyway.






🖍️ Creating Colors



The Color class is the core API that represents any valid CSS color as a living object. Every color you work with in Saturon begins as a Color instance, which you can create in several ways depending on your needs.






🧩 1. Direct Model and Coordinates



If you already know the color model and component values, you can construct a color directly:




CODE
const color = new Color("rgb", [255, 0, 0]);









🧵 2. Parse from a CSS String



For everyday use, it’s easiest to create colors by parsing any valid CSS color string:




CODE
const color = Color.from("red");









🎲 3. Generate a Random Color



If you need a quick test data, you can generate random colors with:




CODE
const color = Color.random();






Each of these methods returns a fully functional Color instance that can be converted, manipulated, mixed, or fitted to a gamut, all using the same unified API.






🧪 Working with Colors



Once you’ve created a Color instance, Saturon gives you powerful ways to transform, convert, and combine it.






🔄 Converting Between Spaces



To create a new Color instance in another color space, use the .in() method:




CODE
const hsl = color.in("hsl");






This returns a new Color instance in the specified model. It’s perfect for manipulating colors in a specific space before manipulating (via .with()) or blending with another color (via .mix()).






🧾 Outputting Colors



You can serialize colors in several ways depending on your needs:




CODE
color.toString(); // → CSS color string
color.to("hex-color"); // → Hex string
color.toArray(); // → [r, g, b]
color.toObject(); // → { r, g, b }









🎨 Manipulating Components



The .with() method lets you adjust color components directly and returns a new Color instance, preserving immutability. Do you can chain transformations safely.:




CODE
color.with({ h: 120 }); // Set hue to 120°
color.with({ l: (l) => l / 2 }); // Modify lightness dynamically
color.with([120, 40, 10]); // Set all components at once









💫 Mixing Colors



Combine colors using CSS-accurate blending math with .mix(). It works just like CSS’s color-mix() function, with support for options such as amount, and hue interpolation.:




CODE
const red = Color.from("red");
const green = Color.from("green");

const mixed = red.in("lch").mix(green, { amount: 0.3, hue: "longer" });

console.log(mixed.to("rgb"));






Equivalent CSS:




CODE
color-mix(in lch longer hue, red, green 30%)









🌈 Gamut Mapping



When working across wide-gamut spaces, some colors can fall outside what a given device or color model can display. Saturon lets you decide exactly how those colors are handled.






🎯 The .within() Method



You can explicitly fit a color into a specific gamut using the .within() method. This creates a new Color instance that’s guaranteed to be inside the target gamut:




CODE
const fitted = color.within("srgb", "css-gamut-map");






The first argument defines the target gamut (e.g. "srgb", "display-p3", "rec2020"), and the second argument selects the mapping method:





  • "clip" → clamps out-of-range values directly to the gamut edges


  • "chroma-reduction" → reduces chroma while preserving hue and lightness


  • "css-gamut-map" → applies the official CSS Color 5 mapping algorithm



Because .within() works independently of serialization, you can fit colors before further manipulation, ensuring predictable behavior across different spaces and outputs.






🧾 Gamut Mapping in Output



Gamut fitting can also be applied automatically when converting or serializing colors. All output methods, toString(), toArray(), and toObject(), support a { fit } option:




CODE
color.toString({ fit: "css-gamut-map" });






When used this way, the method applies gamut mapping according to the target gamut of the output space:




  • For sRGB-bounded models like rgb and hsl, colors are automatically fit to the srgb gamut.

  • For unbounded spaces like lab, lch, oklab, or oklch, gamut mapping is skipped since these models have no display gamut limits.



This makes it easy to ensure your serialized colors remain display-safe without needing to manually constrain them first.






🔍 Utilities



The Color class also includes spec-based tools for comparison, contrast, and analysis:








































Method Description
deltaEOK(other) Perceptual ΔE in Oklab
deltaE76(other) ΔE using CIE76
deltaE94(other) ΔE using CIE94
deltaE2000(other) ΔE using CIEDE2000
contrast(other) Contrast ratio (WCAG 2.1)
equals(other) Equality tolerant of floating-point noise
inGamut(space) Check if within a gamut (e.g. sRGB)





🔌 Built for Extension



Saturon is extensible by design. You can register your own:




  • Color functions (jzazbz())

  • Color spaces (rec2100-pq)

  • Named colors (duskmint)

  • Fit methods (cam16-ucs)

  • Color bases (wavelength())

  • Even entirely new <color> syntaxes (color-at())



Example: hsv() color function in a few lines:




CODE
registerColorFunction("hsv", {
bridge: "hsl",
components: {
h: { index: 0, value: "angle" },
s: { index: 1, value: "percentage" },
v: { index: 2, value: "percentage" },
},
toBridge: ([h, s, v]) => [
/* h, s, l */
],
fromBridge: ([h, s, l]) => [
/* h, s, v */
],
});






Then use it like any other CSS color:




CODE
Color.from("hsv(133grad none calc(infinity))").to("oklch");






Even inside complex expressions:




CODE
const mixed = Color.from(`
color-mix(
in hsv longer hue,
hsv(133grad none calc(infinity)) 30%,
blue
)
`
);






It all just works.






🚀 Performance



Parsing the entire <color> grammar sounds heavy, but Saturon is highly optimized, and often faster than traditional object-oriented libraries.



10,000 parse + convert ops (Core i5-1135G7, Node 24):
















































Test saturon culori colorjs.io chroma-js color
Random input → random output ~75ms ~25ms ~230ms ~250ms ~110ms
Between color() spaces ~95ms ~240ms ~230ms
Relative color → random output ~230ms

color-mix() → random output
~380ms





⚖️ Spec Compliance & Tests



Saturon passes the full

👉 npm:

Vollständiger Original-Artikel
Den kompletten Beitrag mit allen Details direkt auf dev.to lesen.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Samsung Goes to Couples Therapy to Unpack iPhone-to-Android Tension
1 Quelle
Casetify Promo Codes | 15% Off September 2026
1 Quelle
Drohnendaten aus dem Ukraine-Krieg: Wie militärische Einsätze zu einer neuen Ressource für KI-Firmen werden
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Introducing Saturon: A Grammar-Aware Runtime for CSS Color Level 5

Thematisch verwandte Begriffe: Introducing, Saturon, GrammarAware, Runtime · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...