AI CSS Animations

Guides · · Maxwell Prehoda

CSS Animation vs GSAP: 10 Jobs, Which Tool Wins Each, and Why

Use CSS for state changes and loops that live on one element: hover and press feedback, toggles, loaders, simple entrances. Use GSAP when motion is choreography: several elements in a precise order, pinned scroll stories, split text, SVG morphing, layout changes and anything driven by drag or a canvas. Cost is no longer part of the decision: since GSAP 3.13 in April 2025, Webflow has made all of GSAP free for commercial use, including SplitText and MorphSVG.

Most CSS vs GSAP articles are either GreenSock's own or predate scroll-driven animations and the free license. Below are ten real jobs, the tool that wins each one, and the honest reason. Where CSS wins we show a live demo from our directory; browser support figures are from webstatus.dev in November 2026.

1. Hover and press feedback: CSS wins: Best for buttons, links, cards and icons

Platform: CSS transitions; no JavaScript

Live from our directory: Pressed Button Effect. Copy the HTML and CSS →

A hover is a two-state change on one element, and CSS transitions reverse smoothly from wherever they are when the pointer leaves. You get that behavior with one declaration, and it works before any JavaScript has loaded or hydrated. Doing the same in GSAP means event listeners, a tween per element and cleanup on unmount, for no visible gain.

Our Pressed Button Effect below sinks on click as its drop shadow collapses into an inner shadow, all in CSS.

Watch out for: CSS hover has no idea about pointer velocity or position. Magnetic buttons that follow the cursor, or cards that tilt toward the pointer, need a few lines of JavaScript, though not necessarily GSAP.

2. Loaders and ambient loops: CSS wins: Best for spinners, shimmer and background motion

Platform: CSS @keyframes; can run off the main thread

Live from our directory: Gradient Ring Spinner. Copy the HTML and CSS →

This is where the performance argument is real. MDN's performance guide explains that CSS and JavaScript animations cost about the same when both run on the main thread, but when a CSS animation only touches properties like transform, the browser can move it off the main thread entirely. A loader is shown precisely when the main thread is busy fetching and parsing, so that matters: a CSS spinner keeps turning while a JavaScript-driven one can stutter.

Our Gradient Ring Spinner below is a conic gradient masked into a ring and rotated with a single keyframe.

Watch out for: Off-main-thread playback only applies to compositor-friendly properties. Animate width, top or box-shadow in your loop and CSS loses that advantage. Our best practices guide lists the safe properties.

3. Simple scroll reveals: CSS wins, with a fallback: Best for sections and cards that fade in as you scroll

Platform: CSS animation-timeline: view(); Chrome and Edge 115+, Safari 26

Blur
Live from our directory: Blur In On Scroll. Copy the HTML and CSS →

Scroll-driven animations tie a normal @keyframes animation to scroll position. animation-timeline: view() plays it as the element crosses the viewport, with no IntersectionObserver and no library. For a fade or slide as each section arrives, that is less code than a ScrollTrigger setup, and it can run off the main thread like any compositor-friendly CSS animation.

Our Blur In On Scroll below uses it.

Watch out for: Support is recent: Chrome and Edge since 115, Safari since 26 and Firefox since 159 (October 2026), so many visitors are still on browsers without it. Wrap it in @supports and make sure the content is fully visible without it. If the reveal has to work identically for every visitor today, ScrollTrigger is the safer pick.

Browser support ↗

4. Pinned scroll stories: GSAP wins: Best for product tours and scrollytelling sections

Platform: GSAP ScrollTrigger; free

Once a section has to stay pinned while several things animate in sequence, then release, then snap to chapters, you are past what CSS handles comfortably. ScrollTrigger's pin holds an element in place and adds spacing so the content after it does not overlap. scrub ties a whole timeline to the scrollbar, with a number like scrub: 1 for a smoothed catch-up. snap settles on progress points or timeline labels, and markers show you exactly where triggers fire while you build.

Codrops publishes a steady stream of these builds, for example 2026 tutorials on scroll-driven SVG graphs and maps with GSAP, which are a good way to see what the plugin is for.

Watch out for: Pinning changes layout and is easy to break with late-loading images or fonts. Call ScrollTrigger.refresh() after content shifts, and test on a phone, where address bars resize the viewport while you scroll.

Codrops ↗

5. Sequenced timelines: GSAP wins: Best for hero intros and multi-element choreography

Platform: GSAP timeline; free

Live from our directory: CI Pipeline Stages. Copy the HTML and CSS →

You can sequence CSS animations with animation-delay, and for a fixed loop that is fine. Our CI Pipeline Stages below lights its build, test and deploy blocks in turn with nothing but CSS delays.

The trouble starts when the sequence changes. Insert a step and you retune every delay after it; make one tween longer and the rest drift out of sync. A GSAP timeline positions each tween relative to the previous one or to a label, so you can lengthen, insert or overlap steps without touching the rest, and you can pause, reverse, seek or speed up the whole thing from code. GreenSock's own long-standing argument is that keeping several CSS animations in sync is the hard part, and in practice that is true.

Watch out for: A timeline is JavaScript, so it does not run until your bundle loads. Design the first frame in CSS so nothing flashes or jumps when GSAP takes over.

6. Split text reveals: GSAP wins, unless the text never changes: Best for headline reveals by line, word or letter

Platform: GSAP SplitText; free since 3.13

Welcome!
Live from our directory: Letters Rise. Copy the HTML and CSS →

CSS can reveal letters one by one if you wrap each one in a span with its index. Our Letters Rise below does exactly that with a custom property per span. It works well for a fixed word in a logo or a button.

For real headlines, SplitText is better. The 3.13 rewrite is about half the size of the old plugin, adds aria-label to the split element and aria-hidden to the generated pieces so screen readers read the sentence normally, and with autoSplit it re-splits when the window resizes or fonts load, so line-by-line reveals do not break at a new width. Splitting by lines is something CSS cannot do at all, because CSS does not know where a line wraps.

Watch out for: Hand-wrapped letter spans in CSS are read letter by letter by some screen readers unless you add an aria-label to the parent and hide the spans. If you split by hand, do that, or use SplitText, which does it for you.

7. SVG line drawing vs morphing: CSS draws, GSAP morphs: Best for icons, logos and illustrations made of paths

Platform: CSS stroke-dashoffset for drawing; GSAP MorphSVG for morphing

Live from our directory: Check and Cross Toggle Switch. Copy the HTML and CSS →

Drawing a stroke on is a CSS job: set stroke-dasharray to the path length and transition or animate stroke-dashoffset to zero. The check mark in our Check and Cross Toggle Switch below draws itself that way when you switch it on.

Turning one shape into a different shape is GSAP's job. MorphSVG animates a path's d attribute even when the start and end shapes have different numbers or types of points, adding anchor points as needed, and it can convert circles, rectangles and polygons to paths first. CSS can only interpolate between paths that share the same command structure, which almost never happens with artwork from two different drawings.

Watch out for: Complex morphs are CPU work on every frame. MorphSVG's docs suggest precompiling and setting shapeIndex ahead of time for heavy shapes, and you should test them on a low-end phone.

8. Layout changes: GSAP Flip or View Transitions: Best for filtering grids, reordering lists, expanding cards

Platform: GSAP Flip (free) or the View Transition API

When elements jump because the layout changed (a grid filters, a card moves into a modal, a flex row becomes a column), CSS transitions cannot help, because the change is in layout rather than in a property you set. GSAP Flip records the element's position and size, lets you change the DOM however you like, then animates from the old box to the new one. It handles nested transforms and reparenting into rotated or scaled containers, which its docs note many FLIP libraries do not.

The browser-native alternative is the View Transition API, whose same-document version reached Baseline in October 2025 when Firefox 144 shipped it. It snapshots before and after states and animates between them with CSS. For simple cross-fades and shared elements it is lighter; for precise control of many moving items, Flip is still easier.

Watch out for: Flip does not support 3D transforms such as rotationX or z, and in frameworks you must wait for the render before calling Flip.from(). While a view transition runs, the page shows snapshots of the old and new states rather than live content, so keep it short.

MDN: View Transition API ↗

9. Drag, physics and canvas: GSAP wins: Best for draggable UI, WebGL and three.js scenes

Platform: GSAP core and Draggable; free

CSS only animates CSS properties of DOM elements. GSAP animates any numeric property of any JavaScript object, which is why it is common in WebGL and three.js work: you tween a camera position, a shader uniform or a canvas value exactly like a DOM element. Draggable adds dragging, spinning and snapping to elements, which CSS has no concept of.

Many of Codrops' 2026 tutorials combine Three.js, shaders and GSAP for exactly this reason.

Watch out for: Once GSAP owns a canvas scene, you also own its frame budget. Pause timelines for off-screen scenes, and check what happens on a battery-saving phone.

10. Reduced motion and bundle size: a tie, handled differently: Best for accessible motion that respects user settings

Platform: CSS prefers-reduced-motion media query or gsap.matchMedia()

Both respect reduced motion if you ask them to. In CSS, wrap or override animations in a prefers-reduced-motion media query. In GSAP, gsap.matchMedia() runs one setup for no-preference and a gentler one for reduce, and automatically reverts the animations and ScrollTriggers created in a setup when its query stops matching. GSAP's docs note that for vestibular disorders, minimal or no animation is the right choice.

