Skillversitas

CSS Dropdowns - Dropdown Menu

A dropdown is a UI component that hides its content and reveals it when the user interacts (clicks/hovers). Dropdowns are commonly used in navigation menus, custom form selects, and action menus.

CSS Dropdowns make use of the :hover and :focus pseudo-classes, position: absolute, z-index, and transition for animation effects. For accessibility, it is also important to handle :focus states so that the dropdown can be used with a keyboard.

Basic technique: hide the dropdown content with opacity: 0 + visibility: hidden, then reveal it when the parent is hovered with a smooth transition.


Code Example

Comprehensive Dropdown

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS Dropdowns</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      font-family: 'Segoe UI', Tahoma, sans-serif;
      padding: 30px;
      background: #f0f2f5;
      color: #334155;
    }

    h2 {
      margin-bottom: 15px;
      color: #1a1a2e;
    }

    .section {
      margin-bottom: 50px;
    }

    .label {
      font-size: 12px;
      color: #64748b;
      margin-bottom: 10px;
      font-family: monospace;
      background: #e2e8f0;
      display: inline-block;
      padding: 3px 8px;
      border-radius: 4px;
      margin-top: 10px;
      margin-bottom: 15px;
    }

    /* ===== DROPDOWN BASE ===== */
    .dropdown {
      position: relative;
      display: inline-block;
    }

    .dropdown-trigger {
      padding: 12px 24px;
      background: #667eea;
      color: white;
      border: none;
      border-radius: 8px;
      font-size: 15px;
      font-weight: 600;
      cursor: pointer;
      display: flex;
      align-items: center;
      gap: 8px;
      transition: background 0.3s;
    }

    .dropdown-trigger:hover {
      background: #5a67d8;
    }

    .dropdown-trigger::after {
      content: '▾';
      font-size: 12px;
    }

    .dropdown-menu {
      position: absolute;
      top: calc(100% + 8px);
      left: 0;
      background: white;
      border-radius: 12px;
      box-shadow: 0 10px 40px rgba(0,0,0,0.12);
      min-width: 220px;
      padding: 8px;
      opacity: 0;
      visibility: hidden;
      transform: translateY(-10px);
      transition: all 0.3s;
      z-index: 100;
    }

    .dropdown:hover .dropdown-menu,
    .dropdown:focus-within .dropdown-menu {
      opacity: 1;
      visibility: visible;
      transform: translateY(0);
    }

    .dropdown-menu::before {
      content: '';
      position: absolute;
      top: -6px;
      left: 20px;
      width: 12px;
      height: 12px;
      background: white;
      transform: rotate(45deg);
      box-shadow: -2px -2px 4px rgba(0,0,0,0.05);
    }

    .dropdown-menu a,
    .dropdown-menu button {
      display: flex;
      align-items: center;
      gap: 10px;
      padding: 10px 14px;
      color: #475569;
      text-decoration: none;
      border-radius: 8px;
      font-size: 14px;
      transition: all 0.2s;
      border: none;
      background: none;
      width: 100%;
      cursor: pointer;
      text-align: left;
    }

    .dropdown-menu a:hover,
    .dropdown-menu button:hover {
      background: #f1f5f9;
      color: #667eea;
    }

    .dropdown-menu a:focus-visible,
    .dropdown-menu button:focus-visible {
      outline: 2px solid #667eea;
      outline-offset: -2px;
      background: #eef2ff;
    }

    .dropdown-divider {
      height: 1px;
      background: #e2e8f0;
      margin: 6px 0;
    }

    .dropdown-menu .icon {
      width: 18px;
      text-align: center;
      font-size: 14px;
    }

    .dropdown-menu .danger {
      color: #dc2626;
    }

    .dropdown-menu .danger:hover {
      background: #fef2f2;
      color: #dc2626;
    }

    /* ===== NAV DROPDOWN ===== */
    .nav-bar {
      display: flex;
      align-items: center;
      gap: 5px;
      background: #1a1a2e;
      padding: 10px 20px;
      border-radius: 12px;
    }

    .nav-item {
      position: relative;
    }

    .nav-item > a {
      color: #cbd5e1;
      text-decoration: none;
      padding: 10px 18px;
      border-radius: 8px;
      font-weight: 500;
      display: flex;
      align-items: center;
      gap: 6px;
      transition: all 0.3s;
    }

    .nav-item > a::after {
      content: '▾';
      font-size: 10px;
      transition: transform 0.3s;
    }

    .nav-item:hover > a::after,
    .nav-item:focus-within > a::after {
      transform: rotate(180deg);
    }

    .nav-item > a:hover,
    .nav-item > a:focus-visible {
      background: rgba(255,255,255,0.1);
      color: white;
    }

    .nav-dropdown {
      position: absolute;
      top: calc(100% + 8px);
      left: 0;
      background: white;
      border-radius: 12px;
      box-shadow: 0 10px 40px rgba(0,0,0,0.15);
      min-width: 200px;
      padding: 8px;
      opacity: 0;
      visibility: hidden;
      transform: translateY(-10px);
      transition: all 0.3s;
      z-index: 1000;
    }

    .nav-item:hover .nav-dropdown,
    .nav-item:focus-within .nav-dropdown {
      opacity: 1;
      visibility: visible;
      transform: translateY(0);
    }

    .nav-dropdown a {
      display: flex;
      align-items: center;
      gap: 10px;
      padding: 10px 14px;
      color: #475569;
      text-decoration: none;
      border-radius: 8px;
      font-size: 14px;
      transition: all 0.2s;
    }

    .nav-dropdown a:hover {
      background: #f1f5f9;
      color: #667eea;
    }

    .nav-dropdown .nav-icon {
      width: 20px;
      text-align: center;
    }

    .nav-dropdown .nav-desc {
      font-size: 11px;
      color: #94a3b8;
      margin-top: 2px;
    }

    .nav-dropdown .nav-group-title {
      font-size: 11px;
      text-transform: uppercase;
      letter-spacing: 0.5px;
      color: #94a3b8;
      padding: 10px 14px 4px;
      font-weight: 600;
    }

    /* ===== USER MENU ===== */
    .user-menu-container {
      display: flex;
      justify-content: flex-end;
    }

    .user-menu {
      position: relative;
    }

    .user-menu-trigger {
      display: flex;
      align-items: center;
      gap: 10px;
      padding: 6px 12px;
      background: white;
      border: 2px solid #e2e8f0;
      border-radius: 50px;
      cursor: pointer;
      transition: border-color 0.3s;
    }

    .user-menu-trigger:hover {
      border-color: #667eea;
    }

    .user-menu-avatar {
      width: 36px;
      height: 36px;
      border-radius: 50%;
      background: linear-gradient(135deg, #667eea, #764ba2);
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      font-weight: bold;
      font-size: 14px;
    }

    .user-menu-name {
      font-weight: 600;
      color: #1e293b;
      font-size: 14px;
    }

    .user-menu-arrow {
      color: #94a3b8;
      font-size: 12px;
      transition: transform 0.3s;
    }

    .user-menu:hover .user-menu-arrow {
      transform: rotate(180deg);
    }

    .user-dropdown {
      position: absolute;
      top: calc(100% + 10px);
      right: 0;
      background: white;
      border-radius: 12px;
      box-shadow: 0 10px 40px rgba(0,0,0,0.12);
      min-width: 240px;
      padding: 8px;
      opacity: 0;
      visibility: hidden;
      transform: translateY(-10px);
      transition: all 0.3s;
      z-index: 100;
    }

    .user-menu:hover .user-dropdown,
    .user-menu:focus-within .user-dropdown {
      opacity: 1;
      visibility: visible;
      transform: translateY(0);
    }

    .user-dropdown-header {
      padding: 12px 14px;
      border-bottom: 1px solid #e2e8f0;
      margin-bottom: 6px;
    }

    .user-dropdown-header .name {
      font-weight: 600;
      color: #1e293b;
    }

    .user-dropdown-header .email {
      font-size: 12px;
      color: #94a3b8;
    }

    .user-dropdown a,
    .user-dropdown button {
      display: flex;
      align-items: center;
      gap: 10px;
      padding: 10px 14px;
      color: #475569;
      text-decoration: none;
      border-radius: 8px;
      font-size: 14px;
      transition: all 0.2s;
      width: 100%;
      border: none;
      background: none;
      cursor: pointer;
      text-align: left;
    }

    .user-dropdown a:hover,
    .user-dropdown button:hover {
      background: #f1f5f9;
      color: #667eea;
    }

    .user-dropdown .dd-icon {
      width: 18px;
      text-align: center;
    }

    .user-dropdown .danger:hover {
      background: #fef2f2;
      color: #dc2626;
    }

    /* ===== CUSTOM SELECT DROPDOWN ===== */
    .custom-select-wrapper {
      position: relative;
      width: 300px;
    }

    .custom-select {
      width: 100%;
      padding: 12px 40px 12px 16px;
      border: 2px solid #e2e8f0;
      border-radius: 10px;
      font-size: 15px;
      background: white;
      appearance: none;
      cursor: pointer;
      transition: border-color 0.3s;
    }

    .custom-select:focus {
      border-color: #667eea;
      outline: none;
    }

    .custom-select-arrow {
      position: absolute;
      right: 14px;
      top: 50%;
      transform: translateY(-50%);
      color: #94a3b8;
      pointer-events: none;
      font-size: 14px;
    }

    /* ===== RIGHT-ALIGNED DROPDOWN ===== */
    .dropdown-right .dropdown-menu {
      left: auto;
      right: 0;
    }

    .dropdown-right .dropdown-menu::before {
      left: auto;
      right: 20px;
    }

    /* ===== CONTEXT MENU STYLE ===== */
    .context-area {
      width: 100%;
      height: 300px;
      background: white;
      border-radius: 12px;
      display: flex;
      align-items: center;
      justify-content: center;
      color: #94a3b8;
      border: 2px dashed #e2e8f0;
      user-select: none;
    }
  </style>
</head>
<body>
  <!-- Basic Dropdown -->
  <div class="section">
    <h2>Basic Dropdown</h2>
    <span class="label">opacity + visibility + transform + z-index</span>
    <div class="dropdown">
      <button class="dropdown-trigger">Select Action</button>
      <div class="dropdown-menu">
        <a href="#"><span class="icon">✏️</span> Edit Profile</a>
        <a href="#"><span class="icon">⚙️</span> Settings</a>
        <a href="#"><span class="icon">📊</span> Dashboard</a>
        <div class="dropdown-divider"></div>
        <a href="#"><span class="icon">💬</span> Message</a>
        <a href="#"><span class="icon">🔔</span> Notifikasi</a>
        <div class="dropdown-divider"></div>
        <a href="#" class="danger"><span class="icon">🚪</span> Log Out</a>
      </div>
    </div>
  </div>

  <!-- Nav Dropdown -->
  <div class="section">
    <h2>Navigation Dropdown</h2>
    <span class="label">position: absolute + :hover + :focus-within</span>
    <nav class="nav-bar">
      <div class="nav-item">
        <a href="#">Home</a>
      </div>
      <div class="nav-item">
        <a href="#">Products</a>
        <div class="nav-dropdown">
          <div class="nav-group-title">Kategori</div>
          <a href="#">
            <span class="nav-icon">💻</span>
            <div>
              <div>Technology</div>
              <div class="nav-desc">Tutorial programming</div>
            </div>
          </a>
          <a href="#">
            <span class="nav-icon">🎨</span>
            <div>
              <div>Desain</div>
              <div class="nav-desc">UI/UX & Grafis</div>
            </div>
          </a>
          <a href="#">
            <span class="nav-icon">📈</span>
            <div>
              <div>Bisnis</div>
              <div class="nav-desc">Strategi & Marketing</div>
            </div>
          </a>
          <a href="#">
            <span class="nav-icon">📸</span>
            <div>
              <div>Photos & Videos</div>
              <div class="nav-desc">Editing & Production</div>
            </div>
          </a>
        </div>
      </div>
      <div class="nav-item">
        <a href="#">Mentor</a>
      </div>
      <div class="nav-item">
        <a href="#">More</a>
        <div class="nav-dropdown">
          <a href="#"><span class="nav-icon">📖</span> Blog</a>
          <a href="#"><span class="nav-icon">❓</span> FAQ</a>
          <a href="#"><span class="nav-icon">📞</span> Kontak</a>
          <a href="#"><span class="nav-icon">📋</span> Syarat & Ketentuan</a>
        </div>
      </div>
    </nav>
  </div>

  <!-- User Menu -->
  <div class="section">
    <h2>User Menu Dropdown</h2>
    <span class="label">position: absolute right + focus-within</span>
    <div class="user-menu-container">
      <div class="user-menu">
        <button class="user-menu-trigger">
          <div class="user-menu-avatar">BS</div>
          <span class="user-menu-name">John Smith</span>
          <span class="user-menu-arrow">▾</span>
        </button>
        <div class="user-dropdown">
          <div class="user-dropdown-header">
            <div class="name">John Smith</div>
            <div class="email">[email protected]</div>
          </div>
          <a href="#"><span class="dd-icon">👤</span> My Profile</a>
          <a href="#"><span class="dd-icon">⚙️</span> Settings</a>
          <a href="#"><span class="dd-icon">📊</span> Dashboard</a>
          <a href="#"><span class="dd-icon">💳</span> Langganan</a>
          <div class="dropdown-divider"></div>
          <a href="#"><span class="dd-icon">❓</span> Bantuan</a>
          <button class="danger"><span class="dd-icon">🚪</span> Log Out</button>
        </div>
      </div>
    </div>
  </div>

  <!-- Custom Select -->
  <div class="section">
    <h2>Custom Select Dropdown</h2>
    <span class="label">appearance: none + custom arrow</span>
    <div class="custom-select-wrapper">
      <select class="custom-select">
        <option value="">Select Programming Language</option>
        <option value="html">HTML</option>
        <option value="css">CSS</option>
        <option value="javascript">JavaScript</option>
        <option value="python">Python</option>
        <option value="java">Java</option>
        <option value="go">Go</option>
        <option value="rust">Rust</option>
      </select>
      <span class="custom-select-arrow">▾</span>
    </div>
  </div>

  <!-- Right-Aligned -->
  <div class="section">
    <h2>Right-Aligned Dropdown</h2>
    <span class="label">left: auto; right: 0;</span>
    <div style="display: flex; justify-content: flex-end;">
      <div class="dropdown dropdown-right">
        <button class="dropdown-trigger">Opsi ⚙️</button>
        <div class="dropdown-menu">
          <a href="#"><span class="icon">📋</span> Copy Link</a>
          <a href="#"><span class="icon">📤</span> Share</a>
          <a href="#"><span class="icon">⬇️</span> Download</a>
          <div class="dropdown-divider"></div>
          <a href="#" class="danger"><span class="icon">🗑️</span> Delete</a>
        </div>
      </div>
    </div>
  </div>
</body>
</html>

Code Explanation

Hidden Default State

The dropdown content is hidden with a combination of three properties:

.dropdown-menu {
  opacity: 0;           /* Transparent */
  visibility: hidden;   /* Not clickable */
  transform: translateY(-10px);  /* Slightly upward */
  transition: all 0.3s; /* Smooth animation */
}

Why not display: none? Because display: none cannot be animated. The combination of opacity + visibility allows a smooth transition.

Hover Reveal

Shows the dropdown when the parent is hovered:

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

position: absolute

The dropdown menu must be taken out of the document flow so it does not affect the other layout:

.dropdown {
  position: relative;  /* Anchor for the dropdown */
}

.dropdown-menu {
  position: absolute;  /* Floating */
  top: calc(100% + 8px); /* 8px below the trigger */
  left: 0;
}

z-index

Ensures the dropdown sits above other content:

.dropdown-menu {
  z-index: 100;
}

Stacking Context Scale:
- Dropdown: z-index: 1000
- Sticky: 1020
- Fixed: 1030
- Modal: 1040
- Popover: 1050
- Toast: 1060

:focus-within

Important for accessibility — the dropdown stays open when an element inside it is focused with the keyboard:

.dropdown:hover .dropdown-menu,
.dropdown:focus-within .dropdown-menu {
  opacity: 1;
  visibility: visible;
}

transition

Smooth animation effects:

.dropdown-menu {
  transition: opacity 0.3s, visibility 0.3s, transform 0.3s;
}

Everyday Use Cases

1. Action Dropdown in a Table

<!DOCTYPE html>
<html lang="en">
<head>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }

    .table-wrapper {
      padding: 20px;
      background: white;
      border-radius: 12px;
      box-shadow: 0 2px 10px rgba(0,0,0,0.08);
      max-width: 700px;
    }

    table {
      width: 100%;
      border-collapse: collapse;
    }

    th, td {
      padding: 14px 16px;
      text-align: left;
      border-bottom: 1px solid #e2e8f0;
    }

    th {
      background: #f8fafc;
      font-weight: 600;
      color: #475569;
      font-size: 13px;
      text-transform: uppercase;
      letter-spacing: 0.5px;
    }

    .action-cell {
      position: relative;
    }

    .action-btn {
      padding: 6px 12px;
      background: #f1f5f9;
      border: 1px solid #e2e8f0;
      border-radius: 6px;
      cursor: pointer;
      font-size: 13px;
      transition: all 0.2s;
    }

    .action-btn:hover {
      background: #e2e8f0;
    }

    .action-dropdown {
      position: absolute;
      top: calc(100% + 4px);
      right: 0;
      background: white;
      border-radius: 10px;
      box-shadow: 0 10px 30px rgba(0,0,0,0.12);
      min-width: 160px;
      padding: 6px;
      opacity: 0;
      visibility: hidden;
      transform: translateY(-5px);
      transition: all 0.2s;
      z-index: 50;
    }

    .action-cell:hover .action-dropdown {
      opacity: 1;
      visibility: visible;
      transform: translateY(0);
    }

    .action-dropdown a {
      display: flex;
      align-items: center;
      gap: 8px;
      padding: 8px 12px;
      color: #475569;
      text-decoration: none;
      border-radius: 6px;
      font-size: 13px;
      transition: all 0.2s;
    }

    .action-dropdown a:hover {
      background: #f1f5f9;
      color: #667eea;
    }

    .action-dropdown .del:hover {
      background: #fef2f2;
      color: #dc2626;
    }
  </style>
