Home / Snippets / Animation /

Delay chain transition

Stagger transition-delay on child elements to animate them in sequence — hover the group below.

Widely Supported
animationno-js

Quick implementation

/* HTML: <div class="chain"><div class="chain-item"></div> × N </div> */

.chain-item {
  opacity: 0;
  transform: translateY(1rem);
  transition: opacity 0.4s ease-out, transform 0.4s ease-out;
}

/* Stagger each child by 100ms */
.chain-item:nth-child(1) { transition-delay: 0s; }
.chain-item:nth-child(2) { transition-delay: 0.1s; }
.chain-item:nth-child(3) { transition-delay: 0.1s; }
.chain-item:nth-child(4) { transition-delay: 0.3s; }
.chain-item:nth-child(5) { transition-delay: 0.4s; }

/* Trigger on parent hover or focus-within */
.chain:hover .chain-item,
.chain:focus-within .chain-item {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .chain-item {
    transition-duration: 0.01s;
    transition-delay: 0s;
  }
}

Prompt this to your LLM

Includes role, constraints, two framework variants, and edge cases to handle.

You are a senior frontend engineer building staggered reveal animations.

Goal: A row of child elements that fade-and-slide in one after another using only CSS transition-delay — no JavaScript, no @keyframes.

Technical constraints:
- Each child gets an incremental transition-delay via :nth-child() (e.g. 0s, 0.1s, 0.2s …).
- Animate opacity and transform: translateY() for a slide-up entrance.
- Trigger the chain on parent :hover and :focus-within.
- Use oklch() for all color values — no hex or rgba().
- Keep the base transition-duration under 0.5s to feel snappy.

Framework variant (pick one):
A) Vanilla HTML + CSS only.
B) React component — accept items[] prop and a staggerMs prop to set the delay increment.

Edge cases to handle:
- Respect prefers-reduced-motion: collapse delay to 0s and duration to near-instant.
- Ensure the reverse-out animation plays when the parent loses hover.
- If the list has more than 10 items, cap total chain time to avoid sluggish reveals.

Return HTML + CSS.

Why this matters in 2026

Staggered reveals used to require JavaScript libraries like GSAP or Framer Motion to orchestrate timing. With native transition-delay and :nth-child(), the same sequential entrance effect is achievable in pure CSS. This removes a runtime dependency, works without hydration, and keeps the animation layer in the stylesheet where it belongs.

The logic

Every child starts with opacity: 0 and a small translateY offset. A shared transition shorthand covers both properties. The stagger comes from assigning each :nth-child(n) a progressively larger transition-delay — 0s for the first, 0.1s for the second, and so on. When the parent receives :hover or :focus-within, all children transition to their visible state, but each waits its designated delay before starting, producing the cascade effect.

Accessibility & performance

opacity and transform are compositor-friendly properties — they avoid layout recalculations and run on the GPU. Wrap the delay assignments in a prefers-reduced-motion media query to collapse all delays to zero for users who prefer minimal motion. Adding :focus-within as a trigger ensures keyboard users can activate the animation by tabbing into the group.