On size, CSS adds nothing to your JavaScript bundle, while GSAP adds its core plus each plugin you import. For a marketing site with one big scroll story, that is a fair trade. For an app shell where motion is hovers and toggles, it is not.

Watch out for: Neither does anything automatically. A global reduced-motion CSS rule will not stop GSAP tweens, and GSAP will not stop your CSS loops, so a site that mixes both needs both checks.

MDN: prefers-reduced-motion ↗

11. Our CSS directories for the CSS half: Best for the hover, loader and border motion around a GSAP scene

Platform: Motions directory, free; HTML plus CSS Ours

Border beam
Live from our directory: Border Beam. Copy the HTML and CSS →

Most GSAP sites still have dozens of small CSS interactions around the big scroll scene: button hovers, nav underlines, loaders, glowing borders. Our CSS index collects about 1,800 copy-paste snippets for that half, each with a prefers-reduced-motion guard and two custom properties for color and size.

The Border Beam below is a common one to pair with a GSAP hero: a short beam of light that travels the card's edge, in pure CSS.

Watch out for: These are deliberately single-element CSS effects. They will not sequence with your GSAP timeline; trigger them with classes or let them run independently.

12. Our creator: Best for CSS versions of motion you assumed needed GSAP

Platform: Motions creator; a full run is free to try Ours

Plenty of effects people reach for GSAP to build are CSS-able: staggered entrances, looping logos, draw-on icons, scroll fades. Describe the effect or paste your component's HTML or a screenshot into the creator, answer up to four quick questions while it takes shape, and you get production-ready CSS keyframes to refine in chat.

If the honest answer is that it needs a timeline, you will see that quickly too, before you have written either version by hand.

Watch out for: It writes CSS, not GSAP code. Copy, export, save and refine come with the paid plans.

How to choose between CSS and GSAP

Count the elements that move together

One element changing state (a button, a toggle, a card) is CSS. Two or three elements on a fixed loop is still CSS with delays. Once several elements have to stay in sync while the sequence keeps changing in design review, a GSAP timeline will save you time. Our CSS animation vs transition guide covers the CSS side in detail.

Look at what drives it

Time and state changes are native to CSS. Scroll position is native to CSS in Chromium and Safari, and to GSAP everywhere. Pointer position, drag, physics, audio or canvas values need JavaScript, and GSAP is the most complete way to handle them.

Check what the page is doing while it animates

If the motion plays while the main thread is busy (loaders, first paint, route changes), prefer compositor-friendly CSS. If it plays on a page that is already loaded and idle, like a scroll story, GSAP's main-thread cost rarely shows. Most good sites use both: CSS for the UI, GSAP for the set pieces. If you are weighing other libraries too, see our Framer Motion alternatives.

Move the easy half to CSS this week

Search your codebase for gsap.to calls on hover and focus handlers, and for tweens that only ever run once on a single element. Those are usually CSS in disguise, and moving them shrinks the code GSAP has to run before your page feels ready. Keep GSAP for the timelines, the pinned scenes and the morphs, where it is still the best tool there is.

Start the CSS half from a snippet in the directory, or describe the effect and let the creator write it.

A prompt to start from
Rewrite this GSAP hero entrance as pure CSS: the eyebrow, headline and button fade and rise 12px one after another, 80ms apart, each over 500ms on an ease-out quint.
Use a --i custom property per element for the stagger instead of separate delays.
Start from the hidden state with animation-fill-mode: both so nothing flashes before it plays.
Under prefers-reduced-motion, show everything immediately with a 150ms fade and no movement.

Make your own with AI →

Common questions

Is GSAP faster than CSS animation?

Not in general. MDN's performance guide notes that CSS and JavaScript animations perform about the same on the main thread, but CSS can run transform and opacity animations off the main thread, which keeps them smooth while the page is busy. GSAP is highly optimized JavaScript, so for complex sequences the difference is rarely visible.

Is GSAP free now?

Yes. Since GSAP 3.13 in April 2025, Webflow has made the whole library free, including formerly paid plugins like SplitText and MorphSVG, and commercial use is allowed. The license does prohibit using it inside no-code visual animation builders that compete with Webflow without written consent.

Can CSS scroll-driven animations replace ScrollTrigger?

For simple reveals and progress bars tied to scroll, yes, in Chrome, Edge, Safari 26 and Firefox 159. They do not pin elements or snap to sections on their own, and older browsers need a fallback, so ScrollTrigger is still the choice for full scroll stories.

Should I use GSAP or CSS for micro-interactions?

CSS. Hovers, presses, toggles and focus states are two-state changes that CSS transitions handle with less code and no JavaScript. Our directory has hundreds of copy-paste examples.

Can I use GSAP and CSS animations together?

Yes, and most production sites do. Just do not animate the same property of the same element with both at once, because they will overwrite each other.

Sources