How To Outline An Array Of Colours With CSS — Smashing Journal


CSS is principally often called a language primarily based on a set of property-value pairs. You choose a component, outline the properties, and write kinds for it. There’s nothing unsuitable with this strategy, however CSS has advanced so much just lately, and we now have extra strong options, like variables, math formulation, conditional logic, and a bunch of recent pseudo selectors, simply to call just a few.

What if I inform you we are able to additionally use CSS to create an array? Extra exactly, we are able to create an array of colours. Don’t attempt to search MDN or the specification as a result of this isn’t a brand new CSS characteristic however a mixture of what we have already got. It’s like we’re remixing CSS options into one thing that feels new and completely different.

For instance, how cool wouldn’t it be to outline a variable with a comma-separated array of colour values:

--colors: pink, blue, inexperienced, purple;

Even cooler is having the ability to change an index variable to pick out solely the colour we’d like from the array. I do know this concept could sound unimaginable, however it is doable — with some limitations, after all, and we’ll get to these.

Sufficient suspense. Let’s bounce straight into the code!

An Array Of Two Colours

We are going to first begin with a fundamental use case with two colours outlined in a variable:

--colors: black, white;

For this one, I’ll depend on the brand new color-mix() operate. MDN has a pleasant approach of explaining how the operate works:

The color-mix() useful notation takes two <colour> values and returns the results of mixing them in a given colorspace by a given quantity.

The trick is to not use color-mix() for its designed function — mixing colours — however to make use of it as an alternative to return one of many two colours in its argument record.

