After the flower shapes, let’s move to one of the coolest shapes: the Blob! Those distorted wiggly circles that were almost impossible to achieve using CSS. But now, they are possible using the new shape()
function.

Article Series
Before we start, take a look at my blob shape generator. Unlike the flower shapes, blobs have the random factor so having a generator to get the code is a lifesaver. This said, stay with me to understand the logic behind creating them, maybe you will want to make your own generator of blobs.
For this shape, we are going to rely on the curve
command, so let’s start by understanding how it works.
At the time of writing, only Chrome, Edge, and Safari have the full support of the features we will be using.
curve
Command
The This command allows you to draw Bézier curves between two points. With the arc command, we needed a radius, but here we need control points. We can either have one control point and create a Quadratic curve or two control points and create a Cubic curve.
Here is a figure to illustrate a few examples. The black dots illustrate the control points, and the blue ones the starting and ending points.

And a demo:
I won’t detail the exact geometry behind the curves, but notice their behavior close to the starting and ending points. The curve is tangent to the lines that link the starting and ending points with the control points. This will be the key to create our blob shape.
Here is an online demo where you can drag the different points to see how the curve behaves.
The code of this command is:
clip-path: shape(from Xa Ya, curve to Xb Yb with Xc1 Yc1 / Xc2 Yc2)
And I will be using one control point, so we can omit the second control point:
clip-path: shape(from Xa Ya, curve to Xb Yb with Xc1 Yc1)
By combining many curves, we can create a blob. We have to understand how to correctly combine them, so it’s time for a small geometry course.
The Geometry of The Blob
Mathematically speaking, there is no specific geometry for a blob because it’s not a shape we can formally define. We can implement a blob using different methods and calculations, so what I am going to share is my own implementation. It’s probably not the best one, but it gives a good result.
We first start by placing N points around a circle. The number of points is the first parameter of the blob that I am calling “granularity” in my generator. Then I define a distance D I call the depth.

Now, we randomly move the points within the area defined by the distance D. For each point, we pick a random value in the range [0 D] and we make it closer to the center using that value.

For the next step, we take two consecutive points, draw a line between them, and then place a new point at the center. This will double the number of points.

The last step is to draw the Bézier curves. The new points (the blue ones) are the starting and ending points, and the initial points (the black ones) are the control points.

The fact that two adjacent curves share the same tangent is what gives us a continuous and smooth shape, a perfect blob!
That’s it. Now let’s translate this into code.
The Code of The Blob
Similar to the flower shape, the code will be a bunch of curve commands like below:
.blob {
clip-path: shape(from X0 Y0,
curve to X1 Y1 with Xc1 Yc1,
curve to X2 Y2 with Xc2 Yc2,
curve to X3 Y3 with Xc3 Yc3,
curve to X4 Y4 with Xc4 Yc4,
...
curve to Xn Yn with Ycn Ycn
)
}
Code language: CSS (css)
[Xi, Yi]
are the starting/ending points (the blue ones), and [Xci, Yci]
are the control points (the black ones). For the sake of simplicity, I will use pseudo-code to illustrate the calculation. The real implementation can be done using JavaScript like in my generator, or using Sass (I will share a demo using Sass later).
We first start by defining the control points:
N = 15 /* number of points (granularity) */
D = 20% /* depth */
for i in [1 N] {
R = 50% - random(D);
Xci = 50% + R*math.cos(360deg * i/N));
Yci = 50% + R*math.sin(360deg * i/N));
}
R will define the distance of the points from the center, and it will have a random value between 50%
and 50% - D
.
Then we define the main points where each one is placed at the center of two consecutive control points:
for i in [1 N] {
Xi = (Xci + Xci+1)/2;
Yi = (Yci + Yci+1)/2;
}
Finally, the shape function will be as follows:
clip-path: shape(from X0 Y0,
for i in [1 N] {
curve to Xi Yi with Xci Yci,
}
)
Here is a Sass implementation:
One observation we can make is that the shape is responsive. It’s designed to work with square elements (aspect-ratio: 1
), but the result is not bad for rectangular elements as well. Resize the element in the demo below and see how the shape behaves:
The code can also be tweaked to create more variations. We can, for example, have a kind of wavy circle by removing the random part and applying a fixed distance to half the points.
Can you think of other variations?
Animating The Blob
Having the blob shape in CSS is already a cool feature. It’s one line of code that can be applied to any element, including images, and it’s responsive! In addition to this, we can easily animate them. The only requirement is to have the same structure inside shape()
. So if we take two blobs having the same number of curve commands, then we can animate one into another!
Here is an example where we keep the same number of points and only adjust the depth:

You copy both codes from the generator, apply a transition, and you have a cool hover effect that transforms a circle into a blob!
The bouncing effect you get is made with the linear()
function which is another cool feature for custom easing. I am getting the code from here.
Now, if you update the Shape ID and still keep the same number of points, you can have a transition between two different blobs.

Cool, right? The code may look complex but in the end everything is generated for you, so it’s nothing but a few clicks to get a fancy shape with a nice animation! Speaking about animation, let’s end with a demo using a keyframes instead of a transition.
Conclusion
I hope you enjoyed this shape()
exploration through this series of articles. Once this feature becomes widely supported, it will be a game changer and we can forget about all the hacky workarounds to create CSS shapes.
Don’t forget to keep an eye on my CSS Shapes and CSS Generators websites from where you can easily copy the code of any CSS shape.