CSS & React: How to bounce your logo
Tags: css, animation, javascript, react
Published: 2019-11-27 17:58:32

---
title: CSS & React: How to bounce your logo
published: true
description: Build a smooth bouncing logo animation with pure CSS and use it in React.
tags: css, animation, javascript, react
cover_image: https://thepracticaldev.s3.amazonaws.com/i/5r8tzoqo8aodtv58p04y.gif
---

**TLDR:**
Build a smooth bouncing logo animation with pure CSS and use it in React. My impatient friends can scroll down the dark depths (=end) of this article and grab the valuable CSS snippet.

![Bouncing logo of Loceye](https://thepracticaldev.s3.amazonaws.com/i/5r8tzoqo8aodtv58p04y.gif)

# 👵 The Story
While I was craving for inspiration on Dribbble and cursing the trash Internet connection, I saw IT! It was small but beautiful! Μoving tirelessly back and forth and catching my breath every time it hits the ground.

From that time on, I was obsessed with this small devil!

![Dribbble bouncing logo as spinner](https://thepracticaldev.s3.amazonaws.com/i/ax9e0b36p01aresobh8c.gif)

As a front-end engineer that respects himself, I opened the dev tools to check the source code of the animation. Who would have thought that it was just a gif?

![Kanye West meme](https://media.giphy.com/media/xUPGcv60FVRlOz4Mnu/giphy.gif)
<figcaption>I was really disappointed!</figcaption>

From that time on, I had my heart set on building the god damn bounce!

But, enough of my emotional breakdown. Let’s get some 💩 done!

# 🧠 How
Before getting our hands dirty, I want to define **our goal** and how we’re gonna achieve it!

First of all, the Dribbble logo is a basketball, so it makes perfect sense to be bouncing. However, it doesn’t have to be a ball to make the animation look natural. Having a circular shape is enough and to convince you, our object will be an **eye**.

![Eyerolling meme](https://media.giphy.com/media/yZ2FSn86bf2co/source.gif)

My company, [Loceye]("https://www.loceye.io") uses eye-tracking technology to understand users' behavior, and possible that eye thing makes sense now.

The second point is about the shadow! Maybe it’s not obvious to everyone but a bouncing eye transforms its shadow as it gets near the ground. The shadow gets bigger and bigger as the eye comes closer to the ground.

About the code implementation, we’re gonna need an **SVG logo** (PNG could work too with small adjustments) and **a basic understanding of CSS animations**. When we have a functional bouncing eye, I’ll show you how you can use it in any React project with no hassle as a loading component.

# 👨‍💻 Coding Section

![Dr.House coding meme](https://media.giphy.com/media/5ntdy5Ban1dIY/giphy.gif)
<figcaption>Let’s start the coding section!</figcaption>

The idea behind the implementation is not rocket science! It works as simple as that. Define a container that will contain the logo and its shadow. The logo and the shadow will be positioned relative to their parent element.

For educational reasons, I’m gonna break down the whole animation concept into 4 parts.

# 💀 Part #1 — Static skeleton
We’re gonna define the static layout of our animation. For simplicity, the logo and its shadow will be two `<div>` elements with circular and rectangular shape respectively.


```javascript
<div class="container">									
  <div class="logo"></div>
  <div class="shadow"/></div>
</div>
```

Now, let’s declare some useful CSS variables and escape from the headache later. If you’re new into CSS variables and curious to learn more, you can visit [this link]("https://blog.logrocket.com/how-to-create-better-themes-with-css-variables-5a3744105c74/") and thank me later in the comment section.

```css
<div class="container">									
  <div class="logo"></div>
  <div class="shadow"/></div>
</div>
```

It’s time to position our main elements. The trick is the CSS attribute `position`. By defining `position: relative` at the container and `position: absolute` to its children, we achieve to position the ball and the shadow relative to their parent.

The tricky part here is to keep in mind that the `top` and `left` attributes calculate the absolute position of the top left element’s point.

![CSS centering](https://thepracticaldev.s3.amazonaws.com/i/ziwdmz89bopymw5uquun.png)

For example, the elements can be horizontally centered inside the container if we set `left: 50%` and subtract the half of its width.

You can check my [previous article](https://dev.to/d__raptis/css-absolute-center-element-k5a) to learn why.

The CSS classes below align the ball and the shadow inside their container using some plain calculations.

```css
.container {
  position: relative;
}

.logo {
  position: absolute;
  top: var(--offset);
  left: calc(50% - var(--logo-size) / 2);								
}

.shadow {
  position: absolute;
  top: calc(
    var(--offset) + 
    var(--drop-height) + 
    var(--logo-size) - 
    1.5  var(--shadow-height)
  );
  left: calc(50% - var(--logo-size) / 2);
}
```

By now, our animation should look more static than ever!

{% codepen https://codepen.io/dimitrisraptis96/pen/EzzjYq %}

# 🏃Part #2 — Movin’ it

It’s time to move the damn ball!!!

Half the magic lies on the `@keyframes` CSS at-rule, which controls the intermediate steps in a CSS animation sequence by defining styles for keyframes (or waypoints) along the animation sequence.

Our `@keyframes bounce` at-rule is gonna handle the `translateY()` and `scale()` CSS functions.

The function `translateY()` will reposition the ball vertically on the 2D plane from `0` to `var(--drop-height)` pixels. Simpler, it will move our ball **downwards** towards the ground by the specified pixels.

```css
@keyframes bounce {
  from { 
    transform: translateY(0) scale(1);
  }
  to   { 
    transform: translateY(var(--drop-height)) scale(1, 0.7);
  }
}
```

But how? Here comes the rest of the magic! The `animation` CSS property applies an animation between styles. We set the `animation-direction` property alternating back and forth `animation-iteration-count` to infinite.

> Smooth movement is anything and everything!

However, the most important property is the `animation-timing-function`, that specifies how an animation progresses through the duration of each cycle. I picked the `cubic-bezier()` timing function because it’s highly customizable and can give the desired natural feeling.

```css
.logo {
  ...
  animation-name: bounce; 
  animation-duration: 0.5s;
  animation-direction: alternate;
  animation-timing-function: cubic-bezier(0.95, 0.05, 0.795, 0.035);
  animation-iteration-count: infinite;
}
```

Of course, these floating point numbers are not random but precisely defined after hours of calculations. Just kidding!

Hopefully, Andrey Sitnik and Ivan Solovev build an amazing curated list of easing functions, the **[easing.net](https://easings.net/)**. My work was to pick easeInExpo and copy-paste the `cubic-bezier()` easing.

![Preview cubic-bezier(0.95, 0.05, 0.795, 0.035)](https://thepracticaldev.s3.amazonaws.com/i/sp9dvy5qjfvutsss7ony.gif))
<figcaption>Preview cubic-bezier(0.95, 0.05, 0.795, 0.035) at cubic-bezier.com</figcaption>

Another great tool is **[cubic-bezier.com](https://cubic-bezier.com/#.17,.67,.83,.67)** by Lea Verou. Not only helps you visualize your cubic-bezier curve, but you can also compare it with some common easing functions.

{% codepen https://codepen.io/dimitrisraptis96/pen/VOOLBz %}

# 🕶 Part #3— Shadow owes its birth to light.

It’s time to take care of our shadow. Considering our extended analysis on Step #2, the shadow movement should be easy as a pie (unless you’ve never baked a pie).

```css
@keyframes grow {
  from {
    transform: scale(0.2, 0.5);								
  }

  to {
    transform: scale(1, 0.1);   
  }
}
```

As you can see, our only adjustment is on its `scale()` function. Our goal here is to “stretch” the shadow as the ball is coming closer.

So far, we have a fully-functional bouncing animation with two dummy objects. Let’s put the finishing touches at our next step.

{% codepen https://codepen.io/dimitrisraptis96/pen/GaaJBx %}

# 🏀 Part #4 —Dat eye is bouncing

Everything is great by now, but something is missing. The lovely eye and its realistic shadow of course. Obviously, a ball cannot have a rectangular shadow.

I used a `<svg>` element with our `.logo` class to define my logo.

```css
<div class="container">											
  <svg class="logo" ...>....</svg>
  <div class="shadow"/></div>
</div>
```

However, it could work if you kept the `<div> `element and added a PNG image inside the `.logo` class, taking advantage of `background-image` property. Moreover, we should use `background-size` and `border-radius` to center it.

```css
.logo {	
  ...	
  background-image: './path/to/logo.png';							
  background-size: cover;
  border-radius:50% 50% 50% 50%;
}
```

The last touch is adding the `radial-gradient()` function and create a fading natural shadow for our object.

```css
.shadow {	
  	...
	background: radial-gradient(50% 50%, rgba(150,150,150,1), rgba(150,150,150,0.05));
}

```

## 🎉🎉🎉 Kudos! The logo is bouncing! 🎉🎉🎉

{% codepen https://codepen.io/dimitrisraptis96/pen/GaaJYd %}

If you were here to **grab your CSS snippet**, the above Pen will make you joyful. Thank you for being patient with my bad sense of humor and hope to see you around here again!

---

The rest of you, who want the React component should bear with my bad humor a little bit more.

![Dr.Evil meme](https://media.giphy.com/media/xl5QdxfNonh3q/giphy.gif)

# ⚛ Only React geeks here

About the React component, I took advantage of the powerful [styled-components](https://www.styled-components.com/) library, that allows you to write actual CSS code to style your components. Of course, you can use the traditional way and import your CSS file into your component.

A tricky point is that the `<Logo>` component is an `<svg>` element rendered as a React component. You can easily transform an svg element to React component using **[svgr](https://www.smooth-code.com/open-source/svgr/playground/)** web editor(CLI tool is available too). Don’t forget to include `viewPort` in your `<Logo>` component!

{% gist https://gist.github.com/dimitrisraptis96/e49e105d39f8052a49fdb68ade95a443 %}

# 🏃‍♀️🏃 Impatient CSS lovers here

{% gist https://gist.github.com/dimitrisraptis96/73e4b4e1d19fca0a16e75624919de928 %}

# Conclusion

It’s not that difficult to create a cool animation using pure CSS stuff. You should only **take a deep breath** and define what you really want! Transferring your animation to the real world can really help you understand the basic requirements!

Check the functional React Sandbox and I’m gonna wait for your dirty bouncing animation at the comment section below 👇👇👇

{% codesandbox fhf5o %}