Elastic SVG Elements

Some inspiration for elastic components with SVG shape animations for enhanced UI interactions.
Morphing Shape Effects

From our sponsor: Ship fast and never break a thing with Shortcut (formerly Clubhouse.io).

Today we’d like to share some inspiration for adding elasticity to elements. The idea is to integrate an SVG element into a component and then animate it from one path to another with an elastic animation. Using SVGs like this can make things like menus, buttons or other elements more interesting and make the interaction look more organic with a natural feel to it. It’s of course important to keep things subtle and not exaggerate the bounciness. The nice thing is that we can give a more “realistic” interaction feedback to the user. Especially touch feedback can benefit from using this kind of effect. Based on this idea, we’ve created some inspirational examples of contexts where a morphing shape animation enhancement could make sense.

For animating the SVGs, we use Snap.svg, the excellent JavaScript SVG library for modern browsers.

The icons used in some of the demos are from the one and only Font Awesome icon set by Dave Gandy.

For the demo with the draggable & droppable elements we use Dragabilly by David DeSandro.

Please note that this is highly experimental and the demos were only tested in the latest versions of modern browsers.

An example of how we use the SVGs in the components (the sidebar menu in this case) is the following:

<nav id="menu" class="menu">
	<button class="menu__handle"><span>Menu</span></button>
	<div class="menu__inner">
			<li><a href="#"><i class="fa fa-fw fa-home"></i><span>Home<span></a></li>
			<li><a href="#"><i class="fa fa-fw fa-heart"></i><span>Favs<span></a></li>
			<li><a href="#"><i class="fa fa-fw fa-folder"></i><span>Files<span></a></li>
			<li><a href="#"><i class="fa fa-fw fa-tachometer"></i><span>Stats<span></a></li>
	<div class="morph-shape" data-morph-open="M300-10c0,0,295,164,295,410c0,232-295,410-295,410" data-morph-close="M300-10C300-10,5,154,5,400c0,232,295,410,295,410">
		<svg width="100%" height="100%" viewBox="0 0 600 800" preserveAspectRatio="none">
			<path fill="none" d="M300-10c0,0,0,164,0,410c0,232,0,410,0,410"/>

The SVG is inserted after the inner menu and we use two data attributes to store the paths we will be animating the default path to (depending on whether we open or close the menu).

The SVG will be placed absolute into the menu, and enough spacing needs to be ensured on the sides so that we see the line moving elastically without getting cut off. Note that the SVGs are made responsive by using a width and height of 100% and not preserving the aspect ratio. This is important for some shapes as you might want to retain certain proportions and allow a stretching in one dimension only. For this example, although we always set the width and height to 100% in the HTML, we set a fixed width to the morph shape wrapper and the SVG:

.morph-shape {
	position: absolute;
	width: 240px;
	height: 100%;
	top: 0;
	right: 0;

.morph-shape svg path {
	stroke: #5f656f;
	stroke-width: 5px;

With Snap.svg we can then morph from one shape to another:

(function() {

	function SVGMenu( el, options ) {
		this.el = el;

	SVGMenu.prototype.init = function() {
		this.trigger = this.el.querySelector( 'button.menu__handle' );
		this.shapeEl = this.el.querySelector( 'div.morph-shape' );

		var s = Snap( this.shapeEl.querySelector( 'svg' ) );
		this.pathEl = s.select( 'path' );
		this.paths = {
			reset : this.pathEl.attr( 'd' ),
			open : this.shapeEl.getAttribute( 'data-morph-open' ),
			close : this.shapeEl.getAttribute( 'data-morph-close' )

		this.isOpen = false;


	SVGMenu.prototype.initEvents = function() {
		this.trigger.addEventListener( 'click', this.toggle.bind(this) );

	SVGMenu.prototype.toggle = function() {
		var self = this;

		if( this.isOpen ) {
			classie.remove( self.el, 'menu--anim' );
			setTimeout( function() { classie.remove( self.el, 'menu--open' );	}, 250 );
		else {
			classie.add( self.el, 'menu--anim' );
			setTimeout( function() { classie.add( self.el, 'menu--open' );	}, 250 );
		this.pathEl.stop().animate( { 'path' : this.isOpen ? this.paths.close : this.paths.open }, 350, mina.easeout, function() {
			self.pathEl.stop().animate( { 'path' : self.paths.reset }, 800, mina.elastic );
		} );
		this.isOpen = !this.isOpen;

	new SVGMenu( document.getElementById( 'menu' ) );


With the right easing functions and appropriate timings, a slightly bouncy, organic movement can be created. But the options are so versatile and depend on the whole feel of a specific context, so the possibilities are endless 🙂

We hope you enjoy these little effects and find them inspiring!

Tagged with:

Mary Lou

ML is a freelance web designer and developer with a passion for interaction design. She studied Cognitive Science and Computational Logic and has a weakness for the smell of freshly ground peppercorns.


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

Feedback 38

Comments are closed.
  1. Which parameter is responsible for the displacement of the cross and the line to the right?

    • Hi Douglas, you need to remove the following lines:
      // For Demo purposes only [].slice.call( this.el.querySelectorAll('a') ).forEach( function(el) { el.onclick = function() { return false; } } );

      Hope it helps! Cheers.

  2. Hi there , Can anyone please tell me how can i use just the sidebar effect in my site or in any site ? i have been trying for so long its been 3hours but i get able to use just the sidebar by selecting just the needed codes but im having a problem which is the close tag i mean ( the button to close the side bar cross logo) the background of it doesn’t get transparent i have tried a lot but as this thing is made with codes not an image that’s why maybe but guys please can anyone arrange it for me please or can i use a icon [png] here as a button svg animated icon?

  3. How did you come up with the initial paths? For example in the circular menu example, you have:



    • I’m wondering the same. Being able to control the elatic effects more precisely would be nice, but after fucking around with those path values I can’t figure out the formula for them.

  4. I am trying to use the pull up menu as a drop down menu on my site. It looks ok right now but because of how the original svg is created (and because I have no idea how to modify them) the height of the SVG is massive and covers up content as we start scrolling down. I’ve tried modifying the height but that actually makes the SVG smaller for some reason. I could really use some advice.

  5. Hi,

    How to combine circular menu and sidebar on the same page.
    I try it but there is a problem because of same classes names,
    Real mess, but great effect


  6. Hi,

    i’m using a combination of Hamburger and dropdown – everything wirks fine, but the browser (FF, Chrome) does not open the link of the menu inside the dropdown.

    I went back a fe steps an could find the effect even in your Dropdown-Sample.
    All links ther are “#” but just try to link toa real site (e.g. http://www.google.com) -> the link is shown in status bar but does not open.

    Trying to play with pointer events on some levels of the stack didn’t worked.

    My Testsite with menu (top-right):

  7. Thanks for those ! 🙂

    For drop-down menu, what is the best pratice if we want to add several menus ? How do we get element ? by class ?


  8. Salut: Mary lou
    Merci de votre excelent travail.
    je suis entrain de creer mon site svt en HTML5 CSS3,priere de me donner aide pour appliquer quelques technique afin de donner une activite a mes sections surtout celles des exercices.
    je te demande le styles qui est appliquees dans les pages des exercices de ce site:

  9. hi iam trying to use pull up men u but want to use it in reverse as it should be pull doen but not able to do it please help

  10. Nice tutorial.

    Is posible to do a drop-up menú based on drop-down menú.