← Back to all tutorials

Creating Nested Menu's with Flexbox

Build dropdown sub-menus within a Flexbox navigation — nested flex containers and hover-triggered dropdowns.

Creating Nested Menu's with Flexbox

Let's extend our Flexbox navbar to include dropdown sub-menus — menus that appear when hovering over a link. This uses nested flex containers and CSS positioning.

Updated HTML

<nav class="navbar">
    <div class="nav-logo"><a href="#">DevBlog</a></div>
    <ul class="nav-links">
        <li><a href="#">Home</a></li>
        <li class="has-submenu">
            <a href="#">Services ▾</a>
            <ul class="submenu">
                <li><a href="#">Web Design</a></li>
                <li><a href="#">Development</a></li>
                <li><a href="#">SEO</a></li>
                <li><a href="#">Consulting</a></li>
            </ul>
        </li>
        <li class="has-submenu">
            <a href="#">Blog ▾</a>
            <ul class="submenu">
                <li><a href="#">HTML &amp; CSS</a></li>
                <li><a href="#">JavaScript</a></li>
                <li><a href="#">React</a></li>
            </ul>
        </li>
        <li><a href="#">About</a></li>
        <li><a href="#">Contact</a></li>
    </ul>
</nav>

Parent Item Positioning

.has-submenu {
    position: relative;  /* Anchor point for the dropdown */
}

The Submenu (Hidden by Default)

.submenu {
    position: absolute;
    top: 100%;           /* Below the parent link */
    left: 0;
    min-width: 200px;
    background: #34495e;
    border-radius: 0 0 8px 8px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.2);
    list-style: none;
    padding: 8px 0;

    /* Hidden state */
    opacity: 0;
    visibility: hidden;
    transform: translateY(-10px);
    transition: opacity 0.25s ease,
                visibility 0.25s ease,
                transform 0.25s ease;
}

/* Show on hover */
.has-submenu:hover .submenu {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

Submenu Link Styling

.submenu li a {
    display: block;
    padding: 10px 20px;
    color: #bbb;
    text-decoration: none;
    font-size: 14px;
    transition: background 0.2s ease, color 0.2s ease, padding-left 0.2s ease;
}

.submenu li a:hover {
    background: rgba(255,255,255,0.08);
    color: #fff;
    padding-left: 24px;  /* Subtle indent on hover */
}

Adding a Separator Line

.submenu li + li {
    border-top: 1px solid rgba(255,255,255,0.06);
}

Visual Arrow Indicator

.has-submenu > a::after {
    content: '';
    display: inline-block;
    width: 0;
    height: 0;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 5px solid currentColor;
    margin-left: 6px;
    vertical-align: middle;
    transition: transform 0.2s ease;
}

.has-submenu:hover > a::after {
    transform: rotate(180deg);
}

This creates a small triangle arrow using CSS borders that flips on hover.

The Flexbox Layout Stack

Navbar (flex container, row)
├── Logo (flex item)
├── Nav Links (flex item → also flex container, row)
│   ├── Home (flex item)
│   ├── Services (flex item, has-submenu)
│   │   └── Submenu (absolute positioned, vertical list)
│   │       ├── Web Design
│   │       ├── Development
│   │       └── SEO
│   ├── Blog (flex item, has-submenu)
│   │   └── Submenu (absolute positioned, vertical list)
│   ├── About (flex item)
│   └── Contact (flex item)
└── Actions (flex item → also flex container)

Why Flexbox + Position Works

TechniqueHandles
FlexboxHorizontal layout of navbar and link items
position: absoluteDropdown positioning below the parent item
opacity + visibility + transformSmooth animated show/hide

Preventing Dropdown Closing Gap

If there's a gap between the parent link and the dropdown, the mouse leaves the hover zone and the dropdown closes. Fix this by ensuring no gap:

.submenu {
    top: 100%;   /* No gap between parent and dropdown */
    padding-top: 0;
}

/* Or add an invisible bridge */
.has-submenu::after {
    content: '';
    position: absolute;
    top: 100%;
    left: 0;
    width: 100%;
    height: 10px;  /* Invisible hover bridge */
}

Key Takeaways

  • Nested menus combine Flexbox (horizontal layout) with absolute positioning (dropdown)
  • position: relative on the parent anchors the absolute dropdown below it
  • Use opacity + visibility + transform for smooth animated dropdowns
  • CSS-only hover dropdowns don't need JavaScript
  • Prevent hover gaps between the trigger and the dropdown to avoid flicker