Add Interactive Water Ripples to Any Webflow Section

Intermediate 29:14 webflowwebglripplescmsjquery

Add a fully configurable, no-code water ripple effect to any Webflow section or CMS gallery — built on jQuery + WebGL with a live GUI panel for real-time tuning.

Key takeaways

  • The effect distorts a CSS background image, not an <img> tag — so the element that receives it must have a background image set on it, or nothing happens.
  • One attribute is all it takes: mark an element with FC-ripples="component" and resolution, drop radius, and perturbance all fall back to sensible defaults, so you start with zero config.
  • The live GUI panel lets you tune the feel in the browser in real time; once you like it, you bake the winning values back into Webflow as data-* attributes and remove the panel for production.
  • CMS items can't be configured individually, so you apply the effect to an absolutely-positioned overlay div (its background bound to the CMS image, layered over a real <img> that holds the layout) and control the whole set with one shared group.
  • WebGL is heavy, so ship the escape hatches: FC-ripples-disable-mobile skips it on phones, and a toggle button with aria-pressed lets visitors pause it — both good for performance and accessibility.

Video chapters

  1. 00:00 Intro
  2. 01:39 First example and configuration of the solution
  3. 08:03 First example: live behavior and interactive configuration
  4. 13:55 CMS example: structure and configuration
  5. 21:06 CMS example: live behavior and further testing
  6. 24:37 Code overview
  7. 28:04 Outro

Add an interactive water ripple effect to any section or element in Webflow — the kind that reacts to your cursor and gently distorts the background like the surface of a pond — with zero code and full control over how it looks. It runs on a lightweight jQuery plugin with a bit of WebGL magic on top, wrapped in a clean attribute-based system so you can use and tweak it even if JavaScript isn’t your thing.

The nicest part is that it just works out of the box. Mark one element with a single attribute and you get sensible defaults immediately — then, if you want, open a live panel to fine-tune the feel right in the browser before baking your favourite values back into Webflow. The exact same setup scales from a single hero banner all the way up to a full CMS gallery.

And because WebGL effects can be heavy, it ships with the escape hatches that actually matter: disable it on mobile with one attribute, and give visitors a real toggle button — proper ARIA and all — so they can pause it whenever they like.

How it works

The one rule that trips everyone up: the effect needs a background image. The plugin uses WebGL to distort a CSS background image — not an <img> tag, and not any image sitting inside the element. So whatever element you want to ripple must have the image assigned as its background (with background-size: cover on a section, so it fills the space and scales cleanly). Drop a native image in and nothing will happen; that single detail is behind most “why isn’t it working” moments.

One attribute, then defaults. You mark the target element with FC-ripples="component" and that’s genuinely enough — the script reads three parameters (resolution, drop radius, perturbance) and falls back to reasonable defaults whenever you haven’t set them. That’s on purpose: you can prototype instantly and only fine-tune when you care to. When you do want to tune, add FC-ripples-config="something" and the script generates a live GUI panel labelled with your value. You adjust the sliders in the browser, watch the water change in real time, and — once you find the sweet spot — go back into Webflow, remove the config attribute, and hard-code your numbers as data-resolution, data-drop-radius, and data-perturbance. Clean, optimized, production-ready, with no panel shipping to visitors.

The CMS trick is the clever bit. A background image doesn’t occupy space in the layout — it has no width or height of its own — so if you built a gallery purely from background images, the items would collapse. The fix: keep a real <img> in each item to define the size and aspect ratio, then layer an absolutely-positioned overlay div (all offsets 0, so it covers the item exactly) on top of it, bind the overlay’s background to the same CMS image field, and apply FC-ripples="component" to the overlay. You get the layout from the real image and the effect from the background — the best of both worlds. Because Webflow won’t let you configure each CMS item individually, you put FC-ripples="group" and FC-ripples-config="gallery" on the Collection List itself: the script collects every component inside that group and drives them all from a single shared panel. That’s what keeps it manageable across dozens of items.

