Following our latest web experiment by Lucas Bebber where we created realistic heat and water distortion on images and text, we’d like to share some inspiration for these kind of effects on buttons. Applying SVG filters on HTML elements give us some great opportunity to get creative with click interactions, and that’s exactly what we are going to explore today.

The main idea is to apply distortion or blob filters to buttons and explore some creative possibilities.

If you remember the“Gooey effect” that Lucas also introduced last year, you might recall that this technique is using the CSS filter() function mixed with an SVG <filter> . This is now supported by modern browsers, which is really great because lots of other filter effects still aren’t, so let’s dig a bit more into it and see what we can do on buttons with this.

Attention:This is still a highly experimental technique which currently works best in Google Chrome and Firefox.

Let’s have a closer look at the technique used.

Setting up the Button

To begin, let’s create a simple button element:

<button class="button">Click me</button>

With some basic styling, our button looks like this:

Then, we define the filter inside an SVG object which we will place in our HTML:

The slash in the second declaration is important, if you want to have the filter properly applied in Firefox.

How the filter works

SVG filters offer an extensive list of primitives. Check outLucas’ article to get a bit of background on them.

One of the primitives is particularly interesting for our example which is the <fedisplacementmap> .

The displacement map effect moves the pixels of the element you apply it to, based on the pixel values of an input of your choice.

<fedisplacementmap>can be applied on any DOM element based on different sources such as an image, a gradient or another SVG filter element. For the button we are building, we use the SVG’s <feTurbulence> element.

<feTurbulence>is a primitive that generates “noise” (based on the Perlin noise algorithm).

See what happens when we apply this alone to our button:

The <baseFrequency> property is the important one here. It will define how the noise will be generated. It accepts two numbers as parameters that correspond to the effect on the x and y coordinates.

Play with the properties to understand how it works:

Now, let’s apply our <fedisplacementmap> filter and see what happen:

The important property here is the scale : it defines the strength of the effect.

We also need to determine the sources of our filter: every filters accept two input sources with the properties in and in2 . We define our first source as SourceGraphic (this is the HTML element we apply the filter to) and the second source as our first filter <feTurbulence> (we give it the name noise ).

Now our displacement map knows that it must move the pixels of the SourceGraphic based on the noise generated with <feTurbulence> .

The xChannelSelector and yChannelSelector properties tells it which color (R, G or B) to use to define the pixel displacement on each axis.

Now we just have to animate these properties using JavaScript to have the achieve the effect (we use the Greensock animation library here):

You can adventure yourself and apply this to any HTML element. See the result on a textarea for example:

Some interesting possibilities here

SVG filters let us apply advanced algorithm like displacement maps really easily on web elements. All the complicated work is handled by the SVG filter element itself, all we are doing here is applying and animating some parameters.

And that’s it! Most of the effects in the demo are using the principle described.

Check out more ideas in the demo. Keep in mind that SVG filters can be applied to any HTML element so there is tons of other possibilities. Your imagination is the limit, but keep in mind to use these kind of effects wisely as filters can be quite resource intensive; refrain from applying them to large areas.

Note that support for CSS filters varies across browsers and the effects can also look slightly different. Make sure to always include a fallback.