Back to Home

Smashing Animations Part 8: Theming Animations Using CSS Relative Colour
CSS relative colour values are now widely supported. In this article, pioneering author and web designer [Andy Clarke](https://stuffandnonsense.co.uk/) shares practical techniques for using them to theme and animate SVG graphics.
B
Blizine Admin
·1 min read·0 views
Skip to main content
Start reading the article
Jump to list of all articles
Jump to all topics13 min readAnimation,
CSS,
DesignShare on Twitter, LinkedInAbout The AuthorOften referred to as one of the pioneers of web design, Andy Clarke has been instrumental in pushing the boundaries of web design and is known for his creative …
More about
Andy ↬Email NewsletterYour (smashing) email
Weekly tips on front-end & UX.Trusted by 182,000+ folks.
See User Testing Live
Building Modern HTML Emails with Rémi Parmentier
SmashingConf Antwerp 2026
Smart Interface Design Patterns, 45 lessons + UX training
Smart Interface Design Patterns, 45 lessons + UX training
Custom Web Forms for Angular, React, & Vue. Your backend.
Celebrating 10 million developersCSS relative colour values are now widely supported. In this article, pioneering author and web designer Andy Clarke shares practical techniques for using them to theme and animate SVG graphics.I’ve recently refreshed the animated graphics on my website with a new theme and a group of pioneering characters, putting into practice plenty of the techniques I shared in this series. A few of my animations change appearance when someone interacts with them or at different times of day.View this animated SVG on my website. (Large preview)The colours in the graphic atop my blog pages change from morning until night every day. Then, there’s the snow mode, which adds chilly colours and a wintery theme, courtesy of an overlay layer and a blending mode.Snow mode allows my pioneer town background to adapt throughout the day. (Large preview)While working on this, I started to wonder whether CSS relative colour values could give me more control while also simplifying the process.Note: In this tutorial, I’ll focus on relative colour values and the OKLCH colour space for theming graphics and animations. If you want to dive deep into relative colour, Ahmad Shadeed created a superb interactive guide. As for colour spaces, gamuts, and OKLCH, our own Geoff Graham wrote about them.Smashing Animations Part 1: How Classic Cartoons Inspire Modern CSSSmashing Animations Part 2: How CSS Masking Can Add An Extra DimensionSmashing Animations Part 3: SMIL’s Not Dead Baby, SMIL’s Not DeadSmashing Animations Part 4: Optimising SVGsSmashing Animations Part 5: Building Adaptive SVGs With , , And CSS Media QueriesSmashing Animations Part 6: Magnificent SVGs With And CSS Custom PropertiesSmashing Animations Part 7: Recreating Toon Text With CSS And SVGHow Cartoon Animation Taught Me To Reuse EverythingThe Hanna-Barbera animated series I grew up watching had budgets far lower than those available when William Hanna and Joseph Barbera produced Tom and Jerry shorts at MGM Cartoons. This meant the animators needed to develop techniques to work around their cost restrictions.The Yogi Bear Show, copyright Warner Bros. Entertainment Inc. (Large preview)Repeated use of elements was key. Backgrounds were reused whenever possible, with zooms and overlays helping construct new scenes from the same artwork. It was born of necessity, but it also encouraged thinking in terms of series rather than individual scenes.The problem With Manually Updating Colour PalettesLet’s get straight to my challenge. In Toon Titles like this one — based on the 1959 Yogi Bear Show episode “Lullabye-Bye Bear” — and my work generally, palettes are limited to a select few colours.View this on my Toon Titles website. (Large preview)I create shades and tints from what I call my “foundation” colour to expand the palette without adding more hues.Colour palette with shades and tints of a foundation colour. (Large preview)In Sketch, I work in the HSL colour space, so this process involves increasing or decreasing the lightness value of my foundation colour. Honestly, it’s not an arduous task — but choosing a different foundation colour requires creating a whole new set of shades and tints. Doing that manually, again and again, quickly becomes laborious.Shades and tints of a different foundation colour. (Large preview)I mentioned the HSL — H (hue), S (saturation), and L (lightness) — colour space, but that’s just one of several ways to describe colour.RGB — R (red), G (green), B (blue) — is probably the most familiar, at least in its Hex form.There’s also LAB — L (lightness), A (green–red), B (blue–yellow) — and the newer, but now widely supported LCH — L (lightness), C (chroma), H (hue) — model in its OKLCH form. With LCH — specifically OKLCH in CSS — I can adjust the lightness value of my foundation colour.Lightness changes to my foundation colour. Chroma and Hue remain the same. (Large preview)Or I can alter its chroma. LCH chroma and HSL saturation both describe the intensity or richness of a colour, but they do so in different ways. LCH gives me a wider range and more predictable blending between colours.Chroma changes to my foundation colour. Lightness and Hue remain the same. (Large preview)I can also alter the hue to create a palette of colours that share the same lightness and chroma values. In both HSL and LCH, the hue spectrum starts at red, moves through green and blue, and returns to red.Hue changes to my foundation colour. Lightness and Chrome remain the same. (Large preview)Why OKLCH Changed How I Think About ColourBrowser support for the OKLCH colour space is now widespread, even if design tools — including Sketch — haven’t caught up. Fortunately, that shouldn’t stop you from using OKLCH. Browsers will happily convert Hex, HSL, LAB, and RGB values into OKLCH for you. You can define a CSS custom property with a foundation colour in any space, including Hex:/* Foundation colour */
--foundation: #5accd6;
Any colours derived from it will be converted into OKLCH automatically:--foundation-light: oklch(from var(--foundation) [...]; }
--foundation-mid: oklch(from var(--foundation) [...]; }
--foundation-dark: oklch(from var(--foundation) [...]; }
Relative Colour As A Design SystemThink of relative colour as saying: “Take this colour, tweak it, then give me the result.” There are two ways to adjust a colour: absolute changes and proportional changes. They look similar in code, but behave very differently once you start swapping foundation colours. Understanding that difference is what can turn using relative colour into a system./* Foundation colour */
--foundation: #5accd6;
For example, the lightness value of my foundation colour is 0.7837, while a darker version has a value of 0.5837. To calculate the difference, I subtract the lower value from the higher one and apply the result using a calc() function:--foundation-dark:
oklch(from var(--foundation)
calc(l - 0.20) c h);
To achieve a lighter colour, I add the difference instead:--foundation-light:
oklch(from var(--foundation)
calc(l + 0.10) c h);
Calculating the difference between my foundation colour and Lightness, Chroma, and Hue-adjusted colours. (Large preview)Chroma adjustments follow the same process. To reduce the intensity of my foundation colour from 0.1035 to 0.0035, I subtract one value from the other:oklch(from var(--foundation)
l calc(c - 0.10) h);
To create a palette of hues, I calculate the difference between the hue value of my foundation colour (200) and my new hue (260):oklch(from var(--foundation)
l c calc(h + 60));
Those calculations are absolute. When I subtract a fixed amount, I’m effectively saying, “Always subtract this much.” The same applies when adding fixed values:calc(c - 0.10)
calc(c + 0.10)
I learned the limits of this approach the hard way. When I relied on subtracting fixed chroma values, colours collapsed towards grey as soon as I changed the foundation. A palette that worked for one colour fell apart for another.Multiplication behaves differently. When I multiply chroma, I’m telling the browser: “Reduce this colour’s intensity by a proportion.” The relationship between colours remains intact, even when the foundation changes:calc(c * 0.10)
My Move It, Scale It, Rotate It RulesMove lightness (add or subtract),Scale chroma (multiply),Rotate hue (add or subtract degrees).I scale chroma because I want intensity changes to stay proportional to the base colour. Hue relationships are rotational, so multiplying hue makes no sense. Lightness is perceptual and absolute — multiplying it often produces odd results.Lightness: Move it. Chroma: Scale it. Hue: Rotate it. (Large preview)From One Colour To An Entire ThemeRelative colour allows me to define a foundation colour and generate every other colour I need — fills, strokes, gradient stops, shadows — from it. At that point, colour stops being a palette and starts being a system.SVG illustrations tend to reuse the same few colours across fills, strokes, and gradients. Relative colour lets you define those relationships once and reuse them everywhere — much like animators reused backgrounds to create new scenes.Change the foundation colour once, and every derived colour updates automatically, without recalculating anything by hand. Outside of animated graphics, I could use this same approach to define colours for the states of interactive elements such as buttons and links.The foundation colour I used in my “Lullabye-Bye Bear” Toon Title is a cyan-looking blue. The background is a radial gradient between my foundation and a darker version.View this on my Toon Titles website. (Large preview)To create alternative versions with entirely different moods, I only need to change the foundation colour:--foundation: #5accd6;
--grad-end: var(--foundation);
--grad-start: oklch(from var(--foundation)
calc(l - 0.2357) calc(c * 0.833) h);
Use the colour picker on my Toon Titles website to see this in action. (Large preview)To bind those custom properties to my SVG gradient without duplicating colour values, I replaced hard-coded stop-color values with inline styles:
📰Originally published at smashingmagazine.com
B
Blizine Admin
View Profile Staff Writer