惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
DataBreaches.Net
S
Schneier on Security
T
The Exploit Database - CXSecurity.com
Webroot Blog
Webroot Blog
AI
AI
P
Palo Alto Networks Blog
Attack and Defense Labs
Attack and Defense Labs
WordPress大学
WordPress大学
月光博客
月光博客
阮一峰的网络日志
阮一峰的网络日志
Spread Privacy
Spread Privacy
T
Tor Project blog
罗磊的独立博客
小众软件
小众软件
S
Security Affairs
酷 壳 – CoolShell
酷 壳 – CoolShell
量子位
Apple Machine Learning Research
Apple Machine Learning Research
T
Threatpost
NISL@THU
NISL@THU
博客园_首页
PCI Perspectives
PCI Perspectives
大猫的无限游戏
大猫的无限游戏
IT之家
IT之家
N
News and Events Feed by Topic
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Forbes - Security
Forbes - Security
博客园 - 叶小钗
D
Darknet – Hacking Tools, Hacker News & Cyber Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Last Week in AI
Last Week in AI
L
LINUX DO - 热门话题
T
Threat Research - Cisco Blogs
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
腾讯CDC
Security Latest
Security Latest
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
The Cloudflare Blog
A
About on SuperTechFans
爱范儿
爱范儿
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
TaoSecurity Blog
TaoSecurity Blog
宝玉的分享
宝玉的分享
G
GRAHAM CLULEY
雷峰网
雷峰网
F
Full Disclosure
I
Intezer
Cloudbric
Cloudbric
博客园 - 三生石上(FineUI控件)
U
Unit 42

CSS Articles by Temani Afif

