Flexbox Responsive Dropdown Menu, No JavaScript

With Flexbox, it’s relatively simple to quickly create a fully responsive menu without JavaScript. This example includes a one level drop down menu as well.

See the Pen Flexbox Menu by Richard (@barkins) on CodePen.

Step 1: HTML

Here’s a the simple HTML code with an unordered list. Although this can be done without using a UL, it’s more effective to use it when you have a dropdown menu. Otherwise, it’s safe to omit it.

<nav class="menu">
  <ul>
    <li><a href="#">Home</a></li>
    <li class="sub-menu"><a href="#">About</a>
      
      <ul>
          <li><a href="#">History</a></li>
          <li><a href="#">Bio</a></li>
      </ul>
    
    </li>    
    <li><a href="#">Work</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</nav><!--/menu-->

I tried to omit any unnecessary custom classes, however I did need to include one with the drop down LI tag.

Step 2: CSS

Here’s where the Flexbox action comes into play. Start by selecting the UL and add display:flex to it.

.menu ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
}

In order to have the menu take the full space of its container, I needed to include a width:25% on the LIs. Initially I wanted to use flex-grow:1 instead, however I ran into some wonky width issues when hovering over the dropdown menu. Just be sure to change the percentage width based on how many top level menu items you have.

.menu ul li {
  width: 25%;
}

For the dropdown menu, you’ll first want to hide that UL inside the LI tag.

.menu ul li > ul {
  display: none;
  flex-direction: column;
}

Then when hovering over the LI menu item with a dropdown inside of it, apply display:flex to it.

.menu ul li:hover > ul {
  display: flex;
}

Step 3: Complete CSS

Here’s all the CSS for your reference.

.menu {
  font-family: sans-serif;
}
.menu ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
}
.menu ul li {
  width: 25%;
}
@media (max-width: 40em) {
  .menu ul li {
    width: 100%;
  }
}
.menu ul li > ul {
  display: none;
  flex-direction: column;
}
.menu ul li > ul li {
  width: 100%;
}
.menu ul li:hover > ul {
  display: flex;
}
.menu a {
  text-transform: uppercase;
  display: block;
  background: blue;
  padding: 15px;
  color: white;
  text-decoration: none;
  text-align: center;
}
.menu a:hover {
  background: lightBlue;
  color: blue;
}
.menu .sub-menu li > a {
  background: lightBlue;
  color: blue;
}
.menu .sub-menu > a:after {
  content: "+";
  padding-left: 5px;
}
Filed under: CSS3, HTML5Tagged with: