Animate an Octocat Sprite Swimming with CSS
Tags: css, codepen, sprites, animation
Published: 2020-01-30 18:40:40


Animating DOM and SVG elements with CSS using the `@keyframes` rule and `animation` property is usually pretty straightforward. Elements generally animate smoothly from a starting value to an ending value and all the values in between. While this works great for DOM and SVG elements, sprite images animate by displaying different images quickly in succession rather than slowly transitioning from one value to another. This article will demonstrate one technique to animate sprites with CSS by animating an Octocat sprite swimming in the ocean. Checkout the Codepen below to see the completed project.

{% codepen https://codepen.io/codypearce/pen/VwYOGzq %}

## Using Sprites with CSS

Sprite images are a collection of smaller images within a single image. To show any particular image within the collection of images, you need to specify the position and size of that particular image. For example, to show Octocat going to the right (the third image) in the following sprite image we need to specify the width of the image as `200px`, the height as `300px`, and the position on the image as `x: 400` and `y: 0`.

![Octocat Sprite Positions](https://codinhood.com/static/37dace02523b69161f2e8ce9569d7dac/299c1/values.png)

In CSS, we can achieve this by setting the image as a background image on an element. If we set the height and width to size of the whole sprite image then we'll see all the frames.

```css
.Octocat {
  height: 300px;
  width: 800px;
  background: url(./octocat.png) left center;
}
```

![Octocat Sprite full](https://codinhood.com/static/9a146dac647e7129fa173acc0b0d437f/299c1/octocat.png)

But we only want to show one frame at a time, so change the width to size of one frame.

```css
.Octocat {
  height: 300px;
  width: 200px;
  background: url(./octocat.png) left center;
}
```

![Octocat Sprite Single](https://codinhood.com/static/4e96e23ea642cbcf74c1437e5c552ca8/40fa0/octocat-single.png)

This shows the first frame because the position of the sprite image is at `x: 0` and `y: 0`. If we want to show the third frame we can change the sprite image position using the CSS property `background-position`. The position of the third frame is `x: 400px` on the sprite image, but a positive value for `background-position` pushes an image to _right_ which means the position on the image will be `-400px`. Flipping the value around to `-400px` will push the image to the _left_ and reach position `400px` on the sprite image.

```css
.Octocat {
  height: 300px;
  width: 200px;
  background: url(./octocat.png) left center;
  background-position: -400px 0px;
}
```

![Octocat Sprite Right](https://codinhood.com/static/b58138403bf42a5d996155a5d036dc75/a8246/octocat-right.png)

## Animating One Step Sprites with CSS

Animating sprites in CSS, at its core, is simply changing the `background-position` to the appropriate frame within the sprite image at the appropriate time. The problem is that normal CSS animation animates the transition from one value to another rather than immediately switching to a new value. For example, say we want to animate Octocat from frame one to frame two with a normal `ease` or `linear` animation.

```css
.Octocat {
  height: 300px;
  width: 200px;
  background: url(./octocat.png) left center;
  animation: upAndDown 5s ease infinite;
}
@keyframes upAndDown {
  0% {
    background-position: 0px;
  }
  50% {
    background-position: -200px;
  }
  100% {
    background-position: 0px;
  }
}
```

![Octocat Ease](https://codinhood.com/acad509995d43c5899844e9d9b3a74a0/octocat-ease2.gif)

To animate sprites we need to use the `steps()` [animation-timing-function](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-timing-function) instead. Essentially we need to jump from one frame to another and that's exactly what the `steps` function does in CSS. The value passed into `steps()` represents how many steps the animation should show on the way to the provided value. For example, if we animate from `0` to `100` and pass 2 to `steps` , then the animation will show the element at `50` and `100`. Sprite animations with more frames require more steps, in our case we only have two frames, for showing up and down movement, so we only need one step to transition between the two frames.

```css
.Octocat {
  height: 300px;
  width: 200px;
  background: url(./octocat.png) left center;
  animation: upAndDown 2s steps(1) infinite;
}
@keyframes upAndDown {
  0% {
    background-position: 0px;
  }
  50% {
    background-position: -200px;
  }
  100% {
    background-position: 0px;
  }
}
```

![Octocat Up and Down](https://codinhood.com/270bfe8dd0f1e07863902fc971c77ba6/octocat-up-down.gif)

## Moving Sprites Around the Page with CSS

The `steps()` function is great for animating sprites but if we want to move the image around the screen smoothly then we need to use another timing function like `ease` or `linear`. We will need to define another `@keyframes` rule and add a second animation to the element to use different timing function.

First, we want to animate the sprite up and down using a transform. The sprite will start below the middle position,

```css
transform: translate(0px, 100px);
```

and then animate up pass the midpoint,

```css
transform: translate(0px, -100px);
```

and finally animate back down to the starting position:

```css
transform: translate(0px, 100px);
```

To give the illusion of sinking slowly we animate quickly up, from `0%` to `40%`, and animate slower downwards, from `40%` to `100%`.

```css
@keyframes swim {
  0% {
    transform: translate(0, 100px);
  }
  40% {
    transform: translate(0, -100px);
  }
  100% {
    transform: translate(0, 100px);
  }
}
```

We also need to update the sprite transtion animation. At the start, Octocat is at the very bottom of the animation which means he needs to be the first frame. But the `swim` animation above will immediately start animating him straight up to `-100px`, which means we need to immediately switch the frame to the up frame, frame 2. To do this we set the `background-position` to `-200px` at `1%`.

When Octocat is at the very top of the animation, which is at `40%`, we need to switch his frame back to the original frame. Again we want to do this _after_ he's reached the end of the movement so we reset his frame at `41%`, instead of `40%`. Next, we need to make sure he stays at his first frame all the way back down to the original position by setting `100%` to the same position.

```css
@keyframes upAndDown {
  0% {
    background-position: 0;
  }
  1% {
    background-position: -200px;
  }
  41% {
    background-position: 0;
  }
  100% {
    background-position: 0;
  }
}
```

Finally, we can update the element with both animations by comma separating them.

```css
#octocat {
  height: 300px;
  width: 200px;
  background: url("./octocat.png") left center;
  animation: upAndDown 5s steps(1) infinite, swim 5s ease infinite;
}
```

![Octocat swimming up and down](https://codinhood.com/079e6900af19b10db328bcf224df407a/octocat-short.gif)

Extending this pattern further we can create more complicated animations like the one in the Codepen at the top of the article or even tie these sprites to keyboard input.

## Conclusion

Animating sprite images in CSS, while not exceedingly difficult, requires a few tricks to get working correctly. If you'd like to play around with sprites in CSS you can download the Octocat sprite my friend made below or search online for thousands of free sprite images.

![Octocat Sprite Image](https://codinhood.com/static/9a146dac647e7129fa173acc0b0d437f/299c1/octocat.png)