Get Ready For the Powerful CSS border-shape Property! | CSS-Tricks Let’s Play With Gap Decorations! How to Control Infinite CSS Animations (Part 2 of 2) How to Control Infinite CSS Animations (Part 1 of 2) Two Circles, One Arrow, and Anchor Positioning Making a Responsive Pyramidal Grid With Modern CSS | CSS-Tricks How to Create a CSS-only Elastic Text Effect Making Complex CSS Shapes Using shape() | CSS-Tricks Responsive Hexagon Grid Using Modern CSS | CSS-Tricks Responsive List of Avatars Using Modern CSS (Part 2) | CSS-Tricks Responsive List of Avatars Using Modern CSS (Part 1) | CSS-Tricks Perfectly Pointed Tooltips: To The Corners Perfectly Pointed Tooltips: All Four Sides Perfectly Pointed Tooltips: A Foundation Sequential linear() Animation With N Elements | CSS-Tricks Infinite Marquee Animation using Modern CSS Better CSS Shapes Using shape() — Part 4: Close and Move | CSS-Tricks Drawing CSS Shapes using corner-shape Better CSS Shapes Using shape() — Part 3: Curves | CSS-Tricks Better CSS Shapes Using shape() — Part 2: More on Arcs | CSS-Tricks Better CSS Shapes Using shape() — Part 1: Lines and Arcs | CSS-Tricks Creating Blob Shapes using clip-path: shape() Creating Flower Shapes using clip-path: shape() Custom progress element using the attr() function A CSS-Only Star Rating Component and More! (Part 2) | CSS-Tricks A CSS-Only Star Rating Component and More! (Part 1) | CSS-Tricks How to Create Wavy Boxes Using CSS Full-Bleed Layout with Modern CSS Fancy Menu Navigation Using Anchor Positioning | CSS-Tricks How to Create a Zig-Zag Box Using CSS How to Create Zig-Zag CSS Loaders Using One Element Custom Progress Element Using Anchor Positioning & Scroll-Driven Animations How to Create Filling CSS Loaders Using One Element How to Create Curved-Edge and Rounded-Edge Shapes Using CSS CSS Tricks That Use Only One Gradient | CSS-Tricks How to create Shapes with Inner Curves using CSS Mask Custom Range Slider Using Anchor Positioning & Scroll-Driven Animations How to Get the Width/Height of Any Element in Only CSS How Keyboard Navigation Works in a CSS Game How To Create Cut-Out Shapes using The clip-path property The Modern Guide For Making CSS Shapes — Smashing Magazine css-shape.com: The Ultimate Collection of CSS-only Shapes ⚡️ Sliding 3D Image Frames In CSS — Smashing Magazine CSS Tricks To Master The clip-path Property Creating Wavy Circles with Fancy Animations in CSS Modern CSS Tooltips And Speech Bubbles (Part 2) — Smashing Magazine Do you need a Tooltip or a Speech Bubble? I have created 100 using CSS 😲 Modern CSS Tooltips And Speech Bubbles (Part 1) — Smashing Magazine Creating Flower Shapes using CSS Mask & Trigonometric Functions CSS Shapes: The Triangle The Complex But Awesome CSS border-image Property — Smashing Magazine CSS Tricks to add 3D Effects to your Text CSS Responsive Multi-Line Ribbon Shapes (Part 2) — Smashing Magazine CSS Responsive Multi-Line Ribbon Shapes (Part 1) — Smashing Magazine I have made 100+ CSS-only Ribbon Shapes | The Perfect Collection 🎀 How to create a CSS-only infinite scroll animation Re-Creating The Pop-Out Hover Effect With Modern CSS (Part 2) — Smashing Magazine Re-Creating The Pop-Out Hover Effect With Modern CSS (Part 1) — Smashing Magazine How to Create CSS Ribbon Shapes with a Single Element CSS Shapes: The Ribbon Revealing Images With CSS Mask Animations — Smashing Magazine css-loaders.com: The Biggest Collection of Loading Animations (more than 500 🤯) CSS effects on images II Shines, Perspective, And Rotations: Fancy CSS 3D Effects For Images — Smashing Magazine What's your Lucky CSS Pattern? Check It Now! How to Add a CSS Reveal Animation to Your Images Modern Layouts using CSS Grid I created 100+ unique CSS patterns | The best collection 🤩 How to Create a Custom Range Slider Using CSS CSS Shapes: The Heart CSS Shapes: Polygon & Starburst A Text Reveal Animation using CSS CSS Tip: learn CSS the easy way! How to build a CSS-only accordion How to create Breadcrumb Navigation with CSS Different Ways to Get CSS Gradient Shadows | CSS-Tricks A CSS-only responsive Stepper component A Fancy Hover Effect For Your Avatar | CSS-Tricks How to make a zoom effect using CSS Creating a Custom Cursor using CSS CSS Infinite 3D Sliders | CSS-Tricks CSS Infinite Slider Flipping Through Polaroid Images | CSS-Tricks How to create a responsive sidebar menu using CSS CSS Infinite and Circular Rotating Image Slider | CSS-Tricks Making Static Noise From a Weird CSS Gradient Bug | CSS-Tricks CSS Grid and Custom Shapes, Part 3 | CSS-Tricks Fancy Image Decorations: Outlines and Complex Animations | CSS-Tricks Fancy Image Decorations: Masks and Advanced Hover Effects | CSS-Tricks Fancy Image Decorations: Single Element Magic | CSS-Tricks How to create an infinite image slider using CSS How to Create Wavy Shapes & Patterns in CSS | CSS-Tricks How I Made a Pure CSS Puzzle Game | CSS-Tricks How to create a Tooltip/Speech Bubble using CSS CSS Grid and Custom Shapes, Part 2 | CSS-Tricks CSS Grid and Custom Shapes, Part 1 | CSS-Tricks Zooming Images in a Grid Layout | CSS-Tricks How to create a CSS-only loader with one element Exploring CSS Grid’s Implicit Grid and Auto-Placement Powers | CSS-Tricks How to create background pattern using CSS & conic-gradient Single Element Loaders: The Bars | CSS-Tricks
How To Define An Array Of Colors With CSS — Smashing Magazine
https://www.smashingmagazine.com/author/temani-afif/ · 2023-07-28 · via CSS Articles by Temani Afif

Join Temani Afif on experiment with modern CSS features to create an array of colors. The goal is to define a comma-separated list of colors and iterate through them using an index.

CSS is mainly known as a language based on a set of property-value pairs. You select an element, define the properties, and write styles for it. There’s nothing wrong with this approach, but CSS has evolved a lot recently, and we now have more robust features, like variables, math formulas, conditional logic, and a bunch of new pseudo selectors, just to name a few.

What if I tell you we can also use CSS to create an array? More precisely, we can create an array of colors. Don’t try to search MDN or the specification because this is not a new CSS feature but a combination of what we already have. It’s like we’re remixing CSS features into something that feels new and different.

For example, how cool would it be to define a variable with a comma-separated array of color values:

