Theming animations based on user interaction or time of day often leads to maintaining multiple hardcoded color values. CSS Relative Colors, combined with the OKLCH color space, offer a systematic solution: define one foundation color and derive all others from it. This tutorial walks you through implementing this powerful technique for your SVG animations. For a deeper dive, you can refer to the original article on Smashing Magazine.

CSS code on a screen with colorful design elements Programming Illustration

Core Concept: Relative Color Syntax & OKLCH

The CSS Relative Color syntax uses the format oklch(from [base-color] [adjustments]). OKLCH's three channels—Lightness, Chroma, and Hue—allow for intuitive color manipulation.

/* 1. Define a foundation color (any format works) */
--foundation: #5accd6;

/* 2. Create derived colors using relative color */
/* Adjust Lightness (darker) */
--foundation-dark: oklch(from var(--foundation) calc(l - 0.20) c h);

/* Adjust Chroma (reduce by proportion) */
--foundation-muted: oklch(from var(--foundation) l calc(c * 0.5) h);

/* Adjust Hue (create complement - 180deg rotation) */
--foundation-complement: oklch(from var(--foundation) l c calc(h + 180));

In the code above, l, c, and h refer to the lightness, chroma, and hue values of the base color. Using calc() to modify these values generates new colors.

SVG animation and color palette on a designer's workspace System Abstract Visual

Practical Application: Building an Animation Theme System

Guiding Principles for Color Relationships

From practical experience, the author recommends:

  • Move Lightness: Add or subtract absolute values.
  • Scale Chroma: Multiply by a proportion to maintain the relationship to the base color.
  • Rotate Hue: Add or subtract degrees.

Applying to SVG Gradients

/* Inline SVG styles */
<linearGradient id="bgGradient">
  <stop offset="0%" style="stop-color: var(--grad-start);" />
  <stop offset="100%" style="stop-color: var(--grad-end);" />
</linearGradient>
/* Define gradient colors in CSS */
--foundation: #5accd6;
--grad-end: var(--foundation);
--grad-start: oklch(from var(--foundation)
                calc(l - 0.2357)  /* Decrease lightness */
                calc(c * 0.833)   /* Scale chroma */
                h);               /* Keep hue */

Now, changing the --foundation value automatically updates both gradient stops. No more manual recalculations!

Modern web developer desk setup with multiple monitors showing code IT Technology Image

Advanced Technique: Animating the Color Itself

Beyond static theming, you can animate the foundation color. Registering its channels with @property enables smooth interpolation.

/* 1. Register OKLCH channels as typed custom properties */
@property --f-l { syntax: '<number>'; inherits: true; initial-value: 0.40; }
@property --f-c { syntax: '<number>'; inherits: true; initial-value: 0.11; }
@property --f-h { syntax: '<number>'; inherits: true; initial-value: 305; }

/* 2. Reconstruct the foundation color from the channels */
--foundation: oklch(var(--f-l) var(--f-c) var(--f-h));

/* 3. Define keyframes to animate a channel */
@keyframes breathe {
  0%, 100% { --f-l: 0.36; }
  50% { --f-l: 0.46; }
}

/* 4. Apply the animation */
.toon-title {
  animation: breathe 10s ease-in-out infinite;
}

As --foundation animates, all colors derived from it (--foundation-dark, --grad-start, etc.) come to life in unison. Animating one value updates the entire color system, making maintenance significantly easier.

CSS Relative Colors are more than just syntax; they represent a powerful paradigm for building design systems. Consider applying this to button states, dark mode, or visual feedback. It will fundamentally change how you think about color on the web.