How to copy an animation from a website

The one thing a screenshot can never give you. Here is how to read the duration, the easing curve and the keyframes off a live page — including animations no CSS file describes.

Updated September 2026 · by the Design Toolkit team

The short answer

Open DevTools, go to the Animations panel and record while the animation fires. It lists what ran and for how long. For a transition, read transition-duration and transition-timing-function in the Styles panel; for a keyframe animation, search the stylesheet for the animation name. For anything built in JavaScript, run element.getAnimations() in the console — it returns the timing and the keyframes the browser is actually running.

Why animations are harder to copy than layouts

A layout sits still and lets you measure it. An animation is over in 300 milliseconds, and the three things that define it are all invisible in a still frame:

Then there is the trigger: hover, scroll, load, or a state change. Same animation, different trigger, different thing entirely.

1. Find what is animating

Open DevTools, then the Animations panel (in the drawer, under the three-dot menu → More tools). Hit record and make the animation happen. Every animation that fires shows up as a bar on a timeline, with its element and its duration.

The panel also lets you slow playback to 25% or 10%, which is the fastest way to see what is actually moving when several things fire at once.

2. Read the timing and the curve

For a CSS transition, the Styles panel has everything:

transition-property: background-color, transform;
transition-duration: 220ms;
transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);
transition-delay: 0s;

That cubic-bezier with a second value above 1 is a spring — it overshoots the target and settles back. Copy the duration without it and your version will feel flat, at exactly the right speed.

For a keyframe animation, the shorthand carries the same information: animation: spin 1.4s linear infinite.

3. Get the keyframes

The animation name points at a block somewhere in the stylesheet:

@keyframes float {
  0%   { transform: translateY(0); }
  50%  { transform: translateY(-8px); }
  100% { transform: translateY(0); }
}

Find it with the search in the Sources panel. When the stylesheet comes from another domain and cannot be read as text — common on any site with a CDN — go around it:

$0.getAnimations().map(a => ({
  name: a.animationName,
  timing: a.effect.getComputedTiming(),
  frames: a.effect.getKeyframes()
}))

With an element selected in the Elements panel, $0 is that element. This reports what the browser is running, whatever its source.

4. Check the trigger

Worth a moment, because it is the most common reason a faithful copy feels wrong. Ask:

The JavaScript case

A growing share of the motion you want to copy is not in any stylesheet. GSAP, Motion, Framer Motion and hand-written code all drive the Web Animations API, which means the animation exists on the element with no CSS describing it.

getAnimations() is the answer, and it is genuinely complete: the timing, the iterations, the direction, and the computed keyframes. A tool that only reads stylesheets will tell you there is no animation on an element that is visibly moving.

An animation panel listing transitions with their durations, easing curves drawn as graphs, and keyframes
Transitions with their durations, the easing drawn as a curve rather than left as numbers, and the keyframes behind each animation.

The shortcut

All of the above is four panels and a console. Design Toolkit does it in one: select an element and the animation section lists its transitions with their durations and curves, the CSS animations with their keyframes, and anything running through the Web Animations API — with the easing drawn as a curve so you can see the spring rather than parse the numbers. There is a copy button that writes the whole thing out as a brief for an AI, or sends it straight to a coding agent, which is the fastest path from "I like that" to "it is in my project".

If you are rebuilding a whole component rather than one animation, giving your AI the real design covers the same idea for everything else on the element.

Read motion, not just styles

Durations, easing curves, keyframes and JavaScript animations — in one panel, with a copy button for your AI. Free for 7 days.

Add to Chrome — free trial

Common questions

Why does my copy feel wrong even with the right duration?

Almost always the easing. 300ms on ease-out and 300ms on cubic-bezier(0.34, 1.56, 0.64, 1) are different animations — the second overshoots and settles back. Duration sets how long; the curve sets how it feels.

How do I read an animation made with GSAP or Motion?

Those libraries drive the Web Animations API, so the animation exists on the element with no CSS describing it. element.getAnimations() returns it with its timing and keyframes.

Can I copy an animation from a site whose CSS I cannot read?

Yes. A cross-origin stylesheet cannot be read as text, but the animation the browser is running can still be inspected through getAnimations, which reports the computed keyframes regardless of source.

What about scroll-driven animations?

A scroll-driven animation has no duration in seconds — its timeline is the scroll position. Note the timeline and the keyframes rather than a duration, and rebuild it with scroll-timeline or an intersection observer.

Read next