Pure CSS3 Animated Dropdown Navigation

nav-thumb

As you probably already know, CSS3 introduces many new features, one of which is the ability to create animated transitions using nothing but CSS. You've seen this used for many different things, from animated buttons, to accordions menus, to some fun CSS experiments.

One common technique that is completely doable with CSS, but which still remains in the realm of jQuery and other Javascript techniques, is animated dropdown menus.

For an example of what we will be making, you can see the demo.

Create the HTML

We can start by creating a simple unordered list, however because of the way this menu works, the structure must be a bit different from your standard navigation hierarchy. For this to work, the parent of a sub-menu should be its first item.

<div id="nav-wrapper">
    <ul id="nav">
        <li><a href="#">Home</a></li>
        <li>
            <ul class="subnav">
                <li><a href="#">Parent</a></li>
                <li><a href="#">Child 1</a></li>
                <li><a href="#">Child 2</a></li>
            </ul>
        </li>
        <li>
            <ul class="subnav">
                <li><a href="#">Parent 2</a></li>
                <li><a href="#">Child 3</a></li>
                <li><a href="#">Child 4</a></li>
            </ul>
        </li>
    </ul>
</div>

Style it With CSS

#nav-wrapper {
    position: relative;
 
    height: 40px;
    width: 700px;
 
    background: url('nav-bg.png') top left repeat-x;
    border: 1px solid #ccc;
 
    border-radius: 6px;
    -webkit-border-radius: 6px;
    -moz-border-radius: 6px;
}
 
ul {
    height: 30px;
    margin: 0; padding: 0;
    position: absolute;
}
 
ul li {
    line-height: 30px;
    float: left;
    list-style-type: none;
    margin: 0; padding: 0;
    font-size: 18px;
}
 
ul li a {
    display: block;
    height: 30px;
    padding: 5px 10px;
}
 
#nav a, #nav a:link, #nav a:visited {
    color: #555;
    text-decoration: none;
}

Here I used a simple gradient image for the menu background. You could also take this a step further and use CSS3 gradients for the background, instead of having to use an image. But that's a subject for another tutorial.

This will style the top level of the navigation hierarchy, making it look something like this:

It still doesn't look to great yet, because we haven't applied any styles to the sub-menus yet.

.subnav {
    height: 40px;
    overflow: hidden;
 
    z-index: 9999;
    margin: 0; padding: 0;
}
 
.subnav:hover {
    height: 120px;
}
 
.subnav li {
    clear: left;
    height: 30px;
    z-index: 9999;
    background: #ddd;
    width: 100%;
    height: 25px;
    font-size: 14px;
    line-height: 20px;
}
 
.subnav li:first-child {
    clear: none;
    background: transparent;
    margin: 0 0 11px 0;
    font-size: 18px;
    line-height: 30px;
    height: 30px;
}
 
.subnav li:first-child a {
    padding: 5px 10px;
}
 
.subnav li a {
    height: 15px;
    padding: 5px;
}
 
.subnav li:last-child {
    border-radius: 0 0 5px 5px;
    -webkit-border-radius: 0 0 5px 5px;
    -moz-border-radius: 0 0 5px 5px;
    overflow: hidden;
}

I won't go into detail about what each individual property does, so I'll just cover some of the more important ones.

Basically, this CSS sets the height of each .subnav to the same height as the main menu bar, cutting off the rest below it. The first item of each sub-menu is then styled to match the top-level items, so that nobody can tell the difference.

At this point, hovering over a parent item should cause its children to display below it. This is how slightly older browsers which do not yet suport CSS3 transitions should display the navigation menu.

Apply the Transitions

Now to make this menu about a million times more awesome. To create a smooth transition between the two states, the following properties can be added to .subnav:

.subnav {
    transition: height 0.2s linear;
    -webkit-transition: height 0.2s linear;
    -moz-transition: height 0.2s linear;
    -o-transition: height 0.2s linear;
}

The first value for transition is the property to be animated, in this case it's height. Next is the duration of the animation in seconds. The third value is the timing function for the animation. linear creates a smooth, even transition between both states. ease is another good one you might want to try.

The transition property is repeated with the same values for each different browser that supports it.

Here is a demo of the final CSS3 animated dropdown navigation menu.

Well there you have it, a pure CSS animated dropdown menu. The best thing about this method is that if your users don't have a browser that supports CSS3 transitions, they can still use your navigation menu perfectly fine, as opposed to many Javascript-based techniques.

What would you add to this navigation menu? Maybe support for multiple levels, or maybe use fancier animations? Leave your answer in the comments.

Stay Updated

Did you enjoy this post? Don't miss a single post by getting free updates!

9 Comments

  1. October 22, 2010

    Ahh, but what about sub-sub-nav menus? You know like when you go to a sub-menu and each option could have even more links.

    Good Tutorial, plan on using this in my projects because all my other resources for finding a sub-menu tutorial are horrible.

    • October 22, 2010

      This could be done, probably by giving each menu a similar structure to the top-level menu and applying new styles to the sub-menus.

  2. Smenzo
    November 9, 2010

    I think I found 2 potential issues

    1) If the child item has a long name it pads out the parent item to the same width so you look like you have big gaps in the parent menu.

    Parent
    Child With Long Name 1
    Child 2
    Child 3

    2) This technique does not seem to work if there are more than 3 child items in the sub menu.

    Modify menu to have 5 or 6 child items - only the first 3 child items are visible.

    Parent
    Child 1
    Child 2
    Child 3
    Child 4
    Child 5

    Any ideas?

    • November 15, 2010

      You probably need to increase the height of subnav:hover, in order for the other child elements to display properly.

      Sorry about the delay in approving your comment, for some reason I've stopped receiving email notifications.

    • jooraqu
      April 18, 2011

      "1) If the child item has a long name it pads out the parent item to the same width so you look like you have big gaps in the parent menu."

      Take a look at the code: http://www.toplnx.pl/pages/ubumatic_en.html

      Now you know how to do it.

  3. November 17, 2010

    Nice article, easy to implement such a menu!

  4. November 25, 2010

    I'd add some hover effect to subnav lists, to add more interaction to the users. Anyways the tutorial is simply great!

    Cheers!

  5. December 25, 2010

    I think I found 2 potential issues 1) If the child item has a long name it pads out the parent item to the same width so you look like you have big gaps in the parent menu. Parent Child With Long Name 1 Child 2 Child 3 2) This technique does not seem to work if there are more than 3 child items in the sub menu. Modify menu to have 5 or 6 child items - only the first 3 child items are visible. Parent Child 1 Child 2 Child 3 Child 4 Child 5 Any ideas?

Trackbacks/Pingbacks