Dead Simple Dropdown Menu

If you're just starting out in web work, chances are you'll be asked to design a site with a drop-down menu. I spent a while perfecting my preferred method, and now young Skywalker, share it with you I will.

First things first—I've noticed many folks try to pull off navigation using something other than an unordered list. Personally, I don't think that it's the greatest idea from an accessibility standpoint, but to each their own. My prefered method is with an unordered list. Deal with it.

Let's start with the basic markup.

<div class="fancy_dropdown_menu">
      <li><a href="page1.html">Link 1</a>
         <ul id="the_dropdown_part"><!-- Here's your dropdown! -->
            <li><a href="page5.html">Link 5</a></li>
            <li><a href="page6.html">Link 6</a></li>
            <li><a href="page7.html">Link 7</a></li>
      <li><a href="page2.html">Link 2</a></li>
      <li><a href="page3.html">Link 3</a></li>
      <li><a href="page4.html">Link 4</a></li>
<p>Here's your page content</p>

See the Pen 2ea21ff244dc5c780a97b924e89382f9 by Jesse Couch (@designcouch) on CodePen.

That looks nice. Now, for a basic understanding of what you're looking at. The unordered list is basically a parent/child system so that we can apply the CSS that we're about to write to whichever levels of the list that we want. In this case, the first level will be our main navigation, and the second level will be our fancy-schmancy drop-down.

What's that? You're ready to start hammering out some drool-worth CSS? Calm down now. Here we go. First, we're going to use the universal selector (*) to remove the default margin and padding from all elements, and apply two cool CSS3 properties: box-sizing and transition.

Box-sizing:border-box allows us to include the padding of our elements in the declared width. Previous to this property being introduced, adding padding to an element with 100% width would cause it to overflow its container. Using this technique, the padding is included in the declared width, without causing the element to overflow its container. Neat!

Transition is some of the new eye-candy available in CSS3 and simply allows an element to 'transition' (appropriate title!) from one state to another. In our menu's case, the background colors and height will be using it.

Of course, since these are not completely supported yet, it's important to use your vendor prefixes.

