Relative colors and conic gradients 15 September 2024

A subtle gradient without sharp color changes can be a great way to add extra dimension to your designs. However, deciding on the right shades and the correct ratio for the gradient can be tiring, especially if you don’t have a clear picture in mind.

Fortunately, today we can use many handy CSS utilities to help with this process. In particular the relative color functions make abstracting the logic behind color selection much more intuitive!

Take a look at this example:

Notice how rich and vibrant the gradient is compared to the original color. The full snippet used in this example:

body {
  --main: lightcoral;
  --dark: oklch(from var(--main) calc(l - .25) calc(c + .05) h);
  --light: oklch(from var(--main) calc(l + .25) calc(c + .05) h);
  background: conic-gradient(
    at 50% -25%,
    var(--light),
    var(--dark)
  );
}

As you can see, I only chose one color, the --main variable, and left the browser to do the rest. Select an alternative color to get a different flavor of the same gradient.

Let’s break down the snippet.

Finding the right colors

To create a successful gradient, I need at least 2 colors. In this case, I want to start from the main color, and then find both a darker and lighter version.

The oklch() function takes a color value and returns the same color in the oklch color space -which is great, and you should use. Additionally, it gives you access to all the parameters (lightness, chroma, and hue), these can be hard-coded or modified using CSS calculations.

Yes, that’s right, you can say “find the color that is 180° from this hue”, and it will give you yellow if you input blue or cyan if you input red.

All in one line of CSS:

.my-component {
    background: oklch(from blue l c calc(h + 180)); /* yellow */
}

Modifing the lightness (l) to be slightly lower or higher, and adding 0.05 to the chroma (c) channel, is going to give me two rich variations of the main color.

Again, notice how vibrant these colors are, even the lighter one!

The conic gradient

At first, conic gradients might seem better suited for a clock rather than a background.

However, if you don’t consider the line at the start/end of the gradient (i.e. where the two colors meet after a full rotation), the surrounding area has a smooth and beautiful transition. This is exactly what we want.

The conic-gradient() syntax allows us to specify the position of the center and effectively move the line wherever we want. By default, it is in the center, or at 50/50% of the x and y axis.

Setting the y position at -25%, moves the line all the way to the top, and off screen by 25%. Another way to think about it, is that we “cropped” the initial gradient in a very specific section –the middle, where the darker and lighter shades blend into a similar color.

Of course this was just a small example of what is possible with only a few variables and functions in CSS today.

I encourage you to experiment and come up with something different, creating great effects has never been so simultaneously easy and powerful!