:root {
  --colors: black, white; /* outline an array of colour values */
  --i: 0; 
  --_color: color-mix(in hsl, var(--colors) calc(var(--i) * 100%));

physique {
  colour: var(--_color);

Thus far, all we’ve performed is assign the array of colours to a --colors variable, then replace the index, --i, to pick out the colours. The index begins from 0, so it’s both 0 or 1, sort of like a Boolean examine. The code could look a bit complicated, however it turns into clear if we change the variables with their values. For instance, when i=0:

--_color: color-mix(in hsl, black, white 0%);

This leads to black as a result of the quantity of white is 0%. We blended 100% black with 0% white to get strong black. When i=1:

--_color: color-mix(in hsl, black, white 100%);

I guess you already know what occurs. The result’s strong white as a result of the quantity of white is 100% whereas black is 0%.

Give it some thought: We simply created a colour change between two colours utilizing a easy CSS trick. This kind of approach might be useful if, say, you wish to add a darkish mode to your web site’s design. You outline each colours inside the identical variable.

See the Pen [A color switch using color-mix()]( by Temani Afif.

See the Pen A colour change utilizing color-mix() by Temani Afif.

In that demo, I solely replace one variable, --i, to change between darkish and light-weight modes.

If you’re questioning what the hsl within the color-mix() operate is doing, it’s the strategy used to combine the 2 colours. In our case, it serves no function since we aren’t truly mixing colours. So, you should use any technique right here, whether or not sRGB, HSL, OKLCH, OKLAB, or no matter you desire to. No matter it’s, don’t neglect it as a result of it’s a required worth in color-mix().

Extra after bounce! Proceed studying under ↓

An Array Of N Colours

Let’s transfer to the thrilling half. I’ll create a multi-value array of colours and variables for it:

--colors: pink, blue, inexperienced, purple; /* colour array */
--n: 4; /* size of the array  */
--i: 0; /* index of the colour [0 to N-1] */

Discover the variable, --n, which is new. I’m utilizing it to outline the variety of colours within the array, i.e., its size. The index variable is essentially the identical as earlier than, however it may well go as much as N-1 to pick out the wanted colour.

I’m going to vary issues up for you and create a linear gradient background as an alternative of utilizing color-mix(). Anybody who is aware of me nicely is completely not shocked by this as I attain for gradients on a regular basis.

background-image: linear-gradient(var(--colors));

Right here’s the gradient that renders. Nothing complicated up to now.

The result of the linear-gradient
The results of the linear-gradient. (Giant preview)

The trick is manipulating the gradient to extract the colours primarily based on the index. By definition, a gradient transitions between colours, however we’ve a minimum of just a few pixels of the particular colours outlined within the array whereas we’ve a combination or mix of colours in between them. On the very prime, we are able to discover pink. On the very backside, we are able to discover purple. And so forth.

What if we improve the scale of the gradient to one thing actually huge?

See the Pen [Increasing gradient size]( by Temani Afif.

See the Pen Growing gradient measurement by Temani Afif.

Did you see that? By growing the peak of the gradient, it’s like we’re zooming into the pink colour. We solely see the pink portion whereas the remainder of the gradient is clipped out.

What if we improve the gradient by an element of infinity? Sure, we are able to do this in CSS!

background-image: linear-gradient(var(--colors));
background-size: 100% calc(1px * infinity);

See the Pen [Infinity gradient size]( by Temani Afif.

See the Pen Infinity gradient measurement by Temani Afif.

Now the field is strong pink! In different phrases, we’ve chosen pink from the gradient of colours which are outlined within the --colors array. If we wish to change colour, we regulate the place of the gradient.

By default, the gradient is positioned on the top-left fringe of the ingredient, 0 0. That’s why we solely see the highest colour, pink. Now we are able to use the index variable, --i, to regulate the gradient’s place and get no matter colour we would like from the array.

Illustration of the different positions we need to use to get the defined colors
Illustration of the completely different positions we have to use to get the outlined colours. (Giant preview)
background-position: 0 calc(var(--i) * 100% / (var(--n) - 1));

Right here’s the entire code:

.field {
  --colors: pink, blue, inexperienced, purple; /* colour array */
  --n: 4; /* size of the array */
  --i: 0; /* index of the colour [0 to N-1] */
    linear-gradient(var(--colors)) no-repeat
     0 calc(var(--i)*100%/(var(--n) - 1)) /* place */
     /100% calc(1px*infinity);  /* measurement */

Notice: I used no-repeat within the background property. That key phrase ought to be pointless, however for some motive, it’s not working with out it. It may be that browsers can’t repeat gradients which have an infinite measurement.

The next demo illustrates the trick:

See the Pen [Colors array using only CSS]( by Temani Afif.

See the Pen Colours array utilizing solely CSS by Temani Afif.

Cool, proper? We carried out an array of colours in CSS! And the code isn’t that complicated. A easy background trick and some variables are all we would have liked to make it occur.

Let’s Enhance Indexing

Let’s push the restrict just a little and enhance our work. Within the earlier instance, the index, --i, is proscribed to the vary [0 N-1], which is smart. Any worth exterior that vary will end in no colour. What if we take away this restriction and permit the index to take any worth?

Test this out:

See the Pen [Colors array using only CSS II]( by Temani Afif.

See the Pen Colours array utilizing solely CSS II by Temani Afif.

Go forward and play with the demo. You’ll be able to specify any integer — even a adverse one — and the browser will carry out a modulo operation that converts the worth within the [0 N-1] vary. For instance, 21 mod 4 = 1, ensuing within the second colour worth within the array; -5 mod 4 = 3, which produces the fourth colour worth within the array.

In actuality, the browser isn’t doing any mod operation, however I take advantage of a unique implementation utilizing a conical gradient that simulates a modulo operation:

    from calc((var(--i) + 1) * -1turn / var(--n)), 
    var(--colors) 0,var(--colors))
    prime/calc(1px * infinity) calc(1px * infinity) no-repeat;

First, we outline the conic gradient with the colours from the array:

background: conic-gradient(var(--colors) 0,var(--colors))

Notice that the variable is used twice. I did that to make sure the primary colour is identical because the final one so there’s continuity within the coloration.

That code principally boils all the way down to this conical gradient background:

background: conic-gradient(pink, blue, inexperienced, purple 0, pink, blue, inexperienced, purple)

By including 0 to the final colour (purple) and leaving all the things else as-is, it’s like these different colours earlier than purple don’t exist. Which means the gradient is equal to this:

background: conic-gradient(purple 0, pink, blue, inexperienced, purple)
Illustrating the difference between the intuitive gradient and the one with the same variable twice
Illustrating the distinction between the intuitive gradient (on the left) and the one with the identical variable twice (on the suitable). (Giant preview)

After that, we are able to make our gradient very huge by, as soon as once more, multiplying it by infinity. This time, infinity calculates the gradient’s width and peak.

background-size: calc(1px * infinity) calc(1px * infinity);

We place the gradient on the prime to zoom in on the highest colour:

background-position: prime;

Then we rotate the gradient to pick out the colour we would like:

from calc((var(--i) + 1) * -1turn / var(--n))

It’s like having a colour wheel the place we solely show just a few pixels from the highest.

A color wheel with one zoomed-in selected color from the top
We’re zooming into the highest of the gradient to point out a strong colour. The arrow illustrates the rotation we do to pick out the colour. (Giant preview)

Since what we’ve is actually a colour wheel, we are able to flip it as many occasions as we would like in any route and all the time get a colour. This trick permits us to make use of any worth we would like for the index! After a full rotation, we get again to the identical colour.

See the Pen [Colors array using only CSS II]( by Temani Afif.

See the Pen Colours array utilizing solely CSS II by Temani Afif.

Notice that CSS does have a mod() operate. So, as an alternative of the conical gradient implementation, we are able to additionally replace the primary technique that makes use of the linear gradient like this:

.field {
  --colors: pink, blue, inexperienced, purple; /* colour array */
  --n: 4; /* array size  */
  --i: 0; /* index  */
  --_i: mod(var(--i), var(--n)); /* the used index */
    linear-gradient(var(--colors)) no-repeat
     0 calc(var(--_i) * 100% / (var(--n) - 1)) /* place */
     / 100% calc(1px * infinity);  /* measurement */

I didn’t check the above code as a result of assist for mod() continues to be low for such a operate. That mentioned, you possibly can maintain this concept someplace, because it may be useful sooner or later and might be extra intuitive than the conic gradient strategy.

What Are The constraints?

First, I contemplate this strategy extra of a hack than a CSS characteristic. So, use it cautiously. I’m not completely positive if there are implications to multiplying issues by infinity. Forcing the browser to make use of an enormous gradient can most likely result in a efficiency lag or, worse, accessibility points. If you happen to spot one thing, please share them within the feedback so I can regulate this accordingly.

One other limitation is that this will solely be used with the background property. We may overcome this with different tips, like utilizing background-clip: textual content to govern textual content colour. However since this makes use of gradients, that are solely supported by particular properties, utilization is proscribed.

The 2-color technique is protected because it doesn’t depend on any hack. I don’t see any drawbacks to utilizing it on actual tasks.

Wrapping Up

I hope you loved this little CSS experimentation. We went from a easy two-color change to an array of colours with out including a lot code. Now if somebody tells you that CSS isn’t a programming language, you possibly can inform them, “Hey, we’ve arrays!”

Now it’s your flip. Please present me what you’ll construct utilizing this trick. I might be ready to see what you make, so share under!

Additional Studying On SmashingMag

Smashing Editorial
(gg, yk)


Please enter your comment!
Please enter your name here