</head>
<body>
  <div class="table-wrapper">
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Email</th>
          <th>Status</th>
          <th>Action</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>John Smith</td>
          <td>[email protected]</td>
          <td>Active</td>
          <td class="action-cell">
            <button class="action-btn">⋯</button>
            <div class="action-dropdown">
              <a href="#">✏️ Edit</a>
              <a href="#">👁️ View</a>
              <a href="#">📋 Duplikat</a>
              <a href="#">📤 Ekspor</a>
              <div style="height:1px;background:#e2e8f0;margin:4px 0;"></div>
              <a href="#" class="del">🗑️ Delete</a>
            </div>
          </td>
        </tr>
        <tr>
          <td>Amy Lee</td>
          <td>[email protected]</td>
          <td>Active</td>
          <td class="action-cell">
            <button class="action-btn">⋯</button>
            <div class="action-dropdown">
              <a href="#">✏️ Edit</a>
              <a href="#">👁️ View</a>
              <a href="#">📋 Duplikat</a>
              <a href="#">📤 Ekspor</a>
              <div style="height:1px;background:#e2e8f0;margin:4px 0;"></div>
              <a href="#" class="del">🗑️ Delete</a>
            </div>
          </td>
        </tr>
        <tr>
          <td>Mike Williams</td>
          <td>[email protected]</td>
          <td>Pending</td>
          <td class="action-cell">
            <button class="action-btn">⋯</button>
            <div class="action-dropdown">
              <a href="#">✏️ Edit</a>
              <a href="#">👁️ View</a>
              <a href="#">📋 Duplikat</a>
              <a href="#">📤 Ekspor</a>
              <div style="height:1px;background:#e2e8f0;margin:4px 0;"></div>
              <a href="#" class="del">🗑️ Delete</a>
            </div>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</body>
