So, it's that time of the year, if you live in Europe: Eurovision! It's the world's oldest and largest song competition — that people either love, hate or love/hate!
I watched the first semifinal yesterday, and was actually blown away by the graphic design this year. Really nice, animated gradients — and a very vibrant color palette.
But … then I went to the official website, and saw a 4.6 megabyte pixelated, sad looking animated gradient! Why? When we can easily do animated gradients in CSS?
Let's dive in.
Re-creating the gradients
If you look at the gradients — or if you watched the show — you'll notice it's basically a grid with columns that span between 1—8.
.eurovision {
aspect-ratio: 4/1;
container-type: inline-size;
display: grid;
grid-auto-flow: column;
position: relative;
width: 100%;
}
Now, for the columns, we'll create a bunch of <b>
-tags (can be any tag, basically), and add some CSS:
b {
animation: Y var(--animdur, 5s) var(--animdel, 0s) var(--animtf, linear) infinite;
background: repeating-linear-gradient(var(--deg, 0deg), var(--c1, orange), var(--c2, hotpink), var(--c3, yellow), var(--c2, hotpink), var(--c1, orange));
background-size: 100% 500%;
display: block;
}
The animation simply moves the Y-position of the background:
@keyframes Y {
to { background-position-y: 250%; }
}
To create some variation, we change the animation-delay
for the <b>
-tags, based on their nth-of-type
:
b {
&:nth-of-type(1) { --animdel: 50ms; }
&:nth-of-type(2) { --animdel: 100ms; }
&:nth-of-type(3) { --animdel: 150ms; }
&:nth-of-type(4) { --animdel: 200ms; }
&:nth-of-type(5) { --animdel: 250ms; }
/* etc. */
}
Finally, for the column-spans, we add some modifier-classes:
.span-2 { grid-column: span 2; }
.span-3 { grid-column: span 3; }
.span-4 { grid-column: span 4; }
/* etc. */
Let's see how we're doing:
Vibrant! Now, because of the custom properties, we can just add a class with some updates to get the purple/pink-gradient:
.header {
--c1: purple;
--c2: deeppink;
--c3: hotpink;
}
Nice! I added a gradient text as well:
h1 {
background: linear-gradient(95deg, yellow, hotpink, deeppink, orange);
background-clip: text;
font-family: "Hind", sans-serif;
font-optical-sizing: auto;
font-weight: 500;
font-style: normal;
font-size: 10cqi;
letter-spacing: -0.075ch;
place-self: center center;
position: absolute;
text-transform: uppercase;
-webkit-text-fill-color: transparent;
}
Now, for the red/blue-version, I took one of the nice linear()
timing-functions from Adam Argyle's Open Props:
.red-shift {
--c1:red;
--c2:purple;
--c3:blue;
--animtf:linear( 0, .006, .025 2.8%, .101 6.1%, .539 18.9%, .721 25.3%, .849 31.5%, .937 38.1%, .968 41.8%, .991 45.7%, 1.006 50.1%, 1.015 55%, 1.017 63.9%, 1.001 );
}
And we get:
And that's it! Remember to vote for your favorite song, and check out the CodePen here: