AI CSS Animations

Glass Dropdown Menu

A frosted dropdown built on details and summary, so it opens and closes with no script. The chevron flips, the panel drops in with its items staggered, and the danger row sits under a divider.

Also known as: glassmorphism dropdown menu css, frosted dropdown css, glass context menu.

HTML

<div class="gls-glass-dropdown-menu">
  <span class="gls-glass-dropdown-menu-orb gls-glass-dropdown-menu-orb-a" aria-hidden="true"></span>
  <span class="gls-glass-dropdown-menu-orb gls-glass-dropdown-menu-orb-b" aria-hidden="true"></span>
  <details class="gls-glass-dropdown-menu-menu" open>
    <summary class="gls-glass-dropdown-menu-trigger">
      <span class="gls-glass-dropdown-menu-avatar" aria-hidden="true">A</span>
      Acme Studio
      <svg class="gls-glass-dropdown-menu-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg>
    </summary>
    <ul class="gls-glass-dropdown-menu-list">
      <li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 3H6.5A1.5 1.5 0 0 0 5 4.5v15A1.5 1.5 0 0 0 6.5 21h11a1.5 1.5 0 0 0 1.5-1.5V8zM14 3v5h5M12 11v6M9 14h6"/></svg>New file<kbd>⌘N</kbd></a></li>
      <li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 15V3M8 7l4-4 4 4M5 12v7.5A1.5 1.5 0 0 0 6.5 21h11a1.5 1.5 0 0 0 1.5-1.5V12"/></svg>Share<kbd>⌘S</kbd></a></li>
      <li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2"/><path d="M16 8V5.5A1.5 1.5 0 0 0 14.5 4h-9A1.5 1.5 0 0 0 4 5.5v9A1.5 1.5 0 0 0 5.5 16H8"/></svg>Duplicate<kbd>⌘D</kbd></a></li>
      <li class="gls-glass-dropdown-menu-danger"><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4.5h6V7M6.5 7l1 13h9l1-13"/></svg>Delete<kbd>⌫</kbd></a></li>
    </ul>
  </details>
</div>

CSS

