Make a Cool Typing Bubble Loader 
Tags: css, cssvariables, react, animation
Published: 2020-03-14 17:31:03

---
title: Make a Cool Typing Bubble Loader 
published: true
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/ytgwlknr2y59o3f9g1md.jpg
description: Use CSS variables and some CSS tricks to make a bubble loader
tags: css, css variables, react, animation
---

Loaders are extremely useful for informing a **user** that *something* is happening.  The alternative to using loaders is just hoping that the user understands that they need to wait.  Often, this just leads to the user becoming frustrated or, even worse, leaving the application. Obviously, we don't want this, instead, it's better to incorporate a visual loader in your application to improve the user experience. 

 
Now, let's get to coding a bubble loader. We'll take inspiration from the Facebook Messenger typing loader.  This comes up every time your friend is typing a message.  It's a great way to let users know that they're getting a reply.  It's all visual and everyone understands what it is. 

#### What we'll be using
- React
- CSS Variables
- KeyFrames

Here's what our loader will look like at the end.

{% codesandbox loader-97p18 %}

### Diving into the code

Let's start with the jsx markup.


```jsx
function Messenger() {
  return (
    <div className="Messenger">
      <Loader />
    </div>
  );
}

function Loader() {
  let dots = Array(3).fill(3);

  return (
    <div className="Wrapper">
      <div className="Loader">
        {dots.map((_, i) => (
          <div style={{ "--i": i }} className="Dot" key={i} />
        ))}
      </div>
      <div className="Background" />
    </div>
  );
}
```

The **Messenger** component will just act as the wrapper.  We'll use it to set the background color for the page and to align the Loader in the center.

In the Loader, we'll put three divs, each with their own CSS variable **--i**.  We'll use this variable for setting the animation-delay.

We also have a **Background** div but I'll explain more about that later.

The main take away is that we can set the CSS variable to the index of the item. That's going to make our animation super easy to make! 🥳

#### Now to the CSS

```css
.Messenger {
  height: 100%;
  width: 100%;
  background: #F9B5AC;
  display: flex;
  justify-content: center;
  align-items: center;
}

.Loader {
  height:80px;
  width: 200px;
  display: flex;
  justify-content: space-evenly;
  align-items: center;
  border-top-left-radius: 3px;
  border-top-right-radius: 40px;
  border-bottom-right-radius: 40px;
  border-bottom-left-radius: 40px;
  z-index: 3;
  background: #9DBF9E;
  cursor: pointer;
}
```

These are the basic styles and are self-explanatory.

Animation time! 🥳🥳

```css
@keyframes move {
    
    0% {
      transform: translateY(0%);
    }
    25% {
      transform: translateY(-40%)

    }
    50% {
      transform: translateY(-80%)
    }
    75% {
      transform: translateY(10%);
    }
    100% {
      transform: translateY(0%);
    }
  }

.Dot {
  transform: none;
  animation: whoop 1s linear infinite forwards;
  animation-delay: calc(var(--i) * .2s);
  width: 20px;
  height: 20px;
  background: #EE7674;
  border-radius: 50%;
  z-index: 1;
}
```
As you can see, the keyframes define our animation. Next, we just apply an animation-delay by multiply the variable **--i** times .2s. This gives us the awesome effect of each dot moving after the other.

Let's take a look at the CSS variable again.

```javascript
dots.map((_, i) => <div style={{ "--i": i }} className="Dot" key={i} />)
```
As you can see, we're applying the index of the array to the CSS variable. 

Next, in the CSS we just multiply the variable times .2s and the result is each dot moving one after the other!
```css
.Dot {
/*...*/
  animation-delay: calc(var(--i) * .2s);
/*...*/
}
```

# But wait, there's more!

Remember that Background div? Well, we can use it to be the box shadow of the loader. Then on:hover we add a transform of **translate** in the loader. That way we can hover over the loader and the Background will remain in place. This gives us a cool hover effect!

```css
.Loader {
/*...*/
transition: transform .3s ease-in-out; 
&:hover {
transform: translate(10px, 10px);
 }
/*...*/
}
.Background {
position: absolute;
height:80px;
width: 200px;
top: 0;
border-top-left-radius: 3px;
border-top-right-radius: 40px;
border-bottom-right-radius: 40px;
border-bottom-left-radius: 40px;
box-shadow: 10px 10px .07rem rgba(rgb(69, 107, 129),  .7);
z-index: 1; 
}
```

Try it out by hovering your mouse over the loader 😇

{% codesandbox loader-97p18 %}

So that's it!  I hope you learned something! 

### Extra resources:
I learned the CSS variable trick from the fantastic youtube channel [keyframers](https://www.youtube.com/channel/UCtmYk7H-NNYLEe_LgBRYomA). They're focused on making performant CSS animations that are easy to understand. Check them out!