Scrolling Text with Colour Change Effect

  • 3
  • Article
  • Updated 3 years ago
  • (Edited)

Today we are going to show you a way to add a nice colour changing scrolling text effect to your HTML using some simple keyframe animation and overflow:hidden trickery. Check out the live demo here.

How it works

The secret to creating this effect is that the colour of the text is not actually being changed, but what you are really seeing is two different lines of text, one on top of the other, being moved at the same time. The effect is created as the white text is only visible in the area taken up by the image. We also repeat the text on the same line so there are no gaps in the scrolling. If you had a really short headline, you might need to repeat the same line 3 times.

You can think of this page being built with three layers, the dark text, then the image, and the white text on the top.

The code

We have included the full code here so please feel free to copy it and try it yourself. We will go over some of the key points below.

<meta charset="utf-8">
<title>Scrolling Text with Colour Change</title>

/*we import the font we want to use from Google fonts here*/

@import url(;

/*here are the keyframe animations. We use these to control the scrolling text. We have added the -webkit-' prefix for older version of Google Chrome, but you should check to see if your Chrome version needs an upgrade so you can take advantage of some awesome new features! :)*/

@-webkit-keyframes scroll-left {
0% {
-webkit-transform: translate3d(0, -50%, 0);
100% {
-webkit-transform: translate3d(-50.6%, -50%, 0);
@keyframes scroll-left {
0% {
-webkit-transform: translate3d(0, -50%, 0);
-moz-transform: translate3d(0, -50%, 0);
-ms-transform: translate3d(0, -50%, 0);
-o-transform: translate3d(0, -50%, 0);
transform: translate3d(0, -50,% 0)
100% {
-webkit-transform: translate3d(-50.6%, -50%, 0);
-moz-transform: translate3d(-50.6%, -50%, 0);
-ms-transform: translate3d(-50.6%, -50%, 0);
-o-transform: translate3d(-50.6%, -50%, 0);
transform: translate3d(-50.6%, -50%, 0)

#wrapper {
position: relative;
overflow: hidden;

.scroller {
position: absolute;
font-family: 'Open Sans', sans-serif;
-webkit-animation: scroll-left 20s linear infinite;
-moz-animation: scroll-left 20s linear infinite;
animation: scroll-left 20s linear infinite;
white-space: nowrap;

.front {
z-index: 100;

.scrollingText {

.scroll-container {
.scroll-image {
position: relative;
z-index: 10;
.scroll-image img {
.image-container {
.dark {
.light {

p {
display: inline-block;



<div id="wrapper">

<span class="scroller">

<span class="scrollingText dark"> This Is Our Headline&nbsp </span>

<span class="scrollingText dark"> This Is Our Headline&nbsp </span>


<div class="scroll-container">
<div class="scroll-image">
<div class="image-container">

<img src=""/>

<span class="scroller front">

<span class="scrollingText light"> This Is Our Headline&nbsp </span>

<span class="scrollingText light"> This Is Our Headline&nbsp </span>





Setting up the HTML and CSS

The main thing to note in the HTML is that both instances of the text are within a span with a class of scroller, and the second instance has an additional class of front which we will use to bring it to the very front of the document using our CSS styles.

We are using spans rather than p, or h1 tags as spans are inline elements which mean that they will sit next to each other in a row. This lets us position them exactly as we want them, with no margins or extra spaces before we start to animate them. However, if you want to include spaces within the span you may need to use the code   to add a non-breaking space to the HTML, like we have at the end of the sentences.

The image and second instance of the text is contained within a div with the class of image-container. This div is given a style of overflow:hidden which is key to the effect - this means that the white text is only visible within the bounds of this div, so the darker text is visible on either side.

The Animation
We have two instances of text that we want to animate, but luckily for us we want to move them in exactly the same way! We can do this with CSS keyframes. We have called our keyframes scroll-left and have used translate3d(x,y,z) to move the scroller div. Using translate3d creates a smoother transition effect, which is important when using text that you want to have as crisp and visible as possible.

As you can see, the animation moves the span 50.6% to the left of it’s original position, then starts all over again. This is why we repeat the text on the same line, to give the effect that it is continuous and hide the fact that it is jumping back to the start each time.

Tips and Tricks
We set the distance to move at 50.6% as this resulted in a really smooth jump when it reset, but you may want to change this based on the length of your headline text.

We also added a style of backface-visibility:hidden to the image-container div. This is also to help with the smoothness of the text animation and can help to maintain a crisp edge to the characters.

Don’t forget to choose an image which will have a good contrast with your text colour so it is easily readable.

If you want to take this to the next level, try adding in the Rise Google Sheet web component so that you can dynamically update the text and the image through a spreadsheet. You can find more information about this component here.

Hope you enjoy testing out different colour combinations, and please let us know if you have any questions!
Photo of Peter Cameron

Peter Cameron, Employee

  • 1,418 Points 1k badge 2x thumb

Posted 3 years ago

  • 3
Photo of HSuarez


  • 11,896 Points 10k badge 2x thumb
Very cool!
Photo of mlm

mlm, Official Rep

  • 4,624 Points 4k badge 2x thumb
Sweet, looks smooth too!