Blob Mask
A block cut into an organic pebble shape by an SVG mask, gently tightening and easing back: gradient, photo or figure inside.
Updated
This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. SVG has 30 effects, including 3 free. Explore the category →
3 usage examples



How it works
The .blm-blob block is a square (220 px by default, aspect-ratio:1) filled with a cyan → blue → indigo gradient. Its mask-image is a blob shape drawn in SVG and written straight into the CSS (data URI): only the areas covered by the shape stay visible. The mask is centred, not repeated, and spans the square's full width: the whole outline shows, rounded edges and dips included.
The blmBreathe animation takes the mask size from 100% to 86% and back over 4 s (ease-in-out, looping). The shape tightens towards its centre and returns, like breathing; the content itself does not move. Range and duration are set with --blm-min, --blm-max and --blm-speed.
Everything inside the block is cut with it: the centred word “BLOB”, or an <img> filling the square (object-fit:cover). CSS only, no JavaScript; every mask declaration is paired with its -webkit- version.
Accessibility
- Reduced motion: under
prefers-reduced-motion: reducethe animation is removed; the blob stays full size and still. - Slow motion: one cycle lasts 4 s and the shape only varies by 14%: no flashing, no jumps.
- Content: the text is a real
<span>and an image keeps itsalt. The blob's edges trim part of the image: keep the subject centred. - Pointer: the blob is decorative and does not respond to clicks and keeps the normal cursor.
Browser compatibility
SVG data-URI mask-image, animated mask-size (with -webkit- versions for Chrome and Edge before 120 and Safari before 15.4), CSS variables inside @keyframes, aspect-ratio, inset. Measured in Chromium, Firefox and WebKit (Playwright): shape visible (removing the mask changes 8 to 10% of the image), breathing, two copies, reduced-motion stop, 390 px.
Without masking the whole square shows, uncut. Without aspect-ratio, give the block a height equal to --blm-size.
The code
HTML structure to paste into your page (the CSS + JS come with your purchase):
<div class="fx-0627-root">
<div class="blm-blob">
<span class="blm-label">BLOB</span>
</div>
</div>
One-time payment, no subscription — the code is yours forever
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
Size (CSS — --blm-size) |
220px | Side of the square; the shape follows. 100% to fill a parent. |
Fill (CSS — --blm-fill) |
linear-gradient(135deg, #06b6d4, #3b82f6, #6366f1) | Any background value. An <img> placed in the block covers it. |
Breathing (CSS — --blm-min, --blm-max) |
86% / 100% | Extreme mask sizes. Keep --blm-max at 100% or less: beyond that the shape leaves the square and gets trimmed. |
Cycle duration (CSS — --blm-speed) |
4s | 6 to 8 s for a calm background, 3 s for a livelier badge. |
Block background and height (CSS — --blm-page, --blm-height) |
#0a0a0f / 300px | transparent and 0px to drop the blob into your layout. |
Shape (CSS — the path's d attribute in the mask URL) |
10-curve pebble | Swap in another blob path (blob generator, Figma, Inkscape) in a 200 × 200 viewBox; change it in both mask-image and -webkit-mask-image. |
FAQ
mask-size of 100% at most). On a square block, the whole outline shows throughout the breathing. On a block wider than it is tall, the mask would keep its proportions and the shape would be cut at the top and bottom: keep aspect-ratio:1 and only change --blm-size.<span class="blm-label"> with <img src="portrait.jpg" alt="…">: the image covers the square, then the mask cuts it. A tightly framed portrait with the face centred works best.mask-image cannot morph from one shape to another. For a shape that deforms, animate an SVG path (see the Morphing Shape effect in the same category) or an eight-value border-radius.