.gls-glass-dropdown-menu {
  --c: var(--gls-color, #3b82f6);
  font-size: var(--gls-size, 16px);
  position: relative;
  display: grid;
  justify-items: center;
  align-content: start;
  width: 22em;
  height: 12em;
  border-radius: 1.25em;
  overflow: hidden;
  isolation: isolate;
  background: linear-gradient(150deg, color-mix(in srgb, var(--c) 45%, #0f172a), color-mix(in srgb, var(--c) 25%, #581c87));
  color: #fff;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  line-height: 1.3;
}
.gls-glass-dropdown-menu-orb {
  position: absolute;
  z-index: -1;
  border-radius: 50%;
}
.gls-glass-dropdown-menu-orb-a {
  left: 3.5em;
  top: 3.5em;
  width: 6em;
  height: 6em;
  background: linear-gradient(135deg, color-mix(in srgb, var(--c) 40%, #fff), var(--c));
  animation: gls-glass-dropdown-menu-orb 7s ease-in-out infinite alternate;
}
.gls-glass-dropdown-menu-orb-b {
  right: 3.2em;
  top: 5.5em;
  width: 5em;
  height: 5em;
  background: linear-gradient(135deg, #fde68a, #f472b6);
  animation: gls-glass-dropdown-menu-orb 8s ease-in-out -4s infinite alternate-reverse;
}
.gls-glass-dropdown-menu-menu {
  position: relative;
  margin-top: 0.8em;
}
.gls-glass-dropdown-menu-trigger {
  display: flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.35em 0.75em 0.35em 0.35em;
  border-radius: 99em;
  background: color-mix(in srgb, #fff 18%, transparent);
  -webkit-backdrop-filter: blur(0.9em) saturate(1.5);
  backdrop-filter: blur(0.9em) saturate(1.5);
  border: 1px solid color-mix(in srgb, #fff 45%, transparent);
  box-shadow: 0 0.5em 1.5em -0.5em rgb(0 0 0 / 0.35), inset 0 1px 0 color-mix(in srgb, #fff 55%, transparent);
  font-size: 0.82em;
  font-weight: 600;
  list-style: none;
  cursor: pointer;
  transition: background-color 0.25s ease;
}
.gls-glass-dropdown-menu-trigger::-webkit-details-marker { display: none; }
.gls-glass-dropdown-menu-trigger:hover { background-color: rgb(255 255 255 / 0.26); }
.gls-glass-dropdown-menu-trigger:focus-visible { outline: 2px solid #fff; outline-offset: 0.15em; }
.gls-glass-dropdown-menu-avatar {
  display: grid;
  place-items: center;
  width: 1.6em;
  height: 1.6em;
  border-radius: 50%;
  background: linear-gradient(135deg, #fda4af, var(--c));
  font-size: 0.85em;
  font-weight: 750;
}
.gls-glass-dropdown-menu-chevron {
  width: 1em;
  height: 1em;
  transition: rotate 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.gls-glass-dropdown-menu-menu[open] .gls-glass-dropdown-menu-chevron { rotate: 180deg; }
.gls-glass-dropdown-menu-list {
  position: absolute;
  top: calc(100% + 0.45em);
  left: 50%;
  width: 12.5em;
  margin: 0;
  padding: 0.35em;
  border-radius: 1em;
  list-style: none;
  background: color-mix(in srgb, #fff 20%, transparent);
  -webkit-backdrop-filter: blur(0.9em) saturate(1.5);
  backdrop-filter: blur(0.9em) saturate(1.5);
  border: 1px solid color-mix(in srgb, #fff 45%, transparent);
  box-shadow: 0 0.5em 1.5em -0.5em rgb(0 0 0 / 0.35), inset 0 1px 0 color-mix(in srgb, #fff 55%, transparent);
  translate: -50% 0;
  transform-origin: 50% 0;
  animation: gls-glass-dropdown-menu-drop 0.45s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.gls-glass-dropdown-menu-list a {
  display: flex;
  align-items: center;
  gap: 0.65em;
  padding: 0.5em 0.6em;
  border-radius: 0.6em;
  color: inherit;
  font-size: 0.72em;
  font-weight: 550;
  text-decoration: none;
  animation: gls-glass-dropdown-menu-item 0.4s cubic-bezier(0.22, 1, 0.36, 1) both;
  transition: background-color 0.2s ease;
}
.gls-glass-dropdown-menu-list li:nth-child(2) a { animation-delay: 0.05s; }
.gls-glass-dropdown-menu-list li:nth-child(3) a { animation-delay: 0.1s; }
.gls-glass-dropdown-menu-list li:nth-child(4) a { animation-delay: 0.15s; }
.gls-glass-dropdown-menu-list a:hover { background: rgb(255 255 255 / 0.2); }
.gls-glass-dropdown-menu-list a:focus-visible { outline: 2px solid #fff; outline-offset: -2px; }
.gls-glass-dropdown-menu-list svg { flex: none; width: 1.15em; height: 1.15em; opacity: 0.9; }
.gls-glass-dropdown-menu-list kbd {
  margin-left: auto;
  font: inherit;
  font-size: 0.9em;
  opacity: 0.6;
}
.gls-glass-dropdown-menu-danger {
  margin-top: 0.3em;
  padding-top: 0.3em;
  border-top: 1px solid rgb(255 255 255 / 0.22);
}
.gls-glass-dropdown-menu-danger a { color: #fecdd3; }
.gls-glass-dropdown-menu-danger a:hover { background: rgb(244 63 94 / 0.28); color: #fff; }
@keyframes gls-glass-dropdown-menu-drop {
  from { opacity: 0; transform: translateY(-0.5em) scale(0.95); }
}
@keyframes gls-glass-dropdown-menu-item {
  from { opacity: 0; transform: translateY(-0.35em); }
}
@keyframes gls-glass-dropdown-menu-orb {
  to { transform: translate(2em, -1.2em) scale(1.1); }
}

@media (prefers-reduced-motion: reduce) {
  .gls-glass-dropdown-menu, .gls-glass-dropdown-menu *, .gls-glass-dropdown-menu::before, .gls-glass-dropdown-menu::after, .gls-glass-dropdown-menu *::before, .gls-glass-dropdown-menu *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Customizing this snippet

  • Color: set --gls-color on the element or a parent. Currently previewing #3b82f6.
  • Base size: set --gls-size. Every other dimension is in em, so the whole thing scales together. Currently previewing 16px.
  • Speed: change the duration on the transition or animation shorthand. Staggered delays are relative, so they keep their rhythm.
  • Reduced motion: the rule at the end of the CSS turns the motion off for people who asked their OS for less of it. Keep it.

Similar glass effects