Today we'll show you how to create this background animation
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.
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.
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.
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:
<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 theird
attribute - 2 additional
<circle>
elements
Once we have a minimal code, we can embed it in the HTML page and set the image to full-screen:
<!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 elements. Cheers to coolors.co for nice random palettes btw.
<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.
body {
background-color: #fee440;
}
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.
<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.
<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.
Instead, we want to crop the image so the blobs are only partly visible. It can be done easily with preserveAspectRatio="xMidYMid slice"
attribute.
That's it! The animation can be used as inline 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 or check out the video version of this tutorial!
Top comments (6)
Perfect guide!
Just one little addition. You don't have to use
xmlns="http://www.w3.org/2000/svg"
anymore.Thank you for noticing! Just removed the thing from codepen :)
This is super cool, thank you for writing it!
hello this doesn't work in safari browser ... any help ?
Just fixed it (Safari wants 0% keyframe to be specified, I had only the 100% keyframe before)
Hello, Ksenia! Great guide!
Could you please write a guide on how you make an animated single svg file like this one from your website?