About this snippet

A dropdown that holds more than one level. Clicking a product slides the panel across to its submenu, and the back link slides it home again.

Both panels sit side by side in a row twice the width of the dropdown, each taking half of it, inside a container with overflow hidden. Sliding is one translateX of minus 50 percent on that row rather than showing and hiding panels, so the two views move as a single piece and nothing reflows partway through.

Closing waits 300 milliseconds before resetting to the first panel, which lets the fade out finish before the slide snaps back. Without that delay you watch the menu rewind itself on the way out. Adding a third level means one more panel in the row and a wider container to match.

Size
5.2 KB
Uses
HTML, CSS, JavaScript
Loads
placehold.co
Views
261
<div class="nav-system">
  <button class="menu-trigger" id="menu-btn">Explore Features</button>
  
  <div class="glass-dropdown" id="dropdown-menu">
    <div class="panel-container" id="panel-container">
      
      <!-- Primary Menu Panel -->
      <div class="menu-panel" id="panel-main">
        <h3 class="panel-title">Products</h3>
        <div class="menu-item nav-forward">
          <div class="item-icon">P</div>
          <div class="item-text">
            <h4>Payments</h4>
            <p>Accept transactions globally.</p>
          </div>
          <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 18 15 12 9 6"></polyline></svg>
        </div>
        <div class="menu-item nav-forward">
          <div class="item-icon">B</div>
          <div class="item-text">
            <h4>Billing</h4>
            <p>Manage recurring subscriptions.</p>
          </div>
          <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 18 15 12 9 6"></polyline></svg>
        </div>
      </div>
      
      <!-- Secondary Submenu Panel -->
      <div class="menu-panel" id="panel-sub">
        <div class="back-action" id="nav-back">
          <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"><polyline points="15 18 9 12 15 6"></polyline></svg>
          Back to Products
        </div>
        <h3 class="panel-title">Payments Details</h3>
        <div class="menu-item">
          <div class="item-text">
            <h4>Checkout</h4>
            <p>Pre-built conversion optimized pages.</p>
          </div>
        </div>
        <div class="menu-item">
          <div class="item-text">
            <h4>Elements</h4>
            <p>Customizable UI components.</p>
          </div>
        </div>
      </div>
      
    </div>
  </div>
</div>
*, *::before, *::after {
  box-sizing: border-box;
}

body {
  font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  margin: 0;
  background: url("https://placehold.co/1920x1080/0f172a/1e293b?text=Abstract+Colors") center/cover no-repeat;
  display: flex;
  justify-content: center;
  padding-top: 100px;
  min-height: 100vh;
}

.nav-system {
  position: relative;
}

.menu-trigger {
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(10px);
  color: #ffffff;
  border: 1px solid rgba(255, 255, 255, 0.2);
  padding: 12px 24px;
  border-radius: 8px;
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s;
}

.menu-trigger:hover {
  background: rgba(255, 255, 255, 0.2);
}

.glass-dropdown {
  position: absolute;
  top: 60px;
  left: 0;
  width: 320px;
  /* Container establishes the window frame */
  background: rgba(15, 23, 42, 0.6);
  backdrop-filter: blur(20px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 16px;
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
  overflow: hidden;
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px);
  transition: opacity 0.3s ease, transform 0.3s ease, visibility 0.3s ease;
}

.glass-dropdown.show {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.panel-container {
  display: flex;
  width: 200%;
  transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.panel-container.shifted {
  transform: translateX(-50%);
}

.menu-panel {
  width: 50%;
  padding: 24px;
  flex-shrink: 0;
}

.panel-title {
  color: #94a3b8;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 1px;
  margin: 0 0 16px 0;
}

.menu-item {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px;
  border-radius: 12px;
  cursor: pointer;
  color: #f8fafc;
  transition: background 0.2s;
  margin-bottom: 8px;
}

.menu-item:hover {
  background: rgba(255, 255, 255, 0.1);
}

.item-icon {
  width: 40px;
  height: 40px;
  background: rgba(59, 130, 246, 0.2);
  color: #3b82f6;
  border-radius: 8px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-weight: 700;
  flex-shrink: 0;
}

.item-text h4 {
  margin: 0 0 4px 0;
  font-size: 1rem;
}

.item-text p {
  margin: 0;
  font-size: 0.85rem;
  color: #94a3b8;
}

.menu-item svg {
  margin-left: auto;
  color: #64748b;
}

.back-action {
  display: flex;
  align-items: center;
  gap: 8px;
  color: #3b82f6;
  font-weight: 600;
  font-size: 0.9rem;
  cursor: pointer;
  margin-bottom: 24px;
}
const btn = document.getElementById("menu-btn");
const dropdown = document.getElementById("dropdown-menu");
const container = document.getElementById("panel-container");

const forwards = document.querySelectorAll(".nav-forward");
const backBtn = document.getElementById("nav-back");

btn.addEventListener("click", function() {
  dropdown.classList.toggle("show");
  // Reset position when reopening
  if (!dropdown.classList.contains("show")) {
    setTimeout(function() {
      container.classList.remove("shifted");
    }, 300);
  }
});

forwards.forEach(function(item) {
  item.addEventListener("click", function() {
    container.classList.add("shifted");
  });
});

backBtn.addEventListener("click", function() {
  container.classList.remove("shifted");
});
Esc
↑↓ moveEnter select

Start from a template

Open an .html file, or HTML, CSS, JS, Markdown, Less or TypeScript files. You can also drop them here. Styles and scripts go into their panes.

Share

Source

Keyboard shortcuts

Save