<

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x

Animated multi-level drop-down menus without Javascript

Published on
17,311 Points
4,311 Views
5 Endorsements
Last Modified:
Awarded

Lovely Animated Drop-down Menu - without javascript


We're going to be using CSS3 transitions to make the menus slide down gently, and the background colors fade softly in and out.

This is a barebones multi-level drop down menu made entirely in CSS, that plays nice in all browsers and degrades gracefully to regular CSS2 hover effects in IE.

We're also going to address a couple of typical layout challenges in IE.

The goal of this tutorial is to provide only the most fundamental code necessary for the implementation of the drop-down menu, which can then be used as a template for styling to your heart's content.

[We will not be using the usual display:none, display:block technique, so don't look for it]

Step 1.
Let's set up our html. We're going to put our menu inside a header, and we're also going to create a "content" area below the header.

A little explanation:
This part of the process addresses IE's stacking order, and will ensure that our menu doesn't render behind the Content area, an issue I have seen often. A typical scenario is to have some kind of image scroller under the header, which requires the scroller container to have relative positioning, and causing the menu to render behind the scroller in IE. In order to fix this, our Header MUST must have position:static.

<!DOCTYPE HTML>
<html lang="en">
<head>
<meta  charset="UTF-8" />
<title>CSS3 Horizontal sliding menu</title>
<style>
.header{
	width: 600px; 
	height:50px; 
	border:1px dotted grey;
}
.content{
	position:relative; 
	width: 600px; 
	height:500px; 
	color:white; 
	background-color: #e6056f; 
	overflow:hidden;
	}
.item{
	position:absolute; 
	top:50px; 
	left:20px; 
	width: 600px; 
	height:400px; 
	background-color: grey;
	}
</style>
<body>
    <div class="header">
        <div class="navigation">
        </div>
    </div>
    
    <div class="content">
    	<div class="item">
    	</div>
    </div>

</body>
</html>

Open in new window


Step 2.
We're going to use an unordered list to create the menu structure and place it inside the navigation div:
(make sure you replace the #'s with actual links, for example: <a href="#"> becomes <a href="mypage.html">)

            
<ul>
                <li><a href="#">Main - 1</a>
                    <ul>
                        <li><a href="#">Level 2 - 1</a></li>
                        <li><a href="#">Level 2 - 2</a></li>
                        <li><a href="#">Level 2 - 3</a></li>
                        <li><a href="#">Level 2 - 4</a></li>
                    </ul>
                </li>
                <li><a href="#">Main - 2</a>
                    <ul>
                        <li>
                            <ul>
                                <li><a href="#">Level 3 - 1</a></li>
                                <li><a href="#">Level 3 - 2</a></li>
                                <li><a href="#">Level 3 - 3</a></li>
                                <li><a href="#">Level 3 - 4</a></li>
                                <li><a href="#">Level 3 - 5</a></li>
                            </ul>
                            <a href="#">Level 2 - 1</a>
                        </li>
                        <li>
                            <ul>
                                <li><a href="#">Level 3 - 1</a></li>
                                <li><a href="#">Level 3 - 2</a></li>
                                <li><a href="#">Level 3 - 3</a></li>
                                <li><a href="#">Level 3 - 4</a></li>
                                <li><a href="#">Level 3 - 5</a></li>
                            </ul>
                            <a href="#">Level 2 - 2</a></li>
                        <li>
                            <ul>
                                <li><a href="#">Level 3 - 1</a></li>
                                <li><a href="#">Level 3 - 2</a></li>
                                <li><a href="#">Level 3 - 3</a></li>
                                <li><a href="#">Level 3 - 4</a></li>
                                <li><a href="#">Level 3 - 5</a></li>
                            </ul>
                            <a href="#">Level 2 - 3</a></li>
                        <li><a href="#">Level 2 - 4</a></li>
                    </ul>
                </li>
                <li><a href="#">Main - 3</a></li>
                <li><a href="#">Main - 4</a></li>
            </ul>

Open in new window


Step 3.
To position the menu horizontally we'll use float:left on the menu items and a couple of basic styles to make it presentable:

      
.navigation {
            width:600px;
        }
        .navigation ul{
        /* positioning */
        	position:relative;
            z-index:1000;
        /* remove the dots next to list items: */
            list-style:none; 
        /* get rid of any default or inherited margins and padding: */
            margin:0; 
            padding:0; 
            
        /* styling: */
            font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
            font-weight: normal;
            font-size: 15px;
        }
        
        /* we're using the direct descendant selectors > to ONLY affect the main menu items */
        .navigation > ul > li {
        /* positioning */ 
            position: relative;
            float: left;
        /* styling: */
            margin-right: 10px;
        }
        .navigation > ul > li > a {
        /* positioning */ 
            display:block;
        /* styling: */
            background-color: #2c2c2c; /*  grey */
            padding:8px 14px;
            text-decoration:none;
            color:#aaaaaa; 
            
        }
        .navigation > ul > li > a:hover{
        /* styling: */
            background-color:#666666; /* grey */
            color:#eeeeee; /* light grey */
        }

Open in new window

       
Step 4.
The drop-down boxes. We are going to apply the same styles to secondary and tertiary drop-downs, but you can choose to add additional styles to differentiate them.

       
.navigation ul ul{
            
            background-color:#e6056f; /* remove. this is for illustration purposes only */
            width:340px; /* you need a width to accommodate tertiary menus */
            
            position:absolute;
            z-index:100;
            
            height: 0;
            overflow: hidden;
        }
        

        /* don't display tertiary box yet */
        .navigation > ul > li:hover ul ul, .navigation > ul > li > a:hover ul ul{
            height:0;
            
        }
        /* tertiary drop-down box */
        .navigation ul ul ul{
            left:170px;
            width:170px;
        }
        
        .navigation > ul > li:hover ul, .navigation > ul > li > a:hover ul,
        .navigation ul ul li:hover > ul, .navigation ul ul li a:hover > ul{
            height:220px; /* need a height to accommodate any tertiary menus */
        }
        
        /* drop-down item styles */
        /* if you want different styling for tertiary menus, just copy the 4 rules below and insert an additional ul: for example: ".navigation ul ul li", becomes: ".navigation ul ul ul li" */
        
        .navigation ul ul li{
            background-color:#eaeaea; /* grey */
            width:170px;
        }
        
        .navigation ul ul li:hover {
            background-color:#999; /* grey */
        }
        
        .navigation ul ul li a {
            display:block;
            text-decoration:none;
            margin:0 12px;
            padding:5px 0;
            color:#4c4c4c; /* grey */
        }
        .navigation ul ul li a:hover, .navigation ul ul li:hover > a {
            color:#ffffff; /* white */
        }

Open in new window

       
Step 5 - optional
I like to have separator lines between menu items, but only BETWEEN menu items. And I don't want them to go all the way to the edges of the drop-down box either, which means more CSS tweaking, but I think it looks nicer.

Normally we could use :last-child to remove the last line in the list, but since IE doesn't recognize :last-child, we'll use the + selector instead. The following rules insert lines between each menu item, and make sure we don't have any extraneous unwanted lines either. It's a little hairy to get your head around at first, but it works across the board. And since the lines don't go all the way to the edges, it also makes sure there are no weird gaps when you hover over an item.

      
.navigation ul ul ul li a{
            border:0 !important;
        }
        .navigation ul ul ul li + li a{
            border-top:1px dotted #999 !important;
        }
        .navigation ul ul li + li a{
            border-top:1px dotted #999;
        }
        .navigation ul ul li:hover + li a{
            border-top:1px solid #eaeaea;
        }
        .navigation ul ul ul li:hover + li a{
            border: 0 !important;
        }
        .navigation ul ul ul li:hover + li{
            border-top:1px solid #999 !important;
        }

Open in new window

       
Step 6.
THE MAGIC


So by now you should have a plain vanilla CSS drop-down menu. Let's add the magic.
It's actually going to be really easy.

Add these properties to the .navigation ul ul rule:

          
-webkit-transition: height 0.3s ease-in;
            -moz-transition: height 0.3s ease-in;
            -o-transition: height 0.3s ease-in;
            -ms-transition: height 0.3s ease-in;
            transition: height 0.3s ease-in;

Open in new window


And these, to the .navigation ul ul li rule:

          
-webkit-transition: background-color 0.3s ease;
            -moz-transition: background-color 0.3s ease;
            -o-transition: background-color 0.3s ease;
            -ms-transition: background-color 0.3s ease;
            transition: background-color 0.3s ease;

Open in new window

   
Step 7.
Just one more thing if you care about IE 7.

To remove the gaps between menu items in IE 7, I'm going to add some conditional statements into the top of the file:

Replace these two lines
<!DOCTYPE HTML>
<html lang="en">

Open in new window

at the top of your file with this:
<!DOCTYPE HTML>
<!--[if lt IE 7 ]> <html class="ie6" lang="en"> <![endif]-->
<!--[if IE 7 ]>    <html class="ie7" lang="en"> <![endif]-->
<!--[if IE 8 ]>    <html class="ie8" lang="en"> <![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--> <html lang="en"> <!--<![endif]-->

Open in new window


and add this rule to the css:

/* unfortunate ie7 gap fix */
        .ie7 .navigation ul ul li{
            margin-bottom:-3px;
        }

Open in new window

 
That's it!

An optional enhancement:
I'm going to add a little arrow to the items that have tertiary menus:

make an arrow.png graphic, and add this rule to your css:
.arrow{background:url(arrow.png) right center no-repeat;}

Open in new window

 

add the arrow class to the links that have tertiary menus:
ie: <a href="#" class="arrow">Level 2 - 1</a>  

Also, you'll want to remove the background-color in .navigation ul ul. It was meant for illustration purposes only.

Enjoy!

The file is here for your perusal (view source):
CSS3-dropdown3.html
- or -
http://candpgeneration.com/CSS-dropdowns/CSS3-dropdown3.html
5
Comment
5 Comments
LVL 38

Expert Comment

by:lherrou
Nice idea! And it works in well in Firefox and Chrome, as well as IE.

I added a Yes vote :)
0
LVL 61

Expert Comment

by:mbizup
Nice article!  (Voted 'yes')
0
LVL 1

Expert Comment

by:Vee_Mod
Thank you for putting this together.
"Yes" vote above.
0
LVL 65

Expert Comment

by:RobSampson
Very nice article!  Thanks for your contribution!
0
LVL 7

Expert Comment

by:SvenIA
I like this article. Thanks for sharing this knowledge!
0

Featured Post

CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

Join & Write a Comment

In this tutorial viewers will learn how to define a gradient in CSS. Create a new HTML document with an internal stylesheet.: Create a div in CSS and name it Gradient. Define the background as "linear-gradient(to right, #ee3668, black)". Ensure you …
Learn how to create flexible layouts using relative units in CSS.  New relative units added in CSS3 include vw(viewports width), vh(viewports height), vmin(minimum of viewports height and width), and vmax (maximum of viewports height and width).
Next Article:

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month