Performance and accessibility are built in, not bolted on. WebGL can be demanding, so FC-ripples-disable-mobile tells the script to skip a component entirely on small screens — and when it does, hiding the toggle button makes sense, because there’s nothing left to toggle. That toggle is a button element marked FC-ripples="toggle" that pauses and resumes the effect at runtime; it carries aria-label so screen readers announce what it does, and aria-pressed that flips between true and false to communicate the current state. Giving people a clear way to stop motion-heavy effects is exactly the kind of control good sites offer.

How to use it

  1. Clone the project. Grab the Webflow cloneable — it includes the full structure, both examples, and a single fully-commented script (in Page Settings → Before </body>) that loads the jquery.ripples plugin and lil-gui for the panels. A summary table of every attribute lives at the bottom of the cloned page.

  2. Simple section. Give a section a background image (background-size: cover, not fixed, no tiling), then add FC-ripples="component". Publish and hover — you already have ripples on defaults.

  3. Tune it live (optional). Add FC-ripples-config="hero" to open the labelled GUI panel on the live site. Adjust resolution, drop radius, and perturbance until it feels right — see the configuration reference above for what each does and its useful range.

  4. Bake in your values. Remove FC-ripples-config, then add data-resolution, data-drop-radius, and data-perturbance with the numbers you landed on. Now it loads production-ready without the panel.

  5. CMS gallery. In each Collection Item, keep the real <img> for layout, add an overlay div (position: absolute, full offsets, background bound to the CMS image, background-size: 100%), and mark the overlay FC-ripples="component". On the Collection List, add FC-ripples="group" and FC-ripples-config="gallery" to control the whole set from one panel.

  6. Add the escape hatches. Put FC-ripples-disable-mobile on components that shouldn’t run on phones, and drop in a real button with FC-ripples="toggle" (plus aria-label and aria-pressed) so visitors can pause and resume the effect themselves.

Configuration reference

Attribute Values Default What it does
FC-ripples component · group · toggle The role marker that drives everything. Put "component" on the element that receives the effect (it must have a CSS background image), "group" on a parent like a CMS Collection List to control all components inside it with one shared config, and "toggle" on a button that pauses and resumes the effect.
FC-ripples-config any label (e.g. hero, gallery) Optional. Activates the live GUI panel for tuning the effect in the browser, and uses your value as the panel's label. Remove it before publishing to hide the panel.
FC-ripples-disable-mobile presence only (no value) Optional. Completely disables the effect on mobile devices, where WebGL can hurt performance and battery; it also makes sense to hide the toggle button when this is on.
data-resolution integer (64–2048) 512 Resolution of the WebGL texture that simulates the water surface — higher is smoother and more detailed but uses more GPU. 512–1024 is the sweet spot.
data-drop-radius pixels (1–50) 15 Size of each ripple when it is triggered, like the stone you drop into the water. Around 10–15 is elegant and low-profile; 25–30 gets splashy.
data-perturbance number (0–0.1) 0.004 Strength of the distortion applied to the background, from flat water to stormy sea. A good range to play with is 0.003–0.05.

Resources

Frequently asked questions

How do I add a water ripple effect to a Webflow section without code?
Clone the component, give the section a CSS background image, and add the attribute FC-ripples="component". The included jQuery + WebGL script initializes the ripples automatically with default settings — you never touch JavaScript.
Why does the ripple effect not work on my image?
The plugin distorts a background image using WebGL, not a native img element. If you dropped an image into the element, move it to the CSS background instead — or layer an overlay div whose background is that image — and apply the effect to that.
How do I add ripples to a Webflow CMS gallery?
Put an absolutely-positioned overlay div over each real image, bind the overlay's background to the CMS image field, and mark it FC-ripples="component". Then add FC-ripples="group" to the Collection List so one shared panel controls every item at once.
How do I disable the ripple effect on mobile?
Add FC-ripples-disable-mobile to the component. The script detects small screens and skips initialization entirely, which protects performance and battery — and it makes sense to hide the toggle button there too, since there is nothing to toggle.
How do I set my final ripple values after tuning them live?
Note the resolution, drop radius, and perturbance you settled on in the GUI, remove the FC-ripples-config attribute to hide the panel, then add data-resolution, data-drop-radius, and data-perturbance with those numbers so the effect loads production-ready.

← Back to the course

Also part of these courses