From our sponsor: Ready to show your plugin skills? Enter the Penpot Plugins Contest (Nov 15-Dec 15) to win cash prizes!
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.
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="http://www.w3.org/2000/svg" version="1.1" width="600" height="400">
<defs>
<filter id="blur" x="0" y="0">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
</defs>
<rect x="50" y="50" width="500" height="300" fill="#8d81ac" filter="url(#blur)" />
</svg>
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="http://www.w3.org/2000/svg" version="1.1" width="600" height="400">
<defs>
<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" />
</filter>
</defs>
<rect width="500" height="300" fill="#8d81ac" filter="url(#dropshadow)" />
</svg>
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.
Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.
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){
$effectContainer.css({
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 SVG effects to HTML content
- Hands On: SVG Filter Effects
- Cross-browser filters with CSS and SVG
- Smarter SVG filters
- How to go beyond the basics 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>
</button>
<div class="menu-item-bounce"></div>
</li>
<li class="menu-item">
<button class="menu-item-button">
<i class="menu-item-icon icon icon-box"></i>
</button>
<div class="menu-item-bounce"></div>
</li>
<li class="menu-item">
<button class="menu-item-button">
<i class="menu-item-icon icon icon-trash"></i>
</button>
<div class="menu-item-bounce"></div>
</li>
</ul>
<button class="menu-toggle-button">
<i class="fa fa-plus menu-toggle-icon"></i>
</button>
</div>
</div>
We also define the filter inside an SVG object which we will place in our HTML:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<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"/>
</filter>
</defs>
</svg>
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.
Examples
The following demos will show some creative ways of using Gooey effects on all kinds of components:
We hope you find these examples inspiring!
This is Super Amazing
Thank you for this awesome article. You guys always make the most creative demos
Esto es asombroso!!! Lucas, felicitaciones y gracias!!
awesome !!! Lucas, thank you!!
just made me to finally comment here, you guys are so amazing and creative. Love all of your work. Simply Awesome!!
Trally amazing one in here. clap clap clap
Was so amazing I forgot how to write
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.
Muito bom Lucas 🙂
Perfeito.
amazing first post!! i just can’t wait for another post yours! GOOD WORK!!!!
wow.. super awesome tutorial…
Haha! Damn, it’s crazy!
Thanks for sharing this so COOL EFFECTS!!!
That was one of the greatest things I’ve ever seen.
Awesome as always 😀
This is really awesome!
Really awesome!
Brilliant!
Love Chat Application so cool
The ultimate remarkably. Thank
Dat is awesome and so liquid! Marvellous effects buddy. =)
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?
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.
Love it, such an awesome effect and you’ve made it quite simple how to achieve it!
This is Super Amazing
AWESOME! Seeing these effects makes me more confident to say, SVG is the future of UX and UI.
would be great to find out which browsers are compatible with those effects. or if we can start using them today.
As linked in the article http://caniuse.com/#feat=svg-html
this’s great!!
Thanks so much for sharing all this. Your chat app is completely mind blowing, svg microanimation is the future of elegant ux.
We can’t ignore the effect of gooey SVG filter, SVG filters are quite powerful.
This is really awesome
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 : http://codepen.io/akinorikul/pen/zxejJM
This problem doesn’t happen on your examples and I don’t understand why, any help would be greatly appreciated.
Any thoughts about my problem ?
Really impressing, awesome!
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?
Great dude!
This is really impressive!
Super RAD, awesome and lovely!
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.
Thanks
Very impressive. I like it. Keep it up.
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.
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?
HI, great tutorial!
I’m having an issue where the animation is rendering really slow and I cant figure out why. If you have time, here is a link to the site i’m using this feature with.
http://ranelson.970design.com/lake-creek-custom-home/
Any help is greatly appreciated!
thanks
Me Encanta !!! (Adoro)
AMAZING GOOD WORK
How I can make that chat like demo for website.
What kind of libraries you have used?
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.
I made this live player based of this. 🙂 http://codepen.io/enjikaka/full/BNqgVx/
Some of these examples doesn’t work with firefox at this moment.
Sorry, my bad it does work.
I had a missing js.