Creative Gooey Effects


View demo Download source

Today we are going to show how to use SVG Filters to apply a gooey-like effect to HTML elements. We’ll first cover some basics of the technique and then we’ll demonstrate several creative use cases for common website elements, like menus, apps, selections, paginations and more.

Please note that this effect is experimental and is only supported by modern browsers.

Let’s first dive into SVG Filters and understand how to apply them.

SVG Filters

With SVG Filters we can modify a given source graphic with an operation (or more) and create an altered result. Every filter element in SVG contains a set of filter primitives that do some kind of graphical operation. The available SVG filter primitives are the following:

  • feBlend
  • feColorMatrix
  • feComponentTransfer
  • feComposite
  • feConvolveMatrix
  • feDiffuseLighting
  • feDisplacementMap
  • feFlood
  • feGaussianBlur
  • feImage
  • feMerge
  • feMorphology
  • feOffset
  • feSpecularLighting
  • feTile
  • feTurbulence
  • feDistantLight
  • fePointLight
  • feSpotLight


When applying a filter, we can use the result of the operation as an input to another filter, creating an inifinite range of possibilities for effects. That’s what makes filters really powerful.

A common example for a SVG filter is the blur effect with <feGaussianBlur>:

<svg xmlns="" version="1.1" width="600" height="400">
		<filter id="blur" x="0" y="0">
			<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
	<rect x="50" y="50" width="500" height="300" fill="#8d81ac" filter="url(#blur)" />  

The result looks as follows:


The in attribute defines the input for the given filter primitive. Here we can use one of the following keywords:

  • SourceGraphic
  • SourceAlpha
  • BackgroundImage
  • BackgroundAlpha
  • FillPaint
  • StrokePaint

We can also use a string here which references a previous result attribute. The result attribute gives us the possibility to make the result of a filter operation available as input to another filter using in. For our Gooey examples we will be using this.

A more complex example that shows how multiple filter primitives can be used in combination to achieve one desired effect is the drop shadow:

<svg xmlns="" version="1.1" width="600" height="400">
	<filter id="dropshadow" x="0" y="0" width="200%" height="200%">
		<feOffset result="offsetResult" in="SourceAlpha" dx="20" dy="20" />
		<feGaussianBlur result="blurResult" in="offsetResult" stdDeviation="5" />
		<feBlend in="SourceGraphic" in2="blurResult" mode="normal" />
  <rect width="500" height="300" fill="#8d81ac" filter="url(#dropshadow)" />

The result looks as follows:


The concept here is that we first offset the element and then blur that offset “copy”. With the blend primitive, we simply set the original element on top of the blurred result. Using in="SourceAlpha", which is the alpha channel of the source graphic, actually makes the blurred result black. If we’d, for example, use in="SourceGraphic", the “shadow” would have the color of the source element.

SVG Filters for HTML

Applying SVG Filters to HTML elements is pretty straightforward. First, we define our filter somewhere in the HTML and then we can use it in our stylesheet as follows:

.filterClass {
	-webkit-filter: url("#goo");
	filter: url("../index.html#goo");

The reason why we define the path differently for the non-webkit property is Firefox and the way it references the filter. Being a relative path, if we’d only use #goo, it would refer to it’s stylesheet instead of the HTML it is used in and there no filter will be found. Using inline styles or referencing to it the way we do it, solves that problem. We can also add filter effects with JavaScript:

function setFilter(value){
		webkitFilter: value,
		filter: value,

Where value would be something like ‘url(#goo)’.

Support for SVG Filters on HTML elements is currently pretty good.

The following are some great resources for learning more about and experimenting with SVG Filters:

Applying the Gooey Filter

Let’s take a look at one of the demos to see how it works in practice:


The markup for this example looks as follows:

<div class="menu">
	<div class="menu-wrapper">
		<ul class="menu-items">
			<li class="menu-item">
				<button class="menu-item-button">
					<i class="menu-item-icon icon icon-reply"></i>
				<div class="menu-item-bounce"></div>
			<li class="menu-item">
				<button class="menu-item-button">
					<i class="menu-item-icon icon icon-box"></i>
				<div class="menu-item-bounce"></div>
			<li class="menu-item">
				<button class="menu-item-button">
					<i class="menu-item-icon icon icon-trash"></i>
				<div class="menu-item-bounce"></div>
		<button class="menu-toggle-button">
			<i class="fa fa-plus menu-toggle-icon"></i>

We also define the filter inside an SVG object which we will place in our HTML:

<svg xmlns="" version="1.1">
    <filter id="goo">
      <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />
      <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 19 -9" result="goo" />
      <feComposite in="SourceGraphic" in2="goo" operator="atop"/>

Next, we use the filter CSS property like described before in order to apply the filter to the container of the elements we want to stick together:

.menu {
	/* other styles */

	-webkit-filter: url("#goo");
	filter: url("../menu.html#goo");

Now, let’s break down the filter. The first operation done by the filter is to blur the object, through the feGaussianBlur filter.


The next operation is a feColorMatrix filter. It is used in this case to increase the contrast of the alpha channel, which, combined with the blur, creates that blob effect:


Learn more about how to apply a color matrix here.

Finally, to make the contents visible, we draw the original graphics of the object over the effect we just made, using it as a mask as well. To achieve that, we use the feComposite filter with the atop operator:


And we’re done! Please be aware that this filter can be quite resource intensive, so you should refrain from applying it to large areas.


The following demos will show some creative ways of using Gooey effects on all kinds of components:

We hope you find these examples inspiring!

View demo Download source

Creative Gooey Effects was written by Lucas Bebber and published on Codrops.