A Text Reveal Animation using CSS

Written by Web Developer

Reviewed by Web Developer

Updated April 22, 2023
A Text Reveal Animation using CSS

In this article, we are going to build a simple but cool reveal animation that you can apply to your text. It will also work with multi-line of texts! All you have to do is to add a class and see the magic in play.

Here is the demo we are going to build together

The animation will run on page load, to run it again click the small button “Rerun” on the bottom right.

How does it work?

To achieve such an effect we are going to rely on the background property and more precisely gradient layers. We are not going to clutter our code with a lot of <div> or pseudo-elements. Only two background layers will do the trick.

We will have one layer that will color the text and another one will come on top of the text. Then we will adjust the size/position of each layer to create the animation.

The HTML code will look like the below:

<span class="reveal">The text to reveal</span>

It’s important to notice that we need to consider an inline element as a container for the text. If you want to apply the effect to a title, for example, don’t do

<h1 class="reveal">The text to reveal</h1>

But instead, you have to write

<h1><span class="reveal">The text to reveal</span></h1>

The use of an inline element is the trick to make the effect works on multi-line of text.

Now that we have a clear idea of how it does work, let’s write some CSS.

25%

💸 EXTRA 25% OFF ALL VERPEX MANAGED CLOUD SERVERS

with the discount code

SERVERS-SALE

Use Code Now

Introducing background-clip: text

We will start with the first background layer. Instead of using the color property, we are going to color the text using a gradient layer. To do this, we need background-clip: text

.reveal {
  color: #0000;
  background: linear-gradient(red 0 0) no-repeat;
  -webkit-background-clip: text;
          background-clip: text;
}

Nothing complex so far. We have text colored in red (the color defined by the gradient). Now let’s add some animation. In a previous article, I used the same animation technique to create a few loaders.

The logic is pretty simple. We are going to animate the width of the gradient from 0% to 100% to reveal the text.

TADA! We already have a cool reveal animation for our text with a simple code:

.reveal {
  color: #0000;
  background: 
    linear-gradient(red 0 0) no-repeat;
  background-size: 0% 100%; /* we start at 0% 100% */
  -webkit-background-clip: text;
          background-clip: text;
  animation: t 1.2s .5s both;
}

@keyframes t{
  to {background-size: 100% 100%} /* we animate to 100% 100%*/
}

Adding another background layer

Now let’s add the second background layer. This one will color the whole element and will behave the same as the previous layer. We will first animate its size from 0% to 100%

.reveal {
  color: #0000;
  background: 
    linear-gradient(red 0 0) no-repeat,
    linear-gradient(red 0 0) no-repeat;
  background-size: 0% 100%; /* we start at 0% 100% */
  -webkit-background-clip: padding-box,text;
          background-clip: padding-box,text;
  animation: t 1.2s .5s both;
}

@keyframes t{
  to {background-size: 100% 100%} /* we animate to 100% 100%*/
}

Note how in the code I defined two identical gradients but two different values for background-clip because we need one layer to color only the text while the second one is to color the whole element. I used padding-box but it can be content-box or border-box depending on whether you want to color the padding/border area or not.

We still need to add another step to our animation. We have to remove the top layer by sliding it to the right to reveal the text. For this, we can animate background-position.

This part is a bit tricky because we cannot update the position of a gradient that takes 100% width of its element. I am explaining this little quirk in detail here. To overcome this, we will update the size to make it 150% instead of 100% and then we can easily update the position of the first gradient to slide it to the right.

.reveal {
  color: #0000;
  background: 
    linear-gradient(red 0 0) no-repeat,
    linear-gradient(red 0 0) no-repeat;
  background-size: 0% 100%; /* we start at 0% 100% */
  -webkit-background-clip: padding-box,text;
          background-clip: padding-box,text;
  animation: 
    t 1.2s .5s both,
    b 1.2s 1.3s both; /* we run the second animation after the first one is done*/
}

@keyframes t{
  to {background-size: 150% 100%} /* we animate to 150% instead of 100%*/
}
@keyframes b {
  to {background-position:-200% 0,0 0} /* we update the position of only the first layer */
}

You are probably wondering what’s the logic behind the -200%. It’s the value I need to use to slide a background having a width equal to 150% to the right. I won’t deep dive into the math logic but I highly recommend reading my Stack Overflow answer where I am giving a detailed explanation.

We are done! we have nice reveal animation with minimal code. A code that we can optimize a little using a CSS variable to avoid the redundancy of the linear-gradient definition.

.reveal {
  color: #0000;
  --g: linear-gradient(red 0 0) no-repeat;
  background: var(--g),var(--g);
  background-size: 0% 100%;
  -webkit-background-clip: padding-box,text;
          background-clip: padding-box,text;
  animation: 
    t 1.2s .5s both,
    b 1.2s 1.3s both; 
}

@keyframes t{
  to {background-size: 150% 100%} 
}
@keyframes b {
  to {background-position:-200% 0,0 0}
}

Adding box-decoration-break: clone

You have probably noticed that the animation we made is slightly different that the one we saw at the beginning of the article. There is no bug but it’s how backgrounds are meant to work with inline elements. You may want to keep that behavior but you can also change it using the box-decoration-break property and more precisely the clone value

Each box fragment is rendered independently with the specified border, padding, and margin wrapping each fragment. The border-radius, border-image, and box-shadow are applied to each fragment independently. The background is also drawn independently for each fragment, which means that a background image with background-repeat: no-repeat may nevertheless repeat multiple times. ref

Here is a demo to compare both versions. Feel free to use the one that suits you the most.

90%

💸 90% OFF YOUR FIRST MONTH WITH ALL VERPEX WORDPRESS HOSTING PLANS

with the discount code

MOVEME

Grab the Discount

Conclusion

I hope you enjoyed this little animation. A few background tricks are all that we needed here. If you want to play more with gradients you can check my article about CSS patterns or my article where I am adding cool hover effects to images.

Frequently Asked Questions

Can I integrate CSS preprocessors like SASS or LESS with my CSS hosting?

Yes, most CSS hosting services support preprocessors like SASS or LESS. They allow for more advanced CSS functionalities, enabling you to write cleaner and more maintainable code.

Can free HTML editors support other languages like CSS and JavaScript?

Yes, free HTML editors often support languages like CSS and JavaScript, enabling integrated web development.

Can I contact the PHP developers?

Not directly, however, over on PHP.net you’ll find an extensive range of patch update information, forums, and articles that will answer the majority of your technical questions.

Does Verpex provide any tutorials or resources for web developers using their hosting service?

Verpex offers a comprehensive knowledge base and blog featuring tutorials, resources, and best practices to help web developers make the most of their hosting services.

Discount

Enter Discount Code MOVEME During The SIGN UP Process To Get 90% Off Your First Month

with the discount code

MOVEME

Use Code Now
Jivo Live Chat