dev.rean.me
css

How to Create a CSS Dropdown Menu with a Submenu

A complete guide on how to build a multi-level dropdown navigation menu with HTML and CSS using hover effects and absolute positioning.

2026-09-30 ยท 4 min read

Share:

Creating a navigation menu with a dropdown submenu is one of the most common requirements in web development. While you can use JavaScript to handle dropdowns, you can also create perfectly functioning, beautiful dropdown menus using pure HTML and CSS.

In this guide, we'll walk through how to build a multi-level navigation menu with a clean hover effect.


1. The HTML Structure (Nested Lists)

To create a submenu, we nest a new unordered list (<ul>) inside a list item (<li>) of the main menu.

<nav class="navbar">
  <ul class="main-menu">
    <li><a href="#home">Home</a></li>
    <li><a href="#about">About</a></li>
    
    <!-- Dropdown Parent -->
    <li class="dropdown">
      <a href="#services">Services โ–พ</a>
      
      <!-- Submenu -->
      <ul class="submenu">
        <li><a href="#web">Web Design</a></li>
        <li><a href="#seo">SEO Optimization</a></li>
        <li><a href="#marketing">Digital Marketing</a></li>
      </ul>
    </li>

    <li><a href="#contact">Contact</a></li>
  </ul>
</nav>

Note: Notice how the .submenu is completely contained inside the <li> element for "Services". This hierarchy is essential for the CSS hover effect to work.


2. Styling the Main Menu

First, let's style the top-level menu using CSS Flexbox so it sits horizontally, similar to a standard navigation bar.

/* Reset list styles */
.main-menu, .submenu {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Style the main menu bar */
.main-menu {
  display: flex;
  background-color: #333;
  border-radius: 8px;
}

/* Style all links */
.main-menu a {
  display: block;
  padding: 15px 25px;
  color: white;
  text-decoration: none;
  font-family: Arial, sans-serif;
  transition: background-color 0.3s ease;
}

.main-menu a:hover {
  background-color: #555;
}

3. Hiding and Positioning the Submenu

By default, the nested list will break our layout and push everything down. We need to hide the submenu initially and position it absolute so it floats above the rest of the page content.

/* 1. Set the parent li to relative positioning */
.dropdown {
  position: relative;
}

/* 2. Position the submenu absolute and hide it */
.submenu {
  position: absolute;
  top: 100%; /* Position exactly below the parent */
  left: 0;
  background-color: #444;
  min-width: 200px; /* Give the dropdown some width */
  
  /* Hiding the submenu */
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px); /* Move it down slightly for animation */
  transition: all 0.3s ease; /* Smooth reveal animation */
  
  box-shadow: 0 8px 16px rgba(0,0,0,0.2);
  border-radius: 0 0 8px 8px;
  overflow: hidden;
}

/* Make submenu links stack vertically */
.submenu li {
  width: 100%;
}

๐Ÿ’ก Why visibility and opacity instead of display: none? You cannot animate display: none to display: block. By using visibility and opacity, we can create a smooth fade-in and slide-up transition!


4. The Hover Magic

Now for the final piece of the puzzle: showing the submenu when the user hovers over the parent dropdown list item.

/* When hovering over the .dropdown li, target the .submenu inside it */
.dropdown:hover .submenu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0); /* Bring it back to its original position */
}

5. Complete Code & Output

Here is how the interaction behaves:

(Note: In an actual implementation, the dropdown is hidden until you hover over "Services โ–พ".)

Pro Tips for Dropdowns:

  1. Accessibility (aria-haspopup & aria-expanded): To make dropdowns accessible, you should include ARIA attributes. Note that pure CSS hover dropdowns aren't great for keyboard navigation. For robust accessibility, a little JavaScript is recommended to toggle focus states.
  2. The top: 100% Rule: Using top: 100% is incredibly useful because it perfectly aligns the top of the dropdown with the bottom of the parent element, no matter how tall the parent element is.
  3. Z-Index: Always ensure your .submenu has a higher z-index if it appears under other content on your webpage.

Happy Coding! ๐ŸŽจ

โ† Back to css
Share: