CSS Animations with Styled Components
Tags: react, styledcomponents
Published: 2021-03-16 00:41:37

---
title: CSS Animations with Styled Components
published: true
date: 2021-02-19 00:00:00 UTC
tags: react, styledcomponents
canonical_url: https://www.mariokandut.com/how-to-add-css-animations-with-styled-components/
---

Styled components are visual primitives to style your React App and have plenty of great features, like the ability to write CSS right in the component, complexity reduction, faster loading, clear scope and other performance improvements.

This article is about CSS animations with the `@keyframes` property. CSS animations with @keyframes aren't scoped to a single component, but you still don't want them to be global to avoid name collisions.

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#keyframes-in-styled-components)Keyframes in Styled Components

Styled components export a helper for dealing with CSS keyframes, which generates a uniques instance that can be used throughout the entire application.

Let's have a look at an example from the [styled components docs](https://styled-components.com/docs/basics).

We have to create the keyframes.

```
const rotate = keyframes`
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
`;
```

Create a component, that will rotate everything we pass in over two seconds

```
const Rotate = styled.div`
  display: inline-block;
  animation: ${rotate} 2s linear infinite;
  padding: 2rem 1rem;
  font-size: 1.2rem;
`;
```

Then we return the styled component.

```
render(<Rotate>I am rotating </Rotate>);
```

> "Keyframes are not supported by react-native. Use the ReactNative.Animated API."

[💰: Start your cloud journey with $100 in free credits with DigitalOcean!](https://m.do.co/c/29f238135b61)

Keyframes are **lazily injected** when they're used. Hence, keyframes can take advantage of **code-splitting** , though you have to use the css helper for shared style fragments, see example from official docs.

```
const rotate = keyframes``;

// ❌ This will throw an error!
const styles = `
  animation: ${rotate} 2s linear infinite;
`;

// ✅ This will work as intended
const styles = css`
  animation: ${rotate} 2s linear infinite;
`;
```

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#code-beating-heart-example)Code: Beating Heart Example

Let's have a look at a concrete example for animation with keyframes. We want to make a beating heart animation.

First we need a CSS heart shape to animate, we could use an SVG or make a heart shape with CSS. Since we already know how to make a heart with pure CSS, see [Basic CSS shapes](https://www.mariokandut.com/how-to-make-shapes-with-css/), we can adapt the CSS.

```
.heart {
  position: relative;
  width: 100px;
  height: 90px;
}
.heart:before,
.heart:after {
  position: absolute;
  content: '';
  left: 50px;
  top: 0;
  width: 50px;
  height: 80px;
  background: red;
  border-radius: 50px 50px 0 0;
  transform: rotate(-45deg);
  transform-origin: 0 100%;
}
.heart:after {
  left: 0;
  transform: rotate(45deg);
  transform-origin: 100% 100%;
}
```

We adapt the CSS for styled-components:

```
const Heart = styled.div`
  position: relative;
  width: 100px;
  height: 90px;
  &:before,
  &:after {
    position: absolute;
    content: '';
    left: 50px;
    top: 0;
    width: 50px;
    height: 80px;
    background: red;
    border-radius: 50px 50px 0 0;
    transform: rotate(-45deg);
    transform-origin: 0 100%;
  }
  &:after {
    left: 0;
    transform: rotate(45deg);
    transform-origin: 100% 100%;
  }
`;
```

We create the keyframes for the animation:

```
const heartBeat = keyframes`
  0%
  {
    transform: scale( .75 );
  }
  20%
  {
    transform: scale( 1.1 );
  }
  40%
  {
    transform: scale( .75 );
  }
  60%
  {
    transform: scale( 1.1 );
  }
  80%
  {
    transform: scale( .75 );
  }
  100%
  {
    transform: scale( .75 );
  }
`;
```

We add the animation property to our styled `Heart` and voila. We have a beating heart.

```
const AnimatedHeart = styled(Heart)`
  animation: ${heartBeat} 1s infinite;
`;
```

<style>
.animated-heart {
  margin-top: 2rem;
  position: relative;
  width: 100px;
  height: 100px;
  animation: heartBeat 1s infinite;
}
.animated-heart:before,
.animated-heart:after {
  position: absolute;
  content: '';
  left: 50px;
  top: 0;
  width: 50px;
  height: 80px;
  background: red;
  border-radius: 50px 50px 0 0;
  transform: rotate(-45deg);
  transform-origin: 0 100%;
}
.animated-heart:after {
  left: 0;
  transform: rotate(45deg);
  transform-origin: 100% 100%;
}

@keyframes heartBeat {
  0% { transform: scale( .75 ); }
  20% { transform: scale( 1.1 ); }
  40% { transform: scale( .75 ); }
  60% { transform: scale( 1.1 ); }
  80% { transform: scale( .75 ); }
 100% { transform: scale( .75 ); }
}
</style>

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#tldr)TL;DR

CSS animations with keyframes can be easily done with styled-components and the helper utility `keyframes`. The code is cleaner, not scattered around the application and more performant than other CSS solutions.

Thanks for reading and if you have any **questions** , use the **comment** function or **send me a message** **[@mariokandut](https://www.twitter.com/mariokandut)**. If you want to know more about **[React](https://www.mariokandut.com/tags/react)**, have a look at these [React Tutorials](https://www.mariokandut.com/tags/react).

References (and Big thanks):

[Styled Components](https://styled-components.com/docs/basics), [Matt Readout](https://medium.com/@matt.readout/adding-css-animations-with-styled-components-6c191c23b6ba)