Making an animated radial menu with CSS3 and JavaScript



Today, let’s look at how we can easily make a simple animated radial menu with CSS3 and JavaScript.

Have a look at the demo below and click the button for the radial menu to pop out.

The code is readily available in the codepen demo above, so let’s go over some of the specifics.

The HTML

Let’s look at the HTML. We will be using the HTML5 nav element with some links inside of it and the button to activate the radial menu.

<nav class="circular-menu">

  <div class="circle">
    <a href="" class="fa fa-home fa-2x"></a>
    <a href="" class="fa fa-facebook fa-2x"></a>
    <a href="" class="fa fa-twitter fa-2x"></a>
    <a href="" class="fa fa-linkedin fa-2x"></a>
    <a href="" class="fa fa-github fa-2x"></a>
    <a href="" class="fa fa-rss fa-2x"></a>
    <a href="" class="fa fa-pinterest fa-2x"></a>
    <a href="" class="fa fa-asterisk fa-2x"></a>
  </div>

  <a href="" class="menu-button fa fa-bars fa-2x"></a>

</nav>

I have also used Font Awesome icons and added the necessary classes to the a-tag to get some nice icons for the menu items in the radial menu.

The CSS

So let’s look at some of the CSS here. First we define a width and height for our radial menu’s root container (in this case the nav element with the circular-menu class. We also define the position property as relative so that we can position other items relatively.

.circular-menu {
  width: 250px;
  height: 250px;
  margin: 50px auto 0;
  position: relative;
}

By default the menu items will be hidden. We want a nice fade + zoom effect so we will start the menu items out at 0 opacity and also set the scale to 0 with the transform property.

.circle {
  width: 250px;
  height: 250px;
  opacity: 0;

  -webkit-transform: scale(0);
  -moz-transform: scale(0);
  -transform: scale(0);

  -webkit-transition: all 0.4s ease-out;
  -moz-transition: all 0.4s ease-out;
  transition: all 0.4s ease-out;
}

You can also see that we have defined the animation with the transition property.

To make the menu items zoom and fade in, we want to toggle it between classes. So let’s define an open class for the radial menu.

.open.circle {
  opacity: 1;

  -webkit-transform: scale(1);
  -moz-transform: scale(1);
  -transform: scale(1);
}

So, once the open class is put on the same element as the circle class, it will apply the new properties according to the animation length and type defined by the transition property.



The a elements within the circle class still need to be styled of course. Alongside some general styling for the size it is important that we set the position to absolute for the JavaScript to be able to position the menu items in the radial menu.

.circle a {
  text-decoration: none;
  color: white;
  display: block;
  height: 40px;
  width: 40px;
  line-height: 40px;
  margin-left: -20px;
  margin-top: -20px;
  position: absolute;
  text-align: center;

}

.circle a:hover {
  color: #eef;
}

And of course we need to position and style our menu toggle button.

.menu-button {
  position: absolute;
  top: calc(50% - 30px);
  left: calc(50% - 30px);
  text-decoration: none;
  text-align: center;
  color: #444;
  border-radius: 50%;
  display: block;
  height: 40px;
  width: 40px;
  line-height: 40px;
  padding: 10px;
  background: #dde;
}

.menu-button:hover {
  background-color: #eef;
}

Now let’s move on to the final part, the part which makes our menu a real radial menu!

The JavaScript

First, let’s make our menu toggle button show and hide our menu items.

document.querySelector('.menu-button').onclick = function(e) {
   e.preventDefault(); document.querySelector('.circle').classList.toggle('open');
}

This will select the element with menu-button for class and listen for a click event. Once you click it it will take the element with the circle class and add the open class to it.

Now the last thing on the list is the positioning.

var items = document.querySelectorAll('.circle a');

for(var i = 0, l = items.length; i < l; i++) {
  items[i].style.left = (50 - 35*Math.cos(-0.5 * Math.PI - 2*(1/l)*i*Math.PI)).toFixed(4) + "%";
  items[i].style.top = (50 + 35*Math.sin(-0.5 * Math.PI - 2*(1/l)*i*Math.PI)).toFixed(4) + "%";
}

What this code does is select all the links within the element with the circle class. You can then loop through these items.

We then use the iterator (i) to calculate the CSS top and left property with some basic geometry, using the sine and the cosine.

Using JavaScript to position the elements allows you to use any number of child a elements in your menu and the JavaScript math magic will do the rest!

That’s it!

I hope this will help you make a cool radial menu. If you made something awesome, feel free to share it in the comments! If you liked this tutorial be sure to like it and share it on your favorite social media!

Share the knowledge!
Share on Facebook0Tweet about this on Twitter0Share on Google+0Share on StumbleUpon116Share on Reddit29Share on LinkedIn20Share on TumblrBuffer this pageDigg this

Comments

You may also like...

Stay updated
Subscribe!