Making Background Blob Animation in Just 1.5KB: Step-by-Step Guide
Published: 2023-03-09 21:09:21

Today we'll show you how to create this background animation 


{% codepen https://codepen.io/ksenia-k/pen/jXbWaJ %}

It gives the illusion of blobs morphing randomly. But in fact, we're just rotating four static SVG shapes with CSS. 


## Step 1: Create shapes

First, we draw shapes. I'm using Illustrator but any vector editor with SVG export support works.

Start by creating a square canvas. I have it 100 x 100px, but since we're making an SVG image, it scales for any screen size without losing quality. Therefore, pixel size doesn't matter.

![blank canvas](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x2l497jg1dnk2qjvfgo9.png)


You'll need two pairs of roundish shapes. The number of shapes doesn't matter much; they just need to be circular and well cropped by the viewport. 

![shapes to animate](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1awsw0j06eq7nuhpixc5.png)

Additionally, add circles to the central points. They won't stay in the final image; they're just an easy way to get the coordinates of origin points for shapes rotation.

![shapes to animate + circles](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3gmvdqpc3vz6r6eanmse.png)

We don't care about styles and colors at this point. We need to gather only the shapes from Illustrator. So let's export the whole image as .svg file.


## Step 2: Prepare SVG code

Here is the svg code exported from Illustrator:

```html
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
  <path d="M37-5C25.1-14.7,5.7-19.1-9.2-10-28.5,1.8-32.7,31.1-19.8,49c15.5,21.5,52.6,22,67.2,2.3C59.4,35,53.7,8.5,37-5Z" fill="none" stroke="#1d1d1b" stroke-miterlimit="10"/>
  <path d="M20.6,4.1C11.6,1.5-1.9,2.5-8,11.2-16.3,23.1-8.2,45.6,7.4,50S42.1,38.9,41,24.5C40.2,14.1,29.4,6.6,20.6,4.1Z" fill="none" stroke="#1d1d1b" stroke-miterlimit="10"/>
  <path d="M105.9,48.6c-12.4-8.2-29.3-4.8-39.4.8-23.4,12.8-37.7,51.9-19.1,74.1s63.9,15.3,76-5.6c7.6-13.3,1.8-31.1-2.3-43.8C117.6,63.3,114.7,54.3,105.9,48.6Z" fill="none" stroke="#1d1d1b" stroke-miterlimit="10"/>
  <path d="M102,67.1c-9.6-6.1-22-3.1-29.5,2-15.4,10.7-19.6,37.5-7.6,47.8s35.9,3.9,44.5-12.5C115.5,92.6,113.9,74.6,102,67.1Z" fill="none" stroke="#1d1d1b" stroke-miterlimit="10"/>
  <circle cx="13.2" cy="25.6" r="1.6" fill="none" stroke="#1d1d1b" stroke-miterlimit="10"/>
  <circle cx="84.7" cy="93.3" r="1.7" fill="none" stroke="#1d1d1b" stroke-miterlimit="10"/>
</svg>
```

The code may look different depending on the graphic editor you use and export settings. Anyway, we need to clean it up by removing all the styles inherited from the graphic editor. The only elements that should stay are:
- the `viewBox` attribute for `<svg>`
- 4 `<path>` elements for blobs and their `d` attribute
- 2 additional `<circle>` elements


Once we have a minimal <svg> code, we can embed it in the HTML page and set the image to full-screen:


```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="author" content="Ksenia Kondrashova">
    <style>
        svg {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100vh;
        }
    </style>
</head>
<body>

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
    <path d="M37-5C25.1-14.7,5.7-19.1-9.2-10-28.5,1.8-32.7,31.1-19.8,49c15.5,21.5,52.6,22,67.2,2.3C59.4,35,53.7,8.5,37-5Z"/>
    <path d="M20.6,4.1C11.6,1.5-1.9,2.5-8,11.2-16.3,23.1-8.2,45.6,7.4,50S42.1,38.9,41,24.5C40.2,14.1,29.4,6.6,20.6,4.1Z"/>
    <path d="M105.9,48.6c-12.4-8.2-29.3-4.8-39.4.8-23.4,12.8-37.7,51.9-19.1,74.1s63.9,15.3,76-5.6c7.6-13.3,1.8-31.1-2.3-43.8C117.6,63.3,114.7,54.3,105.9,48.6Z"/>
    <path d="M102,67.1c-9.6-6.1-22-3.1-29.5,2-15.4,10.7-19.6,37.5-7.6,47.8s35.9,3.9,44.5-12.5C115.5,92.6,113.9,74.6,102,67.1Z"/>
    <circle cx="13.2" cy="25.6" r="1.6" />
    <circle cx="84.7" cy="93.3" r="1.7" />
</svg>

</body>
</html>
```

Next thing is to add colors and class names to <path> elements. Cheers to [coolors.co](https://coolors.co/) for nice random palettes btw.

```html
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
    <path fill="#9b5de5" class="out-top" d="M37-5C25.1-14.7,5.7-19.1-9.2-10-28.5,1.8-32.7,31.1-19.8,49c15.5,21.5,52.6,22,67.2,2.3C59.4,35,53.7,8.5,37-5Z"/>
    <path fill="#f15bb5" class="in-top" d="M20.6,4.1C11.6,1.5-1.9,2.5-8,11.2-16.3,23.1-8.2,45.6,7.4,50S42.1,38.9,41,24.5C40.2,14.1,29.4,6.6,20.6,4.1Z"/>
    <path fill="#00bbf9" class="out-bottom" d="M105.9,48.6c-12.4-8.2-29.3-4.8-39.4.8-23.4,12.8-37.7,51.9-19.1,74.1s63.9,15.3,76-5.6c7.6-13.3,1.8-31.1-2.3-43.8C117.6,63.3,114.7,54.3,105.9,48.6Z"/>
    <path fill="#00f5d4" class="in-bottom" d="M102,67.1c-9.6-6.1-22-3.1-29.5,2-15.4,10.7-19.6,37.5-7.6,47.8s35.9,3.9,44.5-12.5C115.5,92.6,113.9,74.6,102,67.1Z"/>
</svg>
```

I keep the `<svg>` background transparent so it's possible to set the page background to yellow. Alternatively, we can set `background-color` for `svg` or include yellow back to the image. We're really flexible with how to handle the colors.

```css
body {
    background-color: #fee440;
}
```


![non-animated preview](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pywsiie02tfloxjrl94c.png)

## Step 3: Animate shapes

The next step is to animate the `<path>` elements using CSS. This can be done either by adding regular CSS code outside the `<svg>` tag or by inserting a `<style>` section directly into the SVG code. I insert the CSS to keep the code structure more clean, and because this allows the animation to be saved as a separate .svg file.


```html
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
    <defs>
        <style>
           
        </style>
    </defs>
    ...
</svg>
```

Each of four shapes will be rotated in the same direction in an endless loop. So we need only a single `keyframes` for rotation from 0 to 360 degrees. 

All 4 are moving quite slow but with different speed. So for each blob, we vary only animation duration and origin point. 

For origin points we use the circles' coordinates (specifically, `cx` and `cy` attributes). Once it's done, we can delete the circles.


```html
<style>
    @keyframes rotate {
        100% {
            transform: rotate(360deg);
        }
    }
    .out-top {
        animation: rotate 20s linear infinite;
        transform-origin: 13px 25px;
    }
    .in-top {
        animation: rotate 10s linear infinite;
        transform-origin: 13px 25px;
    }
    .out-bottom {
        animation: rotate 25s linear infinite;
        transform-origin: 84px 93px;
    }
    .in-bottom {
        animation: rotate 15s linear infinite;
        transform-origin: 84px 93px;
    }
</style>

...

// turns to transform-origin: 13px 25px
<circle cx="13.2" cy="25.6" r="1.6" />
// turns to transform-origin: 84px 93px
<circle cx="84.7" cy="93.3" r="1.7" />
```

_Setting the origin point in pixels can be confusing. In fact these values are not related to screen pixels, but rather to the SVG internal coordinate system, which is a 100 x 100 px size canvas we created in Illustrator. Again, SVG is scales to any screen size so having pixels for origin point is simply a matter of CSS syntax._

The animation is finished!

## Step 4: Setup responsiveness

Let's open the page in the browser and try it for different screen ratios. By default, SVG keeps the whole `viewBox` always visible by adding extra space on the sides. This way, we can clearly see the circular rotating shapes.


![responsiveness with extra space](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r68zeg86y5btt7y0dkkx.gif)

Instead, we want to crop the image so the blobs are only partly visible. It can be done easily with `preserveAspectRatio="xMidYMid slice"` attribute.


![responsiveness with cropping](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h70o2r5762yb1sxt9nir.gif)

That's it! The animation can be used as inline <svg> or being saved in the external **blob.svg** file. Even without minimifying, the file size is around 1.5kb which is pretty cool 😎

Play with code on [codepen](https://codepen.io/ksenia-k/pen/jXbWaJ) or check out the video version of this tutorial! 

{% youtube https://youtu.be/0yp9-_NKPC0 %}