--colors: red, blue, green, purple;

Even cooler is being able to change an index variable to select only the color we need from the array. I know this idea may sound impossible, but it is possible — with some limitations, of course, and we’ll get to those.

Enough suspense. Let’s jump straight into the code!

We will first start with a basic use case with two colors defined in a variable:

--colors: black, white;

For this one, I will rely on the new color-mix() function. MDN has a nice way of explaining how the function works:

The color-mix() functional notation takes two <color> values and returns the result of mixing them in a given colorspace by a given amount.

The trick is not to use color-mix() for its designed purpose — mixing colors — but to use it instead to return one of the two colors in its argument list.

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

body {
  color: var(--_color);
}

So far, all we’ve done is assign the array of colors to a --colors variable, then update the index, --i, to select the colors. The index starts from 0, so it’s either 0 or 1, kind of like a Boolean check. The code may look a bit complex, but it becomes clear if we replace the variables with their values. For example, when i=0:

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

This results in black because the amount of white is 0%. We mixed 100% black with 0% white to get solid black. When i=1:

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

I bet you already know what happens. The result is solid white because the amount of white is 100% while black is 0%.

Think about it: We just created a color switch between two colors using a simple CSS trick. This sort of technique can be helpful if, say, you want to add a dark mode to your site’s design. You define both colors inside the same variable.