</html>

2. Filter Dropdown

<!DOCTYPE html>
<html lang="en">
<head>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }

    .filter-bar {
      display: flex;
      gap: 12px;
      padding: 20px;
      flex-wrap: wrap;
    }

    .filter-dropdown {
      position: relative;
    }

    .filter-trigger {
      padding: 10px 16px;
      background: white;
      border: 2px solid #e2e8f0;
      border-radius: 8px;
      cursor: pointer;
      font-size: 14px;
      display: flex;
      align-items: center;
      gap: 8px;
      transition: border-color 0.3s;
    }

    .filter-trigger:hover {
      border-color: #667eea;
    }

    .filter-trigger::after {
      content: '▾';
      font-size: 10px;
      color: #94a3b8;
    }

    .filter-dropdown .filter-menu {
      position: absolute;
      top: calc(100% + 6px);
      left: 0;
      background: white;
      border-radius: 10px;
      box-shadow: 0 10px 30px rgba(0,0,0,0.12);
      min-width: 200px;
      padding: 8px;
      opacity: 0;
      visibility: hidden;
      transform: translateY(-8px);
      transition: all 0.2s;
      z-index: 50;
    }

    .filter-dropdown:hover .filter-menu {
      opacity: 1;
      visibility: visible;
      transform: translateY(0);
    }

    .filter-option {
      display: flex;
      align-items: center;
      gap: 10px;
      padding: 9px 12px;
      border-radius: 6px;
      cursor: pointer;
      transition: background 0.2s;
      font-size: 14px;
    }

    .filter-option:hover {
      background: #f1f5f9;
    }

    .filter-option input[type="checkbox"] {
      accent-color: #667eea;
    }

    .active-filter {
      background: #eef2ff;
      border-color: #667eea;
      color: #667eea;
    }

    .active-count {
      background: #667eea;
      color: white;
      font-size: 11px;
      padding: 1px 7px;
      border-radius: 10px;
      font-weight: bold;
    }
  </style>
