Published in


Pure CSS animation #2: Metaballs

For a new project, I’m trying to experiment metaballs in a pictographic way. I am designing an identity that is composed of elements like loaders, spinners, and arrows that go in a futuristic interface way.

For that, I decided to make a series of elements that are designed by dots. That dots will be connected to each other by a blobby organic link depending on their size and moves.

During my studies, I did use libraries like paper.js to do things that I could do in processing directly on a website (before P5js arrived). And there is a metaballs example on their page.

But I searched for a way to get that in pure CSS, to make it lightweight and use JS for a more important side of the website. The method to make it simple is to play with blur and contrast. We just have to blur children’s items to smooth them and create overlaying sprites. After that, change the threshold increasing contrast, and posterize the result.

#parent {  background: #fff;
-webkit-filter: brightness(1) contrast(100);
filter: brightness(1) contrast(100);
}.child { background: #000;
width: 50px;
height: 50px;
border-radius: 50%;
-webkit-filter: blur(10px);
filter: blur(10px);

After that, I wanted to make a really complex element, closer to a logotype, that has more personality.

I began to make a three-dot line, that I could re-use as a loader later. The code is quite the same and very simple.

.metaballs {  -webkit-filter: brightness(.9) contrast(100);
filter: brightness(1) contrast(100);
position: fixed;
background: #fff;
width: 100vw;
height: 100vh;
padding: 10px 0px;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%) scale(2);
transform: translate(-50%, -50%) scale(2);
& div {

background: lime;
left: 50%;
top: 50%;
width: 45px;
height: 45px;
-webkit-ftransform: translate(-50%, -50%);
transform: translate(-50%, -50%);
border-radius: 50%;
-webkit-filter: blur(12px);
filter: blur(10px);
position: absolute;
-webkit-animation-duration: 2s;
-webkit-animation-fill-mode: both;
-webkit-animation-name: pulse;
-webkit-animation-iteration-count: infinite;

&:first-child {
left: calc(50% - 60px);

&:last-child {
left: calc(50% + 60px);

@for $i from 1 through 3 {
&:nth-of-type(#{$i}) {
-webkit-animation-delay: #{$i * 0.5}s;
} }}@-webkit-keyframes pulse { 40% {
-webkit-transform: translate(-50%, -50%) scale(1.4);

Now I have a line and decide to duplicate it and rotate it to create a circle. I played again with the scss for loop and the transform-origin to make a sun-link shape. The metaballs effect is focused line by line to bring them together. And I make the white background disappear using mix-blend-mode.

.metaballs__line {  position: absolute;
-webkit-filter: brightness(.9) contrast(120);
filter: brightness(1) contrast(100);
mix-blend-mode: lighten;
background: #000;
width: 200px;
height: 150px;
left: 50%;
top: 50%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
transform-origin: 0 50%;
@for $i from 1 through 16 { &:nth-of-type(#{$i}) { -webkit-transform: translateY(-50%) rotate(#{$i*360/16}deg);
transform: translateY(-50%) rotate(#{$i*360/16}deg);
} }}




Everything connected with Tech & Code. Follow to join our 900K+ monthly readers

Recommended from Medium

Vite Tech Series: How the P2P Network gets used in our Blockchain Infrastructure

It Doesn’t Matter If You Finish Your Side Project.

The behavior of the objects

Working with Github Basic Commands in Visual Studio Code

Formatting in Python

How to setup ROS2 Fast-DDS Discovery Server

The Software Optimisation Paradox — Why Should You Care?

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Florian Fromager

Florian Fromager

Graphic designer, developer — Paris, Bruxelles —

More from Medium

CSS selectors with details example

Project 1 And A New CSS Framework

Screenshot of DaisyUI link HTML

How to add Tailwind CSS 3 to a Hugo website in 2022?

First Blog Post