Josh Vogt

toronto based web developer and fan of css. visit my homepage.

Jan 29

CSS3 Animated Drop Down Menu

View the demo HERE.

I just finished Dan Cederholm’s CSS3 For Web Designers (go buy it!) the other day and finally felt like I had a proper understanding of how to work with the new tools available in CSS3. So I thought I’d take a stab at creating a drop down menu using CSS3 transitions. This animated menu does not require JavaScript.

I started with plain old nested lists with id=”top” on the <nav> element and class=”toplink” on each parent list item. I think I could probably do away with both in the future. (I’d post the code but tumblr won’t let me without formatting it and I don’t feel like figuring out why so just view the source).

Obviously, the html wasn’t the hard part, that’d be for the CSS. I’m just going to post the pertinent parts:

  1. #top{
  2. position: relative;
  3. z-index: 2;
  4. #top li li, #top li li a{
  5. height:0px;
  6. margin-top: -10px;
  7. text-align: center;
  8. color: rgba(255,255,255,.0);
  9. text-decoration: none;
  10. -webkit-transition:all .7s ease-in-out;

The first step to get this working is to hide the sub-menus and add the transition (the full CSS has extra lines for each vendor prefix where required). Usually when making a CSS drop down, people will put display:none on the sub-menu to hide them until invoked with the :hover state but CSS3 transitions don’t work when moving between display:none and display:block so that wasn’t going to do me any good. Instead, I set the height to 0px to collapse the list items, added a negative margin to push it up to the same level as the parent menu and used rgba colour with the alpha set to 0 to dissolve the text. Thinking about it now, the same results could probably be achieved using z-index instead but I didn’t try that yet.

So now I have a horizontal menu with a bunch of hidden sub-menus that I want to animate:

  1. #top li:hover li{
  2. height:30px;
  3. margin-top:5px; margin-bottom: 5px;}
  4. .
  5. #top li li:first-of-type{
  6. padding-top: 15px;}
  7. .
  8. #top li:hover li a{
  9. color: rgba(255,102,0,.8);}
  10. .
  11. #top li li a:hover{
  12. color:#333;

The first part adds some height back to the sub-menu list items and adds a bit of margin to the top and bottom. Both height and margins are animated by CSS transitions so I start getting the effect I’m looking for. The second part uses the first-of-type pseudo-class to push the sub-menu below it’s parent element. This step isn’t necessary, I just thought it looked a bit goofy when the sub-menu links were partially in the horizontal nav bar.

The #top li:hover li a selector keeps the text colour of the sub-menu transparent until the parent menu is hovered over. Once it’s hovered, the CSS transition turns the colour of the sub-menu links orange while the menu scrolls down. The last selector is just for the hover state of the sub-menu links. Again, changes to text colour are still transitioned by the initial transition above. I initially just added a text-shadow on the hover but it turned out to be a bit ostentatious and there was a noticeable lag on the transition animation so it was axed in favour of grey.

  1. section{
  2. position: absolute; z-index: 1;

Don’t forget to add the above code to the content section of  the page otherwise the sub-menu will push your content down when it expands.

The animated demo works in Safari, Chrome and Firefox 4 beta and Opera. The menu degrades gracefully, so Internet Explorer and Firefox 3.6 users still get a functional menu.

You can view the demo HERE.


  1. poussette-canne reblogged this from vogtjosh
  2. mon-galaxy-s3 reblogged this from vogtjosh
  3. dojinbar0826 reblogged this from vogtjosh
  4. vogtjosh posted this