</head>
<body>
  <div class="filter-bar">
    <div class="filter-dropdown">
      <div class="filter-trigger active-filter">
        Kategori <span class="active-count">2</span>
      </div>
      <div class="filter-menu">
        <label class="filter-option">
          <input type="checkbox" checked> Technology
        </label>
        <label class="filter-option">
          <input type="checkbox" checked> Desain
        </label>
        <label class="filter-option">
          <input type="checkbox"> Bisnis
        </label>
        <label class="filter-option">
          <input type="checkbox"> Marketing
        </label>
        <label class="filter-option">
          <input type="checkbox"> Photos & Videos
        </label>
      </div>
    </div>

    <div class="filter-dropdown">
      <div class="filter-trigger">Price</div>
      <div class="filter-menu">
        <label class="filter-option">
          <input type="checkbox"> Gratis
        </label>
        <label class="filter-option">
          <input type="checkbox"> $0 - $100
        </label>
        <label class="filter-option">
          <input type="checkbox"> $100 - $500
        </label>
        <label class="filter-option">
          <input type="checkbox"> $500+
        </label>
      </div>
    </div>

    <div class="filter-dropdown">
      <div class="filter-trigger">Rating</div>
      <div class="filter-menu">
        <label class="filter-option">
          <input type="checkbox"> ⭐⭐⭐⭐⭐
        </label>
        <label class="filter-option">
          <input type="checkbox"> ⭐⭐⭐⭐+
        </label>
        <label class="filter-option">
          <input type="checkbox"> ⭐⭐⭐+
        </label>
      </div>
    </div>
  </div>
</body>
</html>

Conclusion

CSS Dropdowns lets you create interactive menus without JavaScript. Key points:

  1. Hide with opacity: 0 + visibility: hidden (not display: none)
  2. position: absolute — The dropdown floats above the other content
  3. z-index — Make sure the dropdown sits above overlapping content
  4. :focus-within — Important for keyboard accessibility
  5. transition — Smooth animation effects for good UX
  6. Arrow indicator — A small arrow on the trigger signals that a dropdown exists

For more complex dropdowns (with keyboard navigation, focus trapping, etc.), consider using a library or vanilla JavaScript.