Blob, Blob, Blob. You hate them. You love them. Personally, as a design illiterate, I like to overuse them… a lot. And when you repeat the same process over and over again, it’s only a question of how much you can optimize it, or in this case, what’s the easiest way to create blobs in CSS? Turns out, as always, there are many approaches.
To know if our following blobs are worth using, we’ll need them to pass three tests:
- They can be with just a single element (and preferably without pseudos).
- They can be easily designed (ideally through an online tool).
- We can use gradient backgrounds, borders, shadows, and other CSS effects on them.
Without further ado, let’sBlob, Blob, Blobright in.
Just generate them online
I know it’s disenchanting to click on an article about making blobs in CSS just for me to say you can generate them outside CSS. Still, it’s probably the most common way to create blobs on the web, so to be thorough, these are some online tools I’ve used before to create SVG blobs.
- Haikei. Probably the one I have used the most since, besides blobs, it can also generate lots of SVG backgrounds.
- Blobmaker. A dedicated tool for making blobs. It’s apparently part of Haikei now, so you can use both.
- Lastly, almost all graphic programs let you hand-draw blobs and export them as SVGs.
For example, this is one I generated just now. Keep it around, as it will come in handy later.
<svg viewbox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"> <path fill="#FA4D56" d="M65.4,-37.9C79.2,-13.9,81,17,68.1,38C55.2,59.1,27.6,70.5,1.5,69.6C-24.6,68.8,-49.3,55.7,-56,38.2C-62.6,20.7,-51.3,-1.2,-39,-24.4C-26.7,-47.6,-13.3,-72,6.2,-75.6C25.8,-79.2,51.6,-62,65.4,-37.9Z" transform="translate(100 100)"></path> </svg>
Using border-radius
While counterintuitive, we can use theborder-radiusproperty to create blobs. This technique isn’t new by any means; it wasfirst described by Nils Binderin 2018, but it is still fairly unknown. Even for those who use it, the inner workings are not entirely clear.
To start, you may know theborder-radiusis a shorthand to each individual corner’s radius, going from the top left corner clockwise. For example, we can set each corner’sborder-radiusto get a bubbly square shape:
<div></div>
.blob { border-radius: 25% 50% 75% 100%; }
However, whatborder-radiusdoes — and also why it’s called “radius” — is to shape each corner following a circle of the given radius. For example, if we set the top left corner to25%, it will follow a circle with a radius25%the size of the shape.
.blob { border-top-left-radius: 25%; }
What’s less known is that each corner property is still ashortcuttowards its horizontal and vertical radii. Normally, you set both radii to the same value, getting a circle, but you can set them individually to create an ellipse. For example, the following sets the horizontal radius to25%of the element’s width and the vertical to50%of its height:
.blob { border-top-left-radius: 25% 50%; }
We can now shape each corner like an ellipse, and it is the combination of all four ellipses that creates the illusion of a blob! Just take into consideration that to use the horizontal and vertical radii syntax through theborder-radiusproperty, we’ll need to separate the horizontal from the vertical radii using a forward slash (/).
.blob { border-radius: /* horizontal */ 100% 30% 60% 70% / /* vertical */ 50% 40% 70% 70%; }
The syntax isn’t too intuitive, so designing a blob from scratch will likely be a headache. Luckily,Nils Binder made a toolexactly for that!
Blobbing blobs together
This hack is awesome. We aren’t supposed to useborder-radiuslike that, but we still do. Admittedly, we are limited to boring blobs. Due to the nature ofborder-radius, no matter how hard we try, we will only get convex shapes.
Just going offborder-radius, we can try to minimize it a little by sticking more than one blob together:
However, I don’t want to spend too much time on this technique since it is too impractical to be worth it. To name a few drawbacks:
- We are using more than one element or, at the very least, an extra pseudo-element. Ideally, we want to keep it to one element.
- We don’t have a tool to prototype our blobby amalgamations, so making one is a process of trial and error.
- We can’t use borders, gradients, or box shadows since they would reveal the element’s outlines.
Multiple backgrounds and SVG filters
This one is an improvement in the Gooey Effect,described here by Lucas Bebber, although I don’t know who first came up with it. In the original effect, several elements can be morphed together like drops of liquid sticking to and flowing out of each other:
It works by first blurring shapes nearby, creating some connected shadows. Then we crank up the contrast, forcing the blur out and smoothly connecting them in the process. Take, for example, this demo by Chris Coyer (It’s from 2014, so more than 10 years ago!):
If you look at the code, you’ll notice Chris uses thefilterproperty along theblur()andcontrast()functions, which I’ve also seen in other blob demos. To be specific, it appliesblur()on each individual circle and thencontrast()on the parent element. So, if we have the following HTML:
<div></div> <div></div> <div></div>
…we would need to apply filters and background colors as such:
.blob { filter: contrast(50); background: white; /* Solid colors are necessary */ } .subblob { filter: blur(15px); background: black; /* Solid colors are necessary */ }
However, there is a good reason why those demos stick to white shapes and black backgrounds (or vice versa) since things get unpredictable once colors aren’t contrast-y enough. See it for yourself in the following demo by changing the color. Just be wary:shades get ugly.
To solve this, we will use an SVG filter instead. I don’t want to get too technical on SVG (if you want to, read Luca’s post!). In a nutshell, we can apply blurring and contrast filters using SVGs, but now, we can also pick which color channel we apply the contrast to, unlike normalcontrast(), which modifies all colors.
Since we want to leave color channels (R,GandB) untouched, we will only crank the contrast up for the alpha channel. That translates to the next SVG filter, which can be embedded in the HTML:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="position: absolute;"> <defs> <filter> <fegaussianblur in="SourceGraphic" stddeviation="12" result="blur"></fegaussianblur> <fecolormatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -6" result="goo"></fecolormatrix> <feblend in="SourceGraphic" in2="blob"></feblend> </filter> </defs> </svg>
To apply it, we will use againfilter, but this time we’ll set it tourl("#blob"), so that it pulls the SVG from the HTML.
.blob { filter: url("#blob"); }
And now we can even use it with gradient backgrounds!
That being said, this approach comes with two small, but important, changes to common CSS filters:
- The filter is applied to the parent element, not the individual shapes.
- The parent element must be transparent (which is a huge advantage). To change the background color, we can instead change the body or other ancestors’ background, and it will work with no issues.
What’s left is to place the.subblobelements together such that they make a blobby enough shape, then apply the SVG filters to morph them:
Making it one element
This works well, but it has a similar issue to the blob we made by morphing severalborder-radius instances: too many elements for a simple blob. Luckily, we can take advantage of thebackgroundproperty to create multiple shapes and morph them together using SVG filters, all in a single element. Since we are keeping it to one element, we will go back to just oneempty .blob div:
<div></div>
To recap, thebackgroundshorthand can set all background properties and also set multiple backgrounds at once. Of all the properties, we only care about thebackground-image,background-positionandbackground-size.
First, we will usebackground-imagealong withradial-gradient()to create a circle inside the element:
body { background: radial-gradient(farthest-side, var(--blob-color) 100%, #0000); background-repeat: no-repeat; /* Important! */ }
Here is what each parameter does:
- farthest-side: Confines the shape to the element’s box farthest from its center. This way, it is kept as a circle.
- var(--blob-color) 100%: Fills the background shape from 0 to 100% with the same color, so it ends up as a solid color.
- #0000: After the shape is done, it makes a full stop to transparency, so the color ends.
The next part is moving and resizing the circle using thebackground-positionandbackground-sizeproperties. Luckily, both can be set onbackgroundafter the gradient, separated from each other by a forward slash (/).
body { background: radial-gradient(...) 20% 30% / 30% 40%; background-repeat: no-repeat; /* Important! */ }
The first pair of percentages sets the shape’s horizontal and vertical position (taking as a reference the top-left corner), while the second pair sets the shape’s width and height (taking as a reference the element’s size).
As I mentioned, we can stack up different backgrounds together, which means we can create as many circles/ellipses as we want! For example, we can create three ellipses on the same element:
.blob { background: radial-gradient(farthest-side, var(--blob-color) 100%, #0000) 20% 30% / 30% 40%, radial-gradient(farthest-side, var(--blob-color) 100%, #0000) 80% 50% / 40% 60%, radial-gradient(farthest-side, var(--blob-color) 100%, #0000) 50% 70% / 50% 50%; background-repeat: no-repeat; }
What’s even better is that SVG filters don’t care whether shapes are made of elements or backgrounds, so we can also morph them together using the lasturl(#blob)filter!
While this method may be a little too much for blobs, it unlocks squishing, stretching, dividing, and merging blobs in seamless animations.
Again, all these tricks are awesome, but not enough for what we want! We accomplished reducing the blob to a single element, but we still can’t use gradients, borders, or shadows on them, and also, they are tedious to design and model. Then, that brings us to the ultimate blob approach…
Using the shape() function
Fortunately, there is a new way to make blobs that just dropped to CSS: theshape()function!
I’ll explainshape()‘s syntax briefly, but for an in-depth explanation, you’ll want to check out both this explainer from the CSS-Tricks Almanac as well asTemani Afif‘s three-partseries on theshape()function, as well as his recent article aboutblobs.
First off, the CSSshape()function is used alongside theclip-pathproperty to cut elements into any shape we want. More specifically, it uses a verbal version of SVG’spathsyntax. The syntax has lots of commands for lots of types of lines, but when blobbing withshape(), we’ll define curves using thecurvecommand:
.blob { clip-path: shape( from X0 Y0, curve to X1 Y1 with Xc1 Yc1, curve to X2 Y2 with Xc21 Yc21 / Xc22 Yc22 /* ... */ ); }
Let’s break down each parameter:
- X0 Y0defines the starting point of the shape.
- curvestarts the curve whereX1 Y1is the next point of the shape, whileXc1 Yc1defines a control point used in Bézier curves.
- The next parameter is similar, but we usedXc21 Yc21 / Xc22 Yc22instead to define two control points on the Bézier curve.
I honestly don’t understand Bézier curves and control points completely, but luckily, we don’t need them to useshape()and blobs! Again,shape()uses a verbal version of SVG’spathsyntax, so it can draw any shape an SVG can, which means that we can translate the SVG blobs we generated earlier… and CSS-ify them. To do so, we’ll grab thedattribute (which defines thepath) from our SVG and paste it into Temani’sSVG toshape()generator.
This is the exact code the tool generated for me:
.blob { aspect-ratio: 0.925; /* Generated too! */ clip-path: shape( from 91.52% 26.2%, curve to 93.52% 78.28% with 101.76% 42.67%/103.09% 63.87%, curve to 44.11% 99.97% with 83.95% 92.76%/63.47% 100.58%, curve to 1.45% 78.42% with 24.74% 99.42%/6.42% 90.43%, curve to 14.06% 35.46% with -3.45% 66.41%/4.93% 51.38%, curve to 47.59% 0.33% with 23.18% 19.54%/33.13% 2.8%, curve to 91.52% 26.2% with 62.14% -2.14%/81.28% 9.66% ); }
As you might have guessed, it returns our beautiful blob:
Let’s check if it passes our requirements:
- Yes, they can be made of a single element.
- Yes, they can also be created in a generator and then translated into CSS.
- Yes, we can use gradient backgrounds, but due to the nature ofclip-path(),borders and shadows get cut out.
Two out of three? Maybe two and a half of three? That’s a big improvement over the other approaches, even if it’s not perfect.
Conclusion
So, alas, we failed to find what I believe is the perfect CSS approach to blobs. I am, however, amazed how something so trivial designing blobs can teach us about so many tricks and new CSS features, many of which I didn’t know myself.
The above is the detailed content of CSS Blob Recipes. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

There are three ways to create a CSS loading rotator: 1. Use the basic rotator of borders to achieve simple animation through HTML and CSS; 2. Use a custom rotator of multiple points to achieve the jump effect through different delay times; 3. Add a rotator in the button and switch classes through JavaScript to display the loading status. Each approach emphasizes the importance of design details such as color, size, accessibility and performance optimization to enhance the user experience.

To deal with CSS browser compatibility and prefix issues, you need to understand the differences in browser support and use vendor prefixes reasonably. 1. Understand common problems such as Flexbox and Grid support, position:sticky invalid, and animation performance is different; 2. Check CanIuse confirmation feature support status; 3. Correctly use -webkit-, -moz-, -ms-, -o- and other manufacturer prefixes; 4. It is recommended to use Autoprefixer to automatically add prefixes; 5. Install PostCSS and configure browserslist to specify the target browser; 6. Automatically handle compatibility during construction; 7. Modernizr detection features can be used for old projects; 8. No need to pursue consistency of all browsers,

Themaindifferencesbetweendisplay:inline,block,andinline-blockinHTML/CSSarelayoutbehavior,spaceusage,andstylingcontrol.1.Inlineelementsflowwithtext,don’tstartonnewlines,ignorewidth/height,andonlyapplyhorizontalpadding/margins—idealforinlinetextstyling

Setting the style of links you have visited can improve the user experience, especially in content-intensive websites to help users navigate better. 1. Use CSS's: visited pseudo-class to define the style of the visited link, such as color changes; 2. Note that the browser only allows modification of some attributes due to privacy restrictions; 3. The color selection should be coordinated with the overall style to avoid abruptness; 4. The mobile terminal may not display this effect, and it is recommended to combine it with other visual prompts such as icon auxiliary logos.

Use the clip-path attribute of CSS to crop elements into custom shapes, such as triangles, circular notches, polygons, etc., without relying on pictures or SVGs. Its advantages include: 1. Supports a variety of basic shapes such as circle, ellipse, polygon, etc.; 2. Responsive adjustment and adaptable to mobile terminals; 3. Easy to animation, and can be combined with hover or JavaScript to achieve dynamic effects; 4. It does not affect the layout flow, and only crops the display area. Common usages are such as circular clip-path:circle (50pxatcenter) and triangle clip-path:polygon (50%0%, 100 0%, 0 0%). Notice

To create responsive images using CSS, it can be mainly achieved through the following methods: 1. Use max-width:100% and height:auto to allow the image to adapt to the container width while maintaining the proportion; 2. Use HTML's srcset and sizes attributes to intelligently load the image sources adapted to different screens; 3. Use object-fit and object-position to control image cropping and focus display. Together, these methods ensure that the images are presented clearly and beautifully on different devices.

The choice of CSS units depends on design requirements and responsive requirements. 1.px is used for fixed size, suitable for precise control but lack of elasticity; 2.em is a relative unit, which is easily caused by the influence of the parent element, while rem is more stable based on the root element and is suitable for global scaling; 3.vw/vh is based on the viewport size, suitable for responsive design, but attention should be paid to the performance under extreme screens; 4. When choosing, it should be determined based on whether responsive adjustments, element hierarchy relationships and viewport dependence. Reasonable use can improve layout flexibility and maintenance.

Different browsers have differences in CSS parsing, resulting in inconsistent display effects, mainly including the default style difference, box model calculation method, Flexbox and Grid layout support level, and inconsistent behavior of certain CSS attributes. 1. The default style processing is inconsistent. The solution is to use CSSReset or Normalize.css to unify the initial style; 2. The box model calculation method of the old version of IE is different. It is recommended to use box-sizing:border-box in a unified manner; 3. Flexbox and Grid perform differently in edge cases or in old versions. More tests and use Autoprefixer; 4. Some CSS attribute behaviors are inconsistent. CanIuse must be consulted and downgraded.
