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.

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 in the loop: Get your dose of frontend twice a week

👾 Hey! Looking for the latest in frontend? Twice a week, we'll deliver the freshest frontend news, website inspo, cool code demos, videos and UI animations right to your inbox.

Zero fluff, all quality, to make your Mondays and Thursdays more creative!

Feedback 48

Comments are closed.
  1. Thank you for this awesome article. You guys always make the most creative demos

  2. Esto es asombroso!!! Lucas, felicitaciones y gracias!!
    awesome !!! Lucas, thank you!!

  3. just made me to finally comment here, you guys are so amazing and creative. Love all of your work. Simply Awesome!!

  4. there´s any way to create a set of answers on the chat example and randomly show them to the viewer?
    I mean, instead of select from a single sentence (var ipsum), I´d like to set some answer blocks.

  5. amazing first post!! i just can’t wait for another post yours! GOOD WORK!!!!

  6. Great article and demos, Lucas!
    I found a bug using Google Chrome on GNU/Linux (no matter what distribution, by now it is the same on Ubuntu and OpenSUSE) that causes the animation flicker with white background. It is so annoying. I cannot reproduce on other devices (not Google Chrome on OSX or Android neither Firefox on GNU/Linux). Is it a known issue using SVG filters on Google Chrome? Do anyone know another issues with this filters?

  7. This is very cool – but nothing in the article about how you achieved the animations. This turns out to be by using Greensock TweenMax. But perhaps there should at least be something about how this was achieved too.

  8. Love it, such an awesome effect and you’ve made it quite simple how to achieve it!

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

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

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

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

  13. 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.

  14. 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?

  15. 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.


  16. 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.

  17. 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?

  18. Que buenas cosas, elementos ayudas, guías, etc. eh encontrado en esta página, estoy empezando en esto de la programación y la verdad que me apasiona mucho. Muchas gracias Lucas estuve viendo su página es increible, le mando un fuerte abrazo desde Arg.