Creating a CSS Sliding Background Effect

Avatar of Geoff Graham
Geoff Graham on (Updated on )

The “trick” of sliding backgrounds in CSS is not new. In fact, the first time I came across it might have been a couple of years ago on the Valio Con site (the current design doesn’t have it anymore). I happened to notice it on a couple of new sites I visited today, however, and thought it would be worth sharing.

This is the effect we’re after:

See the Pen gamYOy by CSS-Tricks (@css-tricks) on CodePen.

Notice that this is different from a CSS slideshow or carousel, where the the content is separated into slides that can be stopped at. There are great examples of those all over CodePen.

This technique takes the background of one element and slides it across the x-axis infinitely in a loop to create the effect of a never-ending and always moving background.

Setting up the HTML

This is sort of a blueprint of how our HTML needs to be structured:

There is one element that fits the exact width of the viewport, and another that runs through and overflows it. That means we only need to create two elements in the HTML markup: one for the background, and another to act as a containing wrapper for that background.

<div class="wrapper">
  <div class="sliding-background"></div>
</div>

Positioning the Elements

Let’s go ahead and add some CSS that will correctly position our two elements.

.wrapper {
  overflow: hidden;
}

.sliding-background {
  height: 500px;
  width: 5076px;
}

Our .wrapper is 100% of browser width by default (that’s how block-level elements are), and we’ve added an overflow property that will hide anything that is visually contained outside of it. Think of it like a crop on a photograph. There may be extra stuff outside the wrapper, but the wrapper is preventing us from seeing it.

That’s where our .sliding-background comes into play. It is set to some ridiculous width that would overflow most viewports. And that’s the trick: it should be something that would overflow the wrapper. In this case, I somewhat arbitrarily chose a 5076px width.

Creating the Background Image

We need an image if we’re going to scroll something across the screen, right? That’s our next order of business.

Remember how I mentioned that I had somewhat arbitrarily chosen 5076px as the width for the sliding background? Well, it is arbitrary, but intentional in the sense that it is nicely divisible by 3, which fits into the timing for a minute-long loop, which will come up a little later. That means the canvas for our background image is 5076 / 3 or 1692px. In the end, our background will repeat a total of three times in one minute in an infinite loop. Math for the win!

The 500px height is truly arbitrary. That can be whatever you want and will act as the height of the canvas for the background image.

Here’s the Photoshop template used in this example to get you started:

Download ZIP

Save (and optimize!) the image. This is what we’ll use as the background image in the CSS:

.sliding-background {
  background: url("..path/to/image") repeat-x;
  height: 500px;
  width: 5076px;
}

Great! That gives us the ginormous image that overflows the wrapper and can now be used to scroll across the screen ad infinitum.

The Sliding Effect

All right, let’s make this bad boy move. We want it to go from left to right in a loop that repeats over and over to create a seamless effect that the image goes on forever.

First, let’s define the CSS animation:

@keyframes .slide {
  0%{
    transform: translate3d(0, 0, 0);
  }
  100%{
    transform: translate3d(-1692px, 0, 0);
  }
}

We’re using the transform property to position the left image at the left edge of the wrapper when the animation begins, like so:

By the time the animation has completed, it will have transformed the position negatively (from left to right) by an amount that matches the exact width of our image. And, since the .sliding-background is three times the width of the actual image, the image repeats three times between 0% and 100% before looping again.

Note: the reason we’re using an additional <div> at all, rather than animating background-position on the main <div>, is so that we can use an animated transform to do the movement, which is much more performant.

OK, let’s round things out by calling our slide animation on the .sliding-background class:

.sliding-background {
  background: url("..path/to/image") repeat-x;
  height: 560px;
  width: 5076px;
  animation: slide 60s linear infinite;
}

The animation property instructs the .sliding-background to use the slide animation and to run it for one minute at a time in a linear, infinite loop.

Putting it All Together

<div class="wrapper">
  <div class="sliding-background"></div>
</div>
.wrapper {
  overflow: hidden;
}

.sliding-background {
  background: url("..path/to/image") repeat-x;
  height: 560px;
  width: 5076px;
  animation: slide 60s linear infinite;
}

@keyframes slide{
  0%{
    transform: translate3d(0, 0, 0);
  }
  100%{
    transform: translate3d(-1692px, 0, 0);
  }
}

Here’s the final result:

See the Pen gamYOy by CSS-Tricks (@css-tricks) on CodePen.