Implementing a Drop-Down menu using CSS

CSS3 allows developers to implement a variety of visual and interactive functions most of us would previously have turned to JavaScript for.

In this tutorial we will implement a drop-down menu, with background images featuring a gradient and rounded corners, all defined purely in CSS3 code. Our list will be structured using embedded lists in the HTML code, with top-level menu options appearing above their sub-menus, which we will display when users hover the mouse over the top level item.


Use the following HTML5 structure for your page:

<!DOCTYPE html> <html><head><style type="text/css"> </style></head><body> </body></html>

We will use the style section in the head to implement the drop-down menu, with no need for JavaScript code or custom-made image files.


The menu is going to comprise top level items modeled as a list, with additional sub-menu lists embedded into these top level list items. Our menu only contains two levels, but you could of course extend it to provide additional levels of embedding. If you do implement more menu levels, you will need to alter your style code to display the additional lists.

To start with, add your top level items as follows:

<ul id="main_menu"> <li class="top_menu"> <a href="#">Products</a> </li><li class="top_menu"> <a href="#">Services</a> </li> <li class="top_menu"> <a href="#">Information</a> </li></ul>

These are the top-level items, which we have given arbitrary headings – feel free to choose your own. We have not included full “href” attributes but you will need to add the URLs you want each item to link to. Inside each list item, after the anchor tag, add a sub-menu with the following structure:

<ul> <li><a href="#">Clothing</a></li> <li><a href="#">Furniture</a></li> <li><a href="#">Toys</a></li></ul>

Your full menu markup should now look something like this:

<ul id="main_menu"> <li class="top_menu"> <a href="#">Products</a> <ul> <li><a href="#">Clothing</a></li> <li><a href="#">Furniture</a></li> <li><a href="#">Toys</a></li> </ul></li><li class="top_menu"> <a href="#">Services</a> <ul> <li><a href="#">Catering</a></li> <li><a href="#">Advice</a></li> <li><a href="#">Events</a></li> <li><a href="#">Other</a></li> </ul> </li> <li class="top_menu"> <a href="#">Information</a> <ul> <li><a href="#">About</a></li> <li><a href="#">Contact</a></li> </ul></li></ul>

The top menu list and list items have ID and class attributes for reference within the CSS code.


Let’s start styling the menu. Add the following declarations to your style section, for the menu area as a whole, as well as the links within it:

/*general menu background*/#main_menu, #main_menu a, #main_menu a:hover { background-color: #990066; background-image: -webkit-linear-gradient(top, #990066, #cc0099, #990066); background-image: -moz-linear-gradient(top, #990066, #cc0099, #990066); background-image: -ms-linear-gradient(top, #990066, #cc0099, #990066); background-image: -o-linear-gradient(top, #990066, #cc0099, #990066); }

Here we are using a gradient background, which you can of course alter to suit your needs. The gradient uses vendor-prefixes to target particular browsers and is not yet fully supported, with particularly low support in Internet Explorer (although this does look set to change in IE 10). We set a background-color property for browsers with no gradient support. Next let’s style the top menu area:

/*container list*/#main_menu { font-family:sans-serif; list-style-type:none; text-align:center; float:left; width:90%; border-radius:5px; box-shadow: 3px 3px 2px #888888; }

Here we set generic properties for the entire menu. We also use a box shadow for the top menu bar, defined using the horizontal and vertical positions, blur level and color. We also give the top menu bar rounded corners, which we define by specifying the radius.

Lots of our CSS code is going to apply to multiple lists and list items at both top and sub levels. However, let’s use the class attribute to target the top level only here:

/*top list items*/.top_menu { float:left; position:relative; border-right:1px solid #ff00cc; border-left:1px solid #ff00cc; margin-left:-1px; }

We use borders to define the sections within the menu and make the position relative, which will allow us to place the sub-menu underneath. Let’s now style the menu links:

/*anchors*/#main_menu a, #main_menu a:hover { color:#ffffff; display:block; padding:5px; text-decoration:none; width:150px; border-top-right-radius:2px; border-top-left-radius:2px; border-bottom-right-radius:10px; border-bottom-left-radius:10px; }

This styling will apply to all menu items in the list, at both levels. However, because the top level items appear on top of the same gradient that is used behind them, the rounded corners will not appear. If you want your sub-menu items to be styled differently to the top-level items, you need to target each specifically. For these style declarations, we can apply the effects to the anchors at both levels.

Now we can stop the sub-menu lists from appearing by default, by targeting the lower level lists:

/*sub menu list*/#main_menu ul { list-style:none; position:absolute; display:none; }

The absolute position property makes sure the sub-menus appear below the top menu. When the user first visits the page, they will see the top menu items only. When they hover over a top-level item, the sub-menu list for that item will appear:

/*sub menu when hover on top item*/#main_menu li:hover ul { display:block; }

Let’s now position the menus so that each sub-menu drops down directly under its parent item and with a little space between the sub-items:

/*sub menu list items*/#main_menu ul li { padding-top:1px; margin-left:-25%; }

Finally, let’s make the sub-level items appear initially with a different text color and with a box shadow: