AI CSS Animations

Glass Stacked Cards

Three frosted cards stacked like a deck, each layer thickening the blur behind the next. Hover and they fan out with a staggered spring so every card shows. Transforms only, so it stays smooth.

Also known as: glassmorphism card stack css, stacked cards hover effect, fan out cards css.

Icon set

900 glyphs

Motion presets

120 easings

Glass UI kit

48 components

Make this your own with AI

HTML

<div class="gls-glass-stacked-cards">
  <div class="gls-glass-stacked-cards-orbit" aria-hidden="true">
    <span class="gls-glass-stacked-cards-blob"></span>
    <span class="gls-glass-stacked-cards-blob"></span>
  </div>
  <div class="gls-glass-stacked-cards-stack">
    <article class="gls-glass-stacked-cards-card">
      <span class="gls-glass-stacked-cards-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 3l2.6 5.6 6.1.7-4.5 4.2 1.2 6L12 16.5 6.6 19.5l1.2-6-4.5-4.2 6.1-.7z"/></svg></span>
      <h3 class="gls-glass-stacked-cards-title">Icon set</h3>
      <p class="gls-glass-stacked-cards-meta">900 glyphs</p>
    </article>
    <article class="gls-glass-stacked-cards-card">
      <span class="gls-glass-stacked-cards-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"><path d="M3 17c3.5 0 4-10 9-10s5.5 10 9 10"/></svg></span>
      <h3 class="gls-glass-stacked-cards-title">Motion presets</h3>
      <p class="gls-glass-stacked-cards-meta">120 easings</p>
    </article>
    <article class="gls-glass-stacked-cards-card">
      <span class="gls-glass-stacked-cards-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linejoin="round"><rect x="4" y="4" width="16" height="16" rx="4"/><path d="M4 10h16M10 10v10"/></svg></span>
      <h3 class="gls-glass-stacked-cards-title">Glass UI kit</h3>
      <p class="gls-glass-stacked-cards-meta">48 components</p>
    </article>
  </div>
</div>

CSS

.gls-glass-stacked-cards {
  --c: var(--gls-color, #3b82f6);
  font-size: var(--gls-size, 16px);
  position: relative;
  display: grid;
  place-items: center;
  width: 22em;
  height: 12em;
  border-radius: 1.25em;
  overflow: hidden;
  isolation: isolate;
  background: linear-gradient(135deg, color-mix(in srgb, var(--c) 40%, #0f172a), color-mix(in srgb, var(--c) 25%, #312e81));
  color: #fff;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  line-height: 1.3;
}
.gls-glass-stacked-cards-orbit {
  position: absolute;
  inset: 0;
  z-index: -1;
  animation: gls-glass-stacked-cards-spin 18s linear infinite;
}
.gls-glass-stacked-cards-blob {
  position: absolute;
  border-radius: 50%;
}
.gls-glass-stacked-cards-blob:nth-child(1) {
  left: 4em;
  top: 0.4em;
  width: 7em;
  height: 7em;
  background: linear-gradient(135deg, color-mix(in srgb, var(--c) 40%, #fff), var(--c));
}
.gls-glass-stacked-cards-blob:nth-child(2) {
  right: 4.5em;
  bottom: 0.6em;
  width: 5em;
  height: 5em;
  background: linear-gradient(135deg, #fcd34d, #ec4899);
}
.gls-glass-stacked-cards-stack {
  position: relative;
  width: 7.4em;
  height: 5.2em;
  margin-top: 1em;
}
.gls-glass-stacked-cards-card {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  padding: 0.7em 0.8em;
  border-radius: 1em;
  background: color-mix(in srgb, #fff 14%, 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);
  transition: transform 0.6s cubic-bezier(0.34, 1.35, 0.64, 1);
}
.gls-glass-stacked-cards-card:nth-child(1) {
  transform: translate(0, -1.25em) rotate(0) scale(0.86);
  transition-delay: 0.1s;
}
.gls-glass-stacked-cards-card:nth-child(2) {
  transform: translate(0, -0.62em) rotate(0) scale(0.93);
  transition-delay: 0.05s;
}
.gls-glass-stacked-cards-card:nth-child(3) { transform: translate(0, 0) rotate(0) scale(1); }
/* fanned like a hand of cards: each card overlaps the one on its left, so every title shows */
.gls-glass-stacked-cards:hover .gls-glass-stacked-cards-card:nth-child(1) { transform: translate(-6em, 0.35em) rotate(-8deg) scale(1); }
.gls-glass-stacked-cards:hover .gls-glass-stacked-cards-card:nth-child(2) { transform: translate(0, -0.45em) rotate(0) scale(1); }
.gls-glass-stacked-cards:hover .gls-glass-stacked-cards-card:nth-child(3) { transform: translate(6em, 0.35em) rotate(8deg) scale(1); }
.gls-glass-stacked-cards-icon {
  display: grid;
  place-items: center;
  width: 1.7em;
  height: 1.7em;
  margin-bottom: auto;
  border-radius: 0.5em;
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.5);
}
.gls-glass-stacked-cards-card:nth-child(1) .gls-glass-stacked-cards-icon { background: linear-gradient(135deg, #fde68a, #f97316); }
.gls-glass-stacked-cards-card:nth-child(2) .gls-glass-stacked-cards-icon { background: linear-gradient(135deg, #f9a8d4, #a855f7); }
.gls-glass-stacked-cards-card:nth-child(3) .gls-glass-stacked-cards-icon { background: linear-gradient(135deg, color-mix(in srgb, var(--c) 40%, #fff), var(--c)); }
.gls-glass-stacked-cards-icon svg { width: 1em; height: 1em; }
.gls-glass-stacked-cards-title {
  margin: 0;
  font-size: 0.78em;
  font-weight: 700;
}
.gls-glass-stacked-cards-meta {
  margin: 0.15em 0 0;
  font-size: 0.6em;
  color: rgb(255 255 255 / 0.78);
}
@keyframes gls-glass-stacked-cards-spin {
  to { transform: rotate(1turn); }
}

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

Tailwind CSS version

The same effect using Tailwind utility classes. No custom CSS or config needed.

<div class="group relative isolate grid h-48 w-[22rem] place-items-center overflow-hidden rounded-[1.25rem] bg-gradient-to-br from-slate-900 to-indigo-900 font-sans text-white">
  <div class="absolute inset-0 -z-10 animate-[spin_18s_linear_infinite]" aria-hidden="true">
    <span class="absolute left-16 top-[0.4rem] h-28 w-28 rounded-full bg-gradient-to-br from-sky-300 to-blue-500"></span>
    <span class="absolute bottom-[0.6rem] right-[4.5rem] h-20 w-20 rounded-full bg-gradient-to-br from-amber-300 to-pink-500"></span>
  </div>
  <div class="relative mt-4 h-[5.2rem] w-[7.4rem]">
    <article class="absolute inset-0 flex -translate-y-5 scale-[0.86] flex-col rounded-2xl border border-white/45 bg-white/[0.14] px-3 py-2.5 shadow-[0_0.5rem_1.5rem_-0.5rem_rgb(0_0_0/0.35),inset_0_1px_0_rgb(255_255_255/0.55)] backdrop-blur-[0.9rem] backdrop-saturate-150 transition-transform delay-100 duration-[600ms] ease-[cubic-bezier(0.34,1.35,0.64,1)] group-hover:-translate-x-24 group-hover:translate-y-[0.35rem] group-hover:-rotate-[8deg] group-hover:scale-100">
      <span class="mb-auto grid h-7 w-7 place-items-center rounded-lg bg-gradient-to-br from-amber-200 to-orange-500" aria-hidden="true">
        <svg class="h-4 w-4" viewBox="0 0 24 24" fill="currentColor"><path d="M12 3l2.6 5.6 6.1.7-4.5 4.2 1.2 6L12 16.5 6.6 19.5l1.2-6-4.5-4.2 6.1-.7z"/></svg>
      </span>
      <h3 class="text-[0.78rem] font-bold">Icon set</h3>
      <p class="mt-0.5 text-[0.6rem] text-white/80">900 glyphs</p>
    </article>
    <article class="absolute inset-0 flex -translate-y-[0.62rem] scale-[0.93] flex-col rounded-2xl border border-white/45 bg-white/[0.14] px-3 py-2.5 shadow-[0_0.5rem_1.5rem_-0.5rem_rgb(0_0_0/0.35),inset_0_1px_0_rgb(255_255_255/0.55)] backdrop-blur-[0.9rem] backdrop-saturate-150 transition-transform delay-[50ms] duration-[600ms] ease-[cubic-bezier(0.34,1.35,0.64,1)] group-hover:-translate-y-[0.45rem] group-hover:scale-100">
      <span class="mb-auto grid h-7 w-7 place-items-center rounded-lg bg-gradient-to-br from-pink-300 to-purple-500" aria-hidden="true">
        <svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"><path d="M3 17c3.5 0 4-10 9-10s5.5 10 9 10"/></svg>
      </span>
      <h3 class="text-[0.78rem] font-bold">Motion presets</h3>
      <p class="mt-0.5 text-[0.6rem] text-white/80">120 easings</p>
    </article>
    <article class="absolute inset-0 flex flex-col rounded-2xl border border-white/45 bg-white/[0.14] px-3 py-2.5 shadow-[0_0.5rem_1.5rem_-0.5rem_rgb(0_0_0/0.35),inset_0_1px_0_rgb(255_255_255/0.55)] backdrop-blur-[0.9rem] backdrop-saturate-150 transition-transform duration-[600ms] ease-[cubic-bezier(0.34,1.35,0.64,1)] group-hover:translate-x-24 group-hover:translate-y-[0.35rem] group-hover:rotate-[8deg]">
      <span class="mb-auto grid h-7 w-7 place-items-center rounded-lg bg-gradient-to-br from-sky-300 to-blue-500" aria-hidden="true">
        <svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linejoin="round"><rect x="4" y="4" width="16" height="16" rx="4"/><path d="M4 10h16M10 10v10"/></svg>
      </span>
      <h3 class="text-[0.78rem] font-bold">Glass UI kit</h3>
      <p class="mt-0.5 text-[0.6rem] text-white/80">48 components</p>
    </article>
  </div>
</div>

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