See the Pen [A color switch using color-mix()](https://codepen.io/t_afif/pen/XWPGWPp) by Temani Afif.

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

In that demo, I only update one variable, --i, to switch between dark and light modes.

If you are wondering what the hsl in the color-mix() function is doing, it’s the method used to mix the two colors. In our case, it serves no purpose since we are not actually mixing colors. So, you can use any method here, whether sRGB, HSL, OKLCH, OKLAB, or whatever you would like. Whatever it is, don’t forget it because it is a required value in color-mix().

An Array Of N Colors

Let’s move to the exciting part. I’ll create a multi-value array of colors and variables for it:

--colors: red, blue, green, purple; /* color array */
--n: 4; /* length of the array  */
--i: 0; /* index of the color [0 to N-1] */

Notice the variable, --n, which is new. I’m using it to define the number of colors in the array, i.e., its length. The index variable is largely the same as before, but it can go up to N-1 to select the needed color.

I’m going to change things up for you and create a linear gradient background instead of using color-mix(). Anyone who knows me well is totally not surprised by this as I reach for gradients all the time.

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

Here’s the gradient that renders. Nothing complex so far.

The result of the linear-gradient
The result of the linear-gradient. (Large preview)

The trick is manipulating the gradient to extract the colors based on the index. By definition, a gradient transitions between colors, but we have at least a few pixels of the actual colors defined in the array while we have a mixture or blend of colors in between them. At the very top, we can find red. At the very bottom, we can find purple. And so on.

What if we increase the size of the gradient to something really big?

See the Pen [Increasing gradient size](https://codepen.io/t_afif/pen/bGQqWyw) by Temani Afif.

See the Pen Increasing gradient size by Temani Afif.

Did you see that? By increasing the height of the gradient, it’s like we are zooming into the red color. We only see the red portion while the rest of the gradient is clipped out.

What if we increase the gradient by a factor of infinity? Yes, we can do that in CSS!

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

See the Pen [Infinity gradient size](https://codepen.io/t_afif/pen/NWEpjQd) by Temani Afif.

See the Pen Infinity gradient size by Temani Afif.

Now the box is solid red! In other words, we’ve selected red from the gradient of colors that are defined in the --colors array. If we want to change color, we adjust the position of the gradient.

By default, the gradient is located at the top-left edge of the element, 0 0. That’s why we only see the top color, red. Now we can use the index variable, --i, to adjust the gradient’s position and get whatever color we want from the array.

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

Here’s the complete code:

.box {
  --colors: red, blue, green, purple; /* color array */
  --n: 4; /* length of the array */
  --i: 0; /* index of the color [0 to N-1] */
  
  background:
    linear-gradient(var(--colors)) no-repeat
     0 calc(var(--i)*100%/(var(--n) - 1)) /* position */
     /100% calc(1px*infinity);  /* size */
}

Note: I used no-repeat in the background property. That keyword should be unnecessary, but for some reason, it’s not working without it. It might be that browsers cannot repeat gradients that have an infinite size.

The following demo illustrates the trick:

See the Pen [Colors array using only CSS](https://codepen.io/t_afif/pen/KKrNYyp) by Temani Afif.

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

Cool, right? We implemented an array of colors in CSS! And the code is not that complex. A simple background trick and a few variables are all we needed to make it happen.

Let’s Improve Indexing

Let’s push the limit a little and improve our work. In the previous example, the index, --i, is limited to the range [0 N-1], which makes sense. Any value outside that range will result in no color. What if we remove this restriction and allow the index to take any value?

Check this out:

See the Pen [Colors array using only CSS II](https://codepen.io/t_afif/pen/QWJpyGY) by Temani Afif.

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

Go ahead and play with the demo. You can specify any integer — even a negative one — and the browser will perform a modulo operation that converts the value in the [0 N-1] range. For example, 21 mod 4 = 1, resulting in the second color value in the array; -5 mod 4 = 3, which produces the fourth color value in the array.

In reality, the browser is not doing any mod operation, but I use a different implementation using a conical gradient that simulates a modulo operation:

background:
  conic-gradient(
    from calc((var(--i) + 1) * -1turn / var(--n)), 
    var(--colors) 0,var(--colors))
    top/calc(1px * infinity) calc(1px * infinity) no-repeat;

First, we define the conic gradient with the colors from the array:

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

Note that the variable is used twice. I did that to ensure the first color is the same as the last one so there is continuity in the coloration.

That code basically boils down to this conical gradient background:

background: conic-gradient(red, blue, green, purple 0, red, blue, green, purple)

By adding 0 to the last color (purple) and leaving everything else as-is, it’s like those other colors before purple don’t exist. That means the gradient is equivalent to this:

background: conic-gradient(purple 0, red, blue, green, purple)
Illustrating the difference between the intuitive gradient and the one with the same variable twice
Illustrating the difference between the intuitive gradient (on the left) and the one with the same variable twice (on the right). (Large preview)

After that, we can make our gradient very big by, once again, multiplying it by infinity. This time, infinity calculates the gradient’s width and height.

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

We place the gradient at the top to zoom in on the top color:

background-position: top;

Then we rotate the gradient to select the color we want:

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

It’s like having a color wheel where we only display a few pixels from the top.

A color wheel with one zoomed-in selected color from the top
We are zooming into the top of the gradient to show a solid color. The arrow illustrates the rotation we do to select the color. (Large preview)

Since what we have is essentially a color wheel, we can turn it as many times as we want in any direction and always get a color. This trick allows us to use any value we want for the index! After a full rotation, we get back to the same color.

See the Pen [Colors array using only CSS II](https://codepen.io/t_afif/pen/QWJpyGY) by Temani Afif.

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

Note that CSS does have a mod() function. So, instead of the conical gradient implementation, we can also update the first method that uses the linear gradient like this:

.box {
  --colors: red, blue, green, purple; /* color array */
  --n: 4; /* array length  */
  --i: 0; /* index  */
   
  --_i: mod(var(--i), var(--n)); /* the used index */
  background:
    linear-gradient(var(--colors)) no-repeat
     0 calc(var(--_i) * 100% / (var(--n) - 1)) /* position */
     / 100% calc(1px * infinity);  /* size */
}

I didn’t test the above code because support for mod() is still low for such a function. That said, you can keep this idea somewhere, as it might be helpful in the future and is probably more intuitive than the conic gradient approach.

What Are The limitations?

First, I consider this approach more of a hack than a CSS feature. So, use it cautiously. I’m not totally sure if there are implications to multiplying things by infinity. Forcing the browser to use a huge gradient can probably lead to a performance lag or, worse, accessibility issues. If you spot something, please share them in the comments so I can adjust this accordingly.

Another limitation is that this can only be used with the background property. We could overcome this with other tricks, like using background-clip: text to manipulate text color. But since this uses gradients, which are only supported by specific properties, usage is limited.

The two-color method is safe since it doesn’t rely on any hack. I don’t see any drawbacks to using it on real projects.

Wrapping Up

I hope you enjoyed this little CSS experimentation. We went from a simple two-color switch to an array of colors without adding much code. Now if someone tells you that CSS isn’t a programming language, you can tell them, “Hey, we have arrays!”

Now it’s your turn. Please show me what you will build using this trick. I will be waiting to see what you make, so share below!

Further Reading On SmashingMag

Smashing Editorial (gg, yk)