Realistic Water Effect using SVG Turbulence Filter

If you think you need a JavaScript or WebGL to create an animation like demo below, think again! In this tutorial I’m going to show you how to create a realistic water effect using SVG turbulence filter and CSS. Let’s check it out!


We’ll need 2 divs. First for the original image. And another (the one with “water” class) is for masking.

<div class="background">
  <div class="water"></div>

We’ll set the original image as background for the first div.

svg turbulence water effect tutorial

.background {
  position: absolute;
  top: 0;
  left: 0;
  height: 100vh;
  width: 100vw;
  background-image: url("sea.jpg");
  background-size: cover;

Masking Layer

From the original image, I’ll use Photoshop to remove all the non-water part. You can use quick selection tool for this job. Use shift button to continue adding more selection. Sometimes it will pickup more area than you need but you can use the alternate button to remove it.

Once you got all the non-water part. Press delete. Then you can the eraser tool for detailing and save the file as transparent png.

svg turbulence water effect tutorial

And then set the mask image that we created as background.

.background .water {
  position: absolute;
  background-image: url("sea-map.png");
  background-size: cover;
  height: 100%;
  width: 100%;

You won’t see any change yet. But the next step is the key.

SVG Turbulence Filter

We’ll use SVG turbulence filter. Basically it’s a filter that creates a turbulence effect on any element which is very useful for creating water and cloud effect. You can create a turbulence filter using <svg> tag. Then apply it to any element using CSS filter property.

  <filter id="turbulence" x="0" y="0" width="100%" height="100%">
    <feTurbulence id="sea-filter" numOctaves="3" seed="2" baseFrequency="0.02 0.05"></feTurbulence>
    <feDisplacementMap scale="20" in="SourceGraphic"></feDisplacementMap>

You can define the characteristic of the turbulence using attribute like seed and baseFrequency. It’s easier to understand each of them in action. There is a nice article on codrops with demo that can try out.

Next the feDisplacementMap tag, here you can set the filter scale amount and input graphic. We will set it to sourceGraphic which means we’ll use the source element that the filter was applied on as input.

Now to create an animation we need to manipulate the baseFrequency. We can use <animate> tag.

<animate xlink:href="#sea-filter" attributeName="baseFrequency" dur="60s" keyTimes="0;0.5;1" values="0.02 0.06;0.04 0.08;0.02 0.06" repeatCount="indefinite"/>

It’s similar to CSS Keyframes. The code above means I’ve divided the animation into 3 keyframes. First the basefrequency is at 0.02 and 0.06. Then at half of the animation is 0.04 and 0.08 and back to 0.02 and 0.06 again at the end. I set the repeatCount to indefinite to create a loop.

And finally applied the filter in CSS using the id of the filter tag.

.background .water {
  filter: url("#turbulence");

And that’s for this tutorial. You can download the source code here. If you love this and want to see more development tips and tutorials, subscribe our YouTube Channel to stay tune 🙂

Written By


  1. Great website with great tutorials. Respect! I could even left comment on every tutorial in here, but don’t want to spam. Good work!

Leave a Reply

Your email address will not be published. Required fields are marked *