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:
#top{position: relative;z-index: 2;#top li li, #top li li a{height:0px;margin-top: -10px;text-align: center;color: rgba(255,255,255,.0);text-decoration: none;-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:
#top li:hover li{height:30px;margin-top:5px; margin-bottom: 5px;}- .
#top li li:first-of-type{padding-top: 15px;}- .
#top li:hover li a{color: rgba(255,102,0,.8);}- .
#top li li a:hover{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.
section{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.