Hover✨ Premium

Liquid Simulation

The mouse repels fifteen DOM drops: the pool opens around the cursor and slowly reassembles at the centre when the cursor leaves (weak centering pull). An SVG goo filter (Gaussian blur + alpha threshold) merges overlapping drops into a homogeneous surface. Not to be confused with the Liquid category (fx-0391–0420) which uses canvas or WebGL.

JSFluidMetaball

Updated

This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Hover has 48 effects, including 5 free. Explore the category →

3 usage examples

Portfolio hero — full-background liquid pool — Liquid Simulation example 1

① Portfolio hero — full-background liquid pool

WhenDark hero section of a creative agency or design studio.
WhyThe blue pool fills the space below the headline and opens around the cursor as the visitor explores — fluid motion without any click.
SettingsCyan-blue drops (#67e8f9 → #0369a1). Headline at top with opaque background (z-index:10). Full-background pool (z-index:1, mousemove received directly by the sim).
Send indicator — contact form on a professional site — Liquid Simulation example 2

② Send indicator — contact form on a professional site

WhenAt rest, drops cluster at the centre of the feedback zone (weak centripetal force). On clicking Send, the scene drives the sim via synthetic event: dispatchEvent(new MouseEvent('mousemove', { clientX: cx, clientY: cy })) centred on the sim; drops flee by repulsion and form a ring — a sign the message is being processed. After 1.4 s, a synthetic mouseleave lets them reassemble.
WhyA generic spinner disappears in the blink of an eye; a ring that opens then closes gives visible state feedback without any external resource or image.
SettingsEmerald drops (#6ee7b7 → #059669), 15 drops 30–70 px (real code). Feedback zone 100% × 150 px inside the card (overflow:hidden, border-radius:10px); root position:absolute; inset:0; min-height:0. pointer-events:none on sim at click to isolate the animation from natural events.
Client portal — File drop zone — Liquid Simulation example 3

③ Client portal — File drop zone

WhenAttachment upload form (client portal, back-office, internal tool).
WhyThe violet pool splits open where the file is held above the drop zone, making the landing spot visible. For real integration: listen to dragover on the zone and dispatch a synthetic mousemove to .ls385-sim at the file position (e.clientX/Y), then mouseleave on dragleave.
SettingsDark-violet drops (#c4b5fd → #6d28d9). Opaque header z-index:10 (title + Browse button always readable). Drop zone label with strong text-shadow (readable even if drops overlap). Drop zone: y:76–360 in the section (284 px tall).

How it works

The "goo" technique relies on two SVG primitives applied to a container: feGaussianBlur (8 px blur) followed by feColorMatrix with a strong alpha contrast (0 0 0 18 −7). This CSS filter is applied to .ls385-sim via filter: url(#uid). The filter's id is unique per instance (randomly generated) to avoid conflicts when two copies coexist in the same page: uid = 'ls385-goo-' + Math.random().toString(36).slice(2,7).

The 15 drops (div.ls385-drop) are created at load time with a random size (30–70 px) and random initial positions inside the container. On every frame, each drop experiences: repulsion from the cursor (vx −= dx/dist × fo, fo = (110−dist)/110 × 0.45) when the cursor is within 110 px; a weak centering pull (vx += (cx−x) × 0.0006 × f) always active; a random jitter (vx += (rand−0.5) × 0.12); and damping (vx *= 0.96^f). When the cursor leaves, only the centering pull remains: drops slowly gather into a mass at the centre. The step is normalised to 60 fps: f = dt / 16.67. An IntersectionObserver pauses the loop off screen.

Accessibility

  • Touch: touchmove repels drops around the finger, exactly like the cursor. touchend triggers the gradual return to the centre.
  • Keyboard: the effect is purely decorative and does not respond to the keyboard.
  • Reduced motion: under prefers-reduced-motion: reduce, the loop does not start and drops remain in a fixed ring around the centre, visible through the goo filter that blends them slightly.
  • Difference from the Liquid category: Liquid effects (fx-0391 to fx-0420) use canvas or WebGL for surface effects, metaballs or refraction. This effect uses only DOM div elements and an SVG filter, with no pixels drawn — it is a visual CSS/DOM simulation, not a graphic render.

Browser compatibility

DOM, CSS and SVG filter, no dependency. feGaussianBlur and feColorMatrix available in all modern browsers since Chrome 8, Firefox 3, Safari 6. filter: url(#id) on an HTML element requires Chrome 18+, Firefox 35+, Safari 9.1+. IntersectionObserver since Chrome 51, Firefox 55, Safari 12.1. Not verified on real Safari; expected full.

Chrome 51+✓ Full (measured)
Firefox 55+✓ Full (measured)
Safari 12.1+✓ Expected full (not measured)
Edge 79+✓ Full (measured)
Mobile iOS 12.2+✓ Full on touch (not measured)
Android Chrome 51+✓ Full on touch (not measured)

Without JavaScript, drops appear in a fixed ring with the goo filter active, blending them slightly. Without IntersectionObserver, the loop also runs off screen.

The code

HTML structure to paste into your page (the CSS + JS come with your purchase):

index.html — structure
<div class="fx-0385-root">
  <div class="ls385-wrap">
    <div class="ls385-sim"></div>
    <svg class="ls385-svg" width="0" height="0" aria-hidden="true" focusable="false">
      <filter>
        <feGaussianBlur in="SourceGraphic" stdDeviation="8" 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 -7" result="goo"></feColorMatrix>
        <feComposite in="SourceGraphic" in2="goo" operator="atop"></feComposite>
      </filter>
    </svg>
    <span class="ls385-label" aria-hidden="true">Hover to merge the drops</span>
  </div>
</div>

One-time payment, no subscription — the code is yours forever

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
Drop count (JS — loop for(var i=0;i<15;i++)) 15 8 gives a compact, less defined blob; 25 a smoother, richer surface. Beyond 30, the goo filter becomes slow on mobile.
Cursor influence radius (JS — dist < 110) 110 px 150 px enlarges the repulsion zone for a wider opening; 70 px only reacts to the cursor very close up.
Repulsion force (JS — factor 0.45) 0.45 0.7 gives a very snappy flight with drops shooting outward; 0.2 a slow, gradual opening.
Centering pull (JS — (cx−x) × 0.0006) 0.0006 0.002 brings drops back quickly when the cursor leaves; 0.0001 lets them drift for a long time before regrouping.
SVG blur (HTML — stdDeviation="8") 8 12 gives softer merging and blurrier edges; 4 sharp outlines but merging visible only on contact.

FAQ

Liquid effects (fx-0391–0420) use a canvas or WebGL to simulate surfaces, metaballs or refraction at the pixel level. This effect uses only DOM div elements and an SVG filter: no pixels are drawn, everything is CSS and DOM. It is lighter but less realistic, and its rendering changes if filter: url() on HTML is not supported (Safari < 9.1).
Two copies of the code on the same page would share the same id on their SVG filters, which is invalid HTML (IDs must be unique). The browser no longer knows which one to use and may apply the first copy's filter to both, or to neither. A random ID resolves this conflict without numbering instances.
Yes. The background of each div.ls385-drop is an animatable CSS property. Use a @keyframes on each drop with staggered delays (animation-delay) for a rotating rainbow; or change the colour from JS on each frame to follow the displacement.