Roll Your Own Dropdown Menu Using Pure CSS

There’s a lot of tutorials out there for creating dropdown menus using Only CSS. However, I haven’t really found one that breaks down the development process in order to teach it instead of just providing an explanation of code you’re meant to copy and paste. Here I hope to explain just how CSS dropdown menus work and go over the process I used to develop the one I use on my projects.

Start With a Good Foundation: The Markup

The most important step when developing something like this is making sure the markup is clean and semantically correct. If you get this step wrong, you’re going to have a more difficult time trying to style it properly later. Here’s the markup I’ve chosen to use for this project:

<ul>
    <li><a href="#">Item 1</a></li>
    <li><a href="#">Item 2</a></li>
    <li><a href="#">Item 3</a></li>
    <li><a href="#">Item 4</a></li>
    <li><a href="#">Item 5</a></li>
</ul>

Here we’ve created a very simple unordered list that contains links that refer back to the page itself: pretty standard stuff. What makes this markup so suited for a dropdown menu is the fact that an dropdown menu is technically just a list of items, each one designed to signify a choice or action that user can take.

Add the Proper Hooks: Classes

Now that we’ve got our markup figured out, it’s time to add some CSS styles to it.

<ul class="dropdown-menu">
    <li class="menu-item">
        <a class="menu-item-link" href="#">Item 1</a>
    </li>
    <li class="menu-item">
        <a class="menu-item-link" href="#">Item 2</a>
    </li>
    <li class="menu-item">
        <a class="menu-item-link" href="#">Item 3</a>
    </li>
    <li class="menu-item">
        <a class="menu-item-link" href="#">Item 4</a>
    </li>
    <li class="menu-item">
        <a class="menu-item-link" href="#">Item 5</a>
    </li>
</ul>

Most of the classes here are pretty self explanatory: their names reflect the function of the elements they’re meant to style.

With the addition of the class names to the elements, we can now start applying styles to the menu.

Style the Menu

Let’s apply the following styles to the dropdown menu:

.dropdown-menu {
    padding: 0;
    margin: 0;
    width: 130px;
    font-family: Arial;
    display: block;
    border: solid 1px #CCCCCC;
    border-bottom-style: none;
    background-color: #F4F4F4;
}
.dropdown-menu .menu-item-link {
    display: block;
    border-bottom: solid 1px #CCCCCC;
    text-decoration: none;
    line-height: 30px; /* Vertically center the text */
    color: rgba(89,87,87,0.9);
    height: 30px;
    padding: 5px;
    cursor: pointer;
}

If you’re familiar with CSS, most of the code here is pretty self explanatory. Once you’ve applied the styles, you should get something that looks like this:

dropdown-menu-step-1

Hide and Hover: Making the Menu Drop Down

With the markup and basic styles now in place, we now have our selves a very nice static menu. However, the goal of the project is to create a drop down menu which means we’re going to need a way to show and hide the list items not at the top of the list.

To start off, we’re going to need to modify our markup and add an “active” class to the first element in the list so we know which list item we want to keep visible. Go ahead and update markup to look like the following:

<ul class="dropdown-menu">
    <li class="menu-item active"> <!-- Add active class -->
        <a class="menu-item-link" href="#">Item 1</a>
    </li>
    <li class="menu-item">
        <a class="menu-item-link" href="#">Item 2</a>
    </li>
    <li class="menu-item">
        <a class="menu-item-link" href="#">Item 3</a>
    </li>
    <li class="menu-item">
        <a class="menu-item-link" href="#">Item 4</a>
    </li>
    <li class="menu-item">
        <a class="menu-item-link" href="#">Item 5</a>
    </li>
</ul>

Now we need to update our CSS to both hide the “inactive” list items (those without the active class) and make sure we keep the active list item visible. Go ahead and add the following rules to your CSS:

.dropdown-menu .menu-item {
    display: none;
}

.dropdown-menu .menu-item.active {
    display: block;
}

.dropdown-menu:hover .menu-item {
    display: block;
}

Now, the above css might be a bit confusing (especially with the use of the :hover pseudo-selectors), so I’ll treat each one as part of a series and go through them step-by-step:

  1. Hide every menu item that is part of the dropdown-menu list.
  2. For every menu item with a class of active, override the display rule from step one and show them as a block-level element.
  3. Whenever the dropdown-menu is moused over, find every element with a class of list-item and display it as a block-level element.

Finishing Touches: Hover Effects and an Arrow “Icon”

Okay, so we’ve now got our dropdown menu showing and hiding the on mouse over. Before we call this thing finished, let’s go ahead and add some finishing touches to make the final product a bit more polished.

First, let’s add a hover effect to each of the dropdown elements. This is not only a nice design touch, it also helps indicate which item the user is currently hovered over. In order to do this, we simply need to add another :hover selector rule to our CSS:

.dropdown-menu .menu-item-link:hover {
    background-color: #DDDDDD;
}

Once you add that to the code, you’ll notice that the background color of each menu item you mouse over darkens.

Now, we’re going to add a cool little down arrow to the right of the active menu item. Traditionally, we’d use some kind of tag with its background-image property set to the location of an arrow icon we created. With this tutorial being about using only CSS to create our dropdown menu, we’re going to instead use the :after selector and the :content property to create our “icon” on the fly using code I learned from Chris Coyier over at CSS tricks. Add the following rule to your stylesheet:

.dropdown-menu .menu-item.active .menu-item-link:after {
    width: 0;
    height: 0;
    content: "";
    position: absolute;
    top: 18px;
    right: 8px;
    border-top: 4px solid rgba(0, 0, 0, 1);
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
}

Now before you starting mumbling WTF at your screen, let me explain what’s going on here.

The first thing I want to cover is the :after selector. If you’ve never encountered this one before, the best definition I’ve found is from the Mozilla Developer Network:

The CSS :after pseudo-element matches a virtual last child of the selected element. Typically used to add cosmetic content to an element, by using the content CSS property. This element is inline by default.

By using the :after selector along with the :content property, we can dynamically inject content designed to appear after our menu item link. In the code above, we’re injecting an empty string, positioning it in the middle of the list item, and then styling it to look like a triangle using the border properties. The finished result will look something like this:

dropdown-menu-final

Wrapping Up

Well, I hope you guys found this CSS menu tutorial a little more helpful than some of the other ones out there. If you don’t understand something or feel I could have explained something better, please let me know. Also feel free to let me know if you like this tutorial and would like to see more stuff like this.