* {
   box-sizing: border-box; /* includes padding in the declared width */
   -webkit-box-sizing: border-box;
   -moz-box-sizing: border-box;
   -o-box-sizing: border-box;
   transition: all .25s ease-in-out; /* Fancy CSS3 Transitions!!! */
   -webkit-transition: all .25s ease-in-out;
   -moz-transition: all .25s ease-in-out;
   -o-transition: all .25s ease-in-out;
   margin: 0;
   padding: 0;

.fancy_dropdown_menu {
   margin:50px auto;

See the Pen c885571d3dfa79d5f2e18fc323bc3c91 by Jesse Couch (@designcouch) on CodePen.

Now we're going to give our main menu items some style, and hide the drop-down menu. First off, we want to give our individual menu items some breathing room, so we give the anchors 20px of padding. Let's also strip out that stupid default anchor underline with text-decoration:none and center the text for visual appeal. An important thing to remember when styling menu anchors is that you should probably make them block elements using display:block, or they may misbehave.

Another significant thing to note: a lot of tutorials will have you use display:none to hide the drop-down. I choose not to do this as it makes the menu less accessible. Instead, I set the max-height of the drop-down to 0 and use overflow:hidden.

.fancy_dropdown_menu a { 
   text-decoration: none;
   text-align: center;
   color:white; /* applying hardly any visual styling to the anchors makes sure that the hover states work in all cases */

.fancy_dropdown_menu ul {
   list-style-type:none; /* removes the bullets */
   overflow:visible; /* makes sure the dropdown can be seen */

.fancy_dropdown_menu > ul > li {
   border-right:1px solid white;

.fancy_dropdown_menu > ul > li > ul {
   max-height: 0; /* hides the drop-down menu */
   overflow: hidden; /* I use this method instead of display:none for accessibility, and you can also do some fun :hover stuff with CSS3 animations. */

.fancy_dropdown_menu > ul > li:hover {
   background: black;

See the Pen 426883d8cc5282805e134df5abe71beb by Jesse Couch (@designcouch) on CodePen.

Woohoo! We're almost there. Now all we have to do is make the drop-down appear when you hover over its parent (and give it some style).

.fancy_dropdown_menu > ul > li:hover ul {
   max-height:1000px; /* shows the drop-down when you hover over its parent. Unless this is a massively long menu, 1000px should cover it. */

.fancy_dropdown_menu > ul > li > ul > li {
   background: red;

.fancy_dropdown_menu > ul > li > ul > li:hover {
   background: orange;

See the Pen 440dc9b811a1d9c7761f2c8496c529dd by Jesse Couch (@designcouch) on CodePen.

That was freaking awesome. I love this stuff! Hope I was able to help you all out with a basic concept. Now go forth and create your own. Oh - and you can check out the demo below. demo

See the Pen 2ea21ff244dc5c780a97b924e89382f9 by Jesse Couch (@designcouch) on CodePen.

Did I help you out?

Read More

←  Creating an iCal feed in MODX with mxCalendar Getting Tough with Clients  →

There are 11 comments. Add Yours.

A Note from the Moderator

Thanks for taking the time to comment! I'll respond as quickly as possible if necessary. In the meantime, please keep the following in mind:

  • All comments must be appropriate. I'll delete 'em if you get nasty.
  • Please allow for response time. I'm here as much as possible, but can't always respond as quickly as some would like.
  • Please stay on topic.
  • I don't work for free—if you want custom work, feel free to get in touch and I'll write up a quote!
  1. Svetlana


    Apr 05, 2013

    Great tutorial. Always nice to see how someone else does things like this.

    Reply to Svetlana

  2. Zeeshan


    May 28, 2013

    Total crap. Your dropdown works fine but only when thre is nothing on the page except this so called dropdown. If you put it on a real web page, it just pushes away rest of the page content downwards when it opens.

    Reply to Zeeshan

    1. Jesse


      May 28, 2013

      Sorry you feel that way, Zeeshan. Unfortunately, this code was written quickly to respond to another post where the code was very over-written, and an essential element was missed that solves your problem. You must add relative positioning to the parent li, and absolute positioning to the child. I have altered the provided code accordingly.

      This is an issue that most reasonably talented front-end folks could straighten out on their own, instead of just relying on cut-and-paste "coding".

      In the future, please be sure to phrase your criticism constructively, as you will receive much more complete and courteous responses.

    2. Lucas


      Sep 05, 2013

      I bet this is only a missconfigured CSS property, why dont you fix it? Otherwise, if you can't, what are you even doing here?

  3. Lucas


    Sep 05, 2013

    Very nice! Noted! love css transitions and pure CSS stuff!

    Reply to Lucas

  4. Bobea


    Jul 16, 2014

    This comment has been edited, as you attempted to cut and paste code, Bobea. If you would like to try again, I'd be happy to respond. - Jesse

    Reply to Bobea

    1. Bobea


      Jul 16, 2014

      ooooooOoooooh Noooooooo!
      I need help my with my menu! the comment SOS did not even show, please understand Im not trying to blog crap! I tried to post a menu that I made using this one as a guide!

  5. Bobea


    Jul 17, 2014

    Jesse thans for the support, what is the best way for me to send this menu?

    Reply to Bobea

    1. Jesse


      Jul 18, 2014

      Harmless plug, but my friend Chris has an awesome site called Codepen where you can write and test all kinds of code. Just bring your menu into that and then share a link!

  6. You know how to amaze and surprise someone else. I really value your greatest assistance and timely support.

    Reply to

  7. 16 page

    16 page

    Oct 27, 2018

    How exciting it is to read your truly wonderful posts! Thank you for expressing your thoughts in such a manner.

    Reply to 16