I have a <h1>
heading text that has each individual letter wrapped within a <span>
, as so:
<h1 class='gradient-heading' id='fade'>
<span>H</span>
<span>e</span>
<span>l</span>
<span>l</span>
<span>o</span>
</h1>
I would like to apply a gradient color to this heading text. As far as I know, the only way to do that is to use CSS background-clip: text
and make the text inside transparent, something like:
.gradient-heading {
background: linear-gradient(90deg, rgba(239,255,0,1) 0%, rgba(255,182,0,1) 48%, rgba(199,0,255,1) 100%);
background-clip: text;
color: transparent;
}
Now let’s say that I want to fade in and out each individual <span>
within the <h1>
heading. With JavaScript this can be done with something like:
function fadeLetters() {
const heading = document.getElementById('fade');
const spans = heading.querySelectorAll('span');
let delay = 0;
let delayIncrement = 200;
let numLettersFadedIn = 0;
const totalLetters = spans.length;
spans.forEach((span, index) => {
setTimeout(() => {
span.style.transition = 'opacity 1s ease-in-out';
span.style.opacity = 1;
numLettersFadedIn++;
if (numLettersFadedIn === totalLetters) {
setTimeout(() => {
spans.forEach((span, index) => {
setTimeout(() => {
span.style.transition = 'opacity 1s ease-in-out';
span.style.opacity = 0;
}, index * delayIncrement);
});
setTimeout(() => {
numLettersFadedIn = 0;
fadeLetters();
}, totalLetters * delayIncrement);
}, delayIncrement);
}
}, delay);
delay += delayIncrement;
});
}
fadeLetters();
The problem is, this animation does not work properly. The fade-in/out actually does not happen. Letters blink on and off as if there was no transition. I believe this has to do with the background-clip: text
CSS property, but I am not sure what exactly is the issue here.
Codepen that replicates this issue: https://codepen.io/mknelsen/pen/vYVxKeb
Has anybody done something similar before, or can anybody explain why this does not work properly?
2
Answers
In the end what worked in my case was a different approach, I ended up using a trick similar to the last example in this CSS Tricks post: https://css-tricks.com/how-to-do-knockout-text/
Changing the
opacity
of something that is alreadytransparent
to begin with doesn’t sound right. I don’t know exactly why.Regardless, such an animation is possible, even without JS. What you need is to animate
color
fromrgba(r, g, b, 0)
(alpha 0, transparent) torgba(r, g, b, 1)
(alpha 1, original color) and vice versa alternately:(See the vanilla CSS version in the snippet below.)
Try it: