22 CSS Dropdown Menu Designs11 / 22

Pure CSSMIT licensed

Nested Multi-Level Dropdown

A three-level deep nested dropdown where each submenu flies out to the right of its parent item, triggered purely by CSS hover on sibling selectors.

Published

Live Demo
Try it

The code

<div class="dd-11">
  <link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700&display=swap" rel="stylesheet">
  <nav class="dd-11__nav">
    <ul class="dd-11__list dd-11__list--root">
      <li class="dd-11__item">
        <a href="#" class="dd-11__link">Home</a>
      </li>
      <li class="dd-11__item dd-11__item--has-sub">
        <a href="#" class="dd-11__link">Products</a>
        <ul class="dd-11__sub">
          <li class="dd-11__item dd-11__item--has-sub">
            <a href="#" class="dd-11__link">Software</a>
            <ul class="dd-11__sub">
              <li class="dd-11__item"><a href="#" class="dd-11__link">Web App</a></li>
              <li class="dd-11__item"><a href="#" class="dd-11__link">Desktop</a></li>
              <li class="dd-11__item"><a href="#" class="dd-11__link">Mobile</a></li>
            </ul>
          </li>
          <li class="dd-11__item dd-11__item--has-sub">
            <a href="#" class="dd-11__link">Hardware</a>
            <ul class="dd-11__sub">
              <li class="dd-11__item"><a href="#" class="dd-11__link">Devices</a></li>
              <li class="dd-11__item"><a href="#" class="dd-11__link">Accessories</a></li>
            </ul>
          </li>
          <li class="dd-11__item"><a href="#" class="dd-11__link">Services</a></li>
        </ul>
      </li>
      <li class="dd-11__item dd-11__item--has-sub">
        <a href="#" class="dd-11__link">Company</a>
        <ul class="dd-11__sub">
          <li class="dd-11__item"><a href="#" class="dd-11__link">About</a></li>
          <li class="dd-11__item"><a href="#" class="dd-11__link">Careers</a></li>
          <li class="dd-11__item dd-11__item--has-sub">
            <a href="#" class="dd-11__link">Press</a>
            <ul class="dd-11__sub">
              <li class="dd-11__item"><a href="#" class="dd-11__link">News</a></li>
              <li class="dd-11__item"><a href="#" class="dd-11__link">Media Kit</a></li>
            </ul>
          </li>
        </ul>
      </li>
      <li class="dd-11__item"><a href="#" class="dd-11__link">Contact</a></li>
    </ul>
  </nav>
</div>
.dd-11,
.dd-11 *,
.dd-11 *::before,
.dd-11 *::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.dd-11 ::selection {
  background: #1d4ed8;
  color: #eff6ff;
}

.dd-11 {
  --brand: #1d4ed8;
  --surface: #fff;
  --text: #1e293b;
  --muted: #64748b;
  --border: #e2e8f0;
  --hover: #eff6ff;
  font-family: 'Manrope', sans-serif;
  min-height: 380px;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 32px 20px;
  background: linear-gradient(135deg, #eff6ff 0%, #e0e7ff 100%);
}

.dd-11__nav {
  position: relative;
  z-index: 100;
}

.dd-11__list {
  list-style: none;
  display: flex;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 6px;
  gap: 2px;
  box-shadow: 0 4px 20px rgba(0,0,0,.07);
}

.dd-11__list--root > .dd-11__item {
  position: relative;
}
/* submenus */

.dd-11__sub {
  list-style: none;
  position: absolute;
  top: 0;
  left: 100%;
  min-width: 170px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 8px 32px rgba(0,0,0,.12);
  padding: 5px;
  display: flex;
  flex-direction: column;
  gap: 1px;
  opacity: 0;
  pointer-events: none;
  transform: translateX(4px);
  transition: opacity 0.2s ease, transform 0.2s ease;
  z-index: 10;
}
/* Hover bridges — must be on the .dd-11__item (the :hover target),
   NOT on .dd-11__sub because the sub has pointer-events:none at rest
   so its ::before is unreachable. Nested items extend their right
   edge by an invisible strip covering the gap to the submenu. */

.dd-11__item {
  position: relative;
}

.dd-11__item:not(.dd-11__list--root > .dd-11__item)::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 100%;
  width: 10px;
}
/* Root-level items drop submenus DOWNWARD, so bridge goes BELOW. */

.dd-11__list--root > .dd-11__item::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  height: 8px;
}
/* first level drops down */

.dd-11__list--root > .dd-11__item > .dd-11__sub {
  top: calc(100% + 8px);
  left: 0;
  transform: translateY(-4px);
}

.dd-11__list--root > .dd-11__item:hover > .dd-11__sub {
  transform: translateY(0);
}

.dd-11__item:hover > .dd-11__sub {
  opacity: 1;
  pointer-events: auto;
  transform: translateX(0);
}

.dd-11__list--root > .dd-11__item:hover > .dd-11__sub {
  opacity: 1;
  pointer-events: auto;
}

.dd-11__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 9px 14px;
  border-radius: 8px;
  text-decoration: none;
  color: var(--text);
  font-size: 13.5px;
  font-weight: 500;
  white-space: nowrap;
  transition: background 0.15s, color 0.15s;
  gap: 8px;
}

.dd-11__link:hover {
  background: var(--hover);
  color: var(--brand);
}
/* nested indicator arrow */

.dd-11__item--has-sub > .dd-11__link::after {
  content: '›';
  font-size: 14px;
  font-weight: 400;
  color: var(--muted);
  margin-left: auto;
}
/* root level items use down arrow */

.dd-11__list--root > .dd-11__item--has-sub > .dd-11__link::after {
  content: '⌄';
  font-size: 11px;
}

.dd-11__list--root .dd-11__link {
  font-weight: 600;
}

@media (prefers-reduced-motion: reduce) {
  .dd-11__sub {
    transition: none;
  }
}
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Dropdown Menu Design from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Nested Multi-Level Dropdown
Source: https://codefronts.com/navigation/css-dropdown-menus/nested-multi-level-dropdown/

A three-level deep nested dropdown where each submenu flies out to the right of its parent item, triggered purely by CSS hover on sibling selectors.
## HTML
```html
<div class="dd-11">
  <link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700&display=swap" rel="stylesheet">
  <nav class="dd-11__nav">
    <ul class="dd-11__list dd-11__list--root">
      <li class="dd-11__item">
        <a href="#" class="dd-11__link">Home</a>
      </li>
      <li class="dd-11__item dd-11__item--has-sub">
        <a href="#" class="dd-11__link">Products</a>
        <ul class="dd-11__sub">
          <li class="dd-11__item dd-11__item--has-sub">
            <a href="#" class="dd-11__link">Software</a>
            <ul class="dd-11__sub">
              <li class="dd-11__item"><a href="#" class="dd-11__link">Web App</a></li>
              <li class="dd-11__item"><a href="#" class="dd-11__link">Desktop</a></li>
              <li class="dd-11__item"><a href="#" class="dd-11__link">Mobile</a></li>
            </ul>
          </li>
          <li class="dd-11__item dd-11__item--has-sub">
            <a href="#" class="dd-11__link">Hardware</a>
            <ul class="dd-11__sub">
              <li class="dd-11__item"><a href="#" class="dd-11__link">Devices</a></li>
              <li class="dd-11__item"><a href="#" class="dd-11__link">Accessories</a></li>
            </ul>
          </li>
          <li class="dd-11__item"><a href="#" class="dd-11__link">Services</a></li>
        </ul>
      </li>
      <li class="dd-11__item dd-11__item--has-sub">
        <a href="#" class="dd-11__link">Company</a>
        <ul class="dd-11__sub">
          <li class="dd-11__item"><a href="#" class="dd-11__link">About</a></li>
          <li class="dd-11__item"><a href="#" class="dd-11__link">Careers</a></li>
          <li class="dd-11__item dd-11__item--has-sub">
            <a href="#" class="dd-11__link">Press</a>
            <ul class="dd-11__sub">
              <li class="dd-11__item"><a href="#" class="dd-11__link">News</a></li>
              <li class="dd-11__item"><a href="#" class="dd-11__link">Media Kit</a></li>
            </ul>
          </li>
        </ul>
      </li>
      <li class="dd-11__item"><a href="#" class="dd-11__link">Contact</a></li>
    </ul>
  </nav>
</div>
```
## CSS
```css
.dd-11,
.dd-11 *,
.dd-11 *::before,
.dd-11 *::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.dd-11 ::selection {
  background: #1d4ed8;
  color: #eff6ff;
}

.dd-11 {
  --brand: #1d4ed8;
  --surface: #fff;
  --text: #1e293b;
  --muted: #64748b;
  --border: #e2e8f0;
  --hover: #eff6ff;
  font-family: 'Manrope', sans-serif;
  min-height: 380px;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 32px 20px;
  background: linear-gradient(135deg, #eff6ff 0%, #e0e7ff 100%);
}

.dd-11__nav {
  position: relative;
  z-index: 100;
}

.dd-11__list {
  list-style: none;
  display: flex;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 6px;
  gap: 2px;
  box-shadow: 0 4px 20px rgba(0,0,0,.07);
}

.dd-11__list--root > .dd-11__item {
  position: relative;
}
/* submenus */

.dd-11__sub {
  list-style: none;
  position: absolute;
  top: 0;
  left: 100%;
  min-width: 170px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 8px 32px rgba(0,0,0,.12);
  padding: 5px;
  display: flex;
  flex-direction: column;
  gap: 1px;
  opacity: 0;
  pointer-events: none;
  transform: translateX(4px);
  transition: opacity 0.2s ease, transform 0.2s ease;
  z-index: 10;
}
/* Hover bridges — must be on the .dd-11__item (the :hover target),
   NOT on .dd-11__sub because the sub has pointer-events:none at rest
   so its ::before is unreachable. Nested items extend their right
   edge by an invisible strip covering the gap to the submenu. */

.dd-11__item {
  position: relative;
}

.dd-11__item:not(.dd-11__list--root > .dd-11__item)::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 100%;
  width: 10px;
}
/* Root-level items drop submenus DOWNWARD, so bridge goes BELOW. */

.dd-11__list--root > .dd-11__item::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  height: 8px;
}
/* first level drops down */

.dd-11__list--root > .dd-11__item > .dd-11__sub {
  top: calc(100% + 8px);
  left: 0;
  transform: translateY(-4px);
}

.dd-11__list--root > .dd-11__item:hover > .dd-11__sub {
  transform: translateY(0);
}

.dd-11__item:hover > .dd-11__sub {
  opacity: 1;
  pointer-events: auto;
  transform: translateX(0);
}

.dd-11__list--root > .dd-11__item:hover > .dd-11__sub {
  opacity: 1;
  pointer-events: auto;
}

.dd-11__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 9px 14px;
  border-radius: 8px;
  text-decoration: none;
  color: var(--text);
  font-size: 13.5px;
  font-weight: 500;
  white-space: nowrap;
  transition: background 0.15s, color 0.15s;
  gap: 8px;
}

.dd-11__link:hover {
  background: var(--hover);
  color: var(--brand);
}
/* nested indicator arrow */

.dd-11__item--has-sub > .dd-11__link::after {
  content: '›';
  font-size: 14px;
  font-weight: 400;
  color: var(--muted);
  margin-left: auto;
}
/* root level items use down arrow */

.dd-11__list--root > .dd-11__item--has-sub > .dd-11__link::after {
  content: '⌄';
  font-size: 11px;
}

.dd-11__list--root .dd-11__link {
  font-weight: 600;
}

@media (prefers-reduced-motion: reduce) {
  .dd-11__sub {
    transition: none;
  }
}
```

How this works

Each .dd-11__item with a child .dd-11__sub uses the pattern .dd-11__item:hover > .dd-11__sub to reveal only the direct child submenu, not all nested descendants. The submenu panel uses position: absolute; left: 100%; top: -6px to anchor to the right edge of its parent list item. A small negative margin bridges the hover gap between parent and child.

The depth indicator — a right-pointing chevron — is added via ::after pseudo-element on any list item that contains a nested .dd-11__sub, using content: '›' positioned at the right edge. The entire system is recursive: each sub-menu follows the same pattern, so a third level just requires a third nesting of the same markup structure.

Make it yours

  • Flip submenus to the left side by changing left: 100% to right: 100%; left: auto — useful when the dropdown is near the right edge of the viewport.
  • Add a visual depth cue by increasing box-shadow blur and opacity on each nested level: level 1 gets 8px blur, level 2 gets 16px, level 3 gets 24px.
  • Add a connecting bridge between parent and child using a transparent pseudo-element that extends the hover zone across the gap between levels.
  • Limit depth to 2 levels in real UI — studies show 3+ level fly-outs severely impact usability, especially on touch devices.

Gotchas — read before shipping

  • The hover bridge gap between parent item and submenu panel can cause the submenu to close if the user moves the mouse diagonally — expand the parent's padding-right to cover the gap.
  • Nested dropdowns are notoriously difficult on touch devices — consider collapsing to an accordion pattern on mobile with a media query.
  • The z-index stacking order must increase with each depth level — a level-2 submenu appearing behind a level-1 panel is the most common bug.

Browser support

ChromeSafariFirefoxEdge
49+9+44+49+

Nested hover selectors are universally supported; no special features required.

Techniques used in this demo

Search CodeFronts

Loading…