Creative Gooey Effects

A set of examples that use a gooey SVG filter for creating a variety of different effects for all kinds of website components.

From our sponsor: Guide customers along the path to purchase with our award-winning platform. Starting at $14.99/mo.

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!

Tagged with:

Lucas Bebber

Lucas is a developer and illustrator at Garden Estúdio in Brazil. Check out his work on Codepen.

Stay up to date with the latest web design and development news and relevant updates from Codrops.

CSS Reference

Learn about all important CSS properties from the basics with our extensive and easy-to-read CSS Reference.

It doesn't matter if you are a beginner or intermediate, start learning CSS now.

Feedback 48

Comments are closed.
  1. Love it, such an awesome effect and you’ve made it quite simple how to achieve it!

  2. AWESOME! Seeing these effects makes me more confident to say, SVG is the future of UX and UI.

  3. would be great to find out which browsers are compatible with those effects. or if we can start using them today.

  4. Thanks so much for sharing all this. Your chat app is completely mind blowing, svg microanimation is the future of elegant ux.

  5. We can’t ignore the effect of gooey SVG filter, SVG filters are quite powerful.

  6. I tried to code a simple example but my svg filter disappears when animating my elements with tweenMax ; if I disable the animation, the filter works.
    Here’s a demo of the problem :

    This problem doesn’t happen on your examples and I don’t understand why, any help would be greatly appreciated.

  7. the chat app does not work well on Chrome (version 41 or 42 beta for example) and Mac (Yosemite):
    Click here for screenshot
    There is a clipping problem overflow-x: hidden; overflow-y: auto; so the chat thread is still visible on top of whole page.
    This seems to be a Chrome bug which doesn’t appear on all Mac installations: I tried with MacBook Air and Pro and Browserstack – all works well. But with latest Retina iMac this problem appears. The problem is located in
    TweenMax.fromTo( $messagesList,0.4,{ y:scrollDiff },{ y:0, ease:Quint.easeOut } );
    So without the scroll animation it works. As a workaround it is possible to use old school animate() feature of jQuery but synchronization is not so easy. Does anybody has got a better idea what to do?

  8. Superb efforts.
    Very nice and cool effect for Chat App. Need to give a scroll in the text area. If we type too many line than it will increase the height and some text is not visible.


  9. Hello,i used the share button on various grids i used to design for a blog UI and it was perfect on the single grid i put it on but when i added it on other grids it look perfect but on clicking one of the buttons it activates every where the button is on the page. So i have several open share buttons when i click one. Please help.

  10. How to “ul > li” items not top,i want to do float right so not horizontally, how do vertically?
    And how to “ul > li > ul > li” tree?