Features

What AE2CSS turns into web code — and what's next.

What exports today, what's partial, what's coming — and exactly where any JavaScript shows up, and where it doesn't.

Shape morphing, Glow, Drop Shadow, luma mattes and particle systems all export. Those are Lottie's limits, not CSS's — the FAQ at the bottom takes each one in turn.

Support matrix

Everything in your comp, accounted for.

Better to know the edges up front than hit them mid-project.

Supported exports today Partial works, with a stated limit Incoming on the roadmap Not in CSS no honest web equivalent

Motion & timing

Expression-driven motionSupportedWiggle, loops, time-driven spin — the expression is evaluated and rewritten as clean CSS keys. No parsing, no per-frame JavaScript.
Position, Scale, Rotation, OpacitySupportedReal keyframes with per-segment cubic-bezier easing — pixel-matched to After Effects, never a stack of baked frames.
Animated Anchor PointSupportedA keyframed anchor moves the pivot, not the layer — so rotation and scale keep turning around the point as it travels, the way After Effects does it.
Auto-Orient along pathSupportedA layer that turns to follow its motion path rides offset-rotate: auto where the position is a real path — zero extra keyframes — and a baked tangent where it isn't. Angles are unwrapped, so 170°→−170° never spins back through zero.
Auto-range loopsSupportedFinds the real animated window so every layer loops tight and on one shared beat.
Time RemappingPartialA precomp After Effects loops on a shorter period keeps that period: its contents get their own CSS clock instead of the same cycle copied N times over. Time Remap on a top-level layer is reported, not replayed.
Motion blurNot in CSSPer-frame smear has no CSS equivalent, and faking it with stacked copies costs more than it buys. The export tells you the layer had it rather than dropping it quietly.

Effects

GlowSupportedVector-first: blur → filter: blur(), AE Glow → a drop-shadow stack, round glows → a radial bloom. A flattened PNG only as a last resort.
EchoSupportedAE's Echo becomes time-shifted, fading clones — generalized over any animation, not a per-case hack.
Light sweep / shineSupportedBoth routes: a matte shine band, solid or gradient, riding real keyframe motion — and AE's own CC Light Sweep, whose band is rebuilt from the effect's own parameters. Edge Intensity and Thickness (the rim glint) are reported rather than drawn.
Draw-on strokes / TrimSupportedAnimated trim start, end and offset draw the stroke on along its path.
Layer blend modesSupportedMultiply, Screen, Overlay, Soft and Hard Light, Lighten, Add and Linear Dodge become mix-blend-mode on the layer — inside precomps too. Stencil and Silhouette are read as track mattes on everything beneath. The modes CSS has no analogue for fall back to Normal and say so.
Layer StylesSupportedDrop Shadow and Outer Glow → drop-shadow(); Stroke, Inner Glow and Inner Shadow → box-shadow; Color Overlay goes through the same recolor path as a Fill effect — applied after the effect stack, as After Effects composites them. Bevel, Satin and the gradient/pattern overlays are reported.
Colour correctionPartialHue/Saturation, Brightness & Contrast, Invert and Drop Shadow compile into one static filter: chain, in AE's own effect order. CSS filter can't animate on the compositor, so a keyframed parameter holds its first value and says so. Levels, Curves, Lumetri and friends are reported instead of silently approximated.
Adjustment layersSupportedFill recolor and glow apply straight to each layer beneath, per-target — no wrapper, no repaint.
Transform effectPartialReads as one static matrix plus an opacity multiplier, with expression-driven controllers resolved to their values. Keyframing the effect's own parameters exports the in-point pose and reports the rest.
Gradient RampPartialRides the layer's own alpha as a real CSS gradient — a circle stays a circle — across rects, ellipses, donuts, groups and pen paths alike. On a solid or footage layer, and for a ramp that animates, it falls back and reports.
Path morph — affineSupportedSquare→diamond and rotate/scale/skew morphs become pure CSS transform: matrix() — compositor-only. Sample density is measured against the pose After Effects draws, not guessed from an angle.
Path morph — true shape changeSupportedGenuine contour changes (e.g. a blob) render via a tiny canvas runtime, scoped to the morphing path — see "What ships" below. Everything else on the layer stays CSS on the compositor.
Radial WipeSupportedThe loading-pie reveal: an angular clip-path cut from the layer's own alpha, with Transition Completion animating it. CSS allows one clip per element, so a layer carrying both a wipe and a light sweep keeps the wipe and reports the dropped sweep.
Linear Wipe / Venetian BlindsIncomingThe same shape of problem — an effect that decides which part of the layer you see — with no reader yet, so the layer exports fully painted and, unlike the rest of this table, without a warning. Radial Wipe just left that state; these follow.

Masking & mattes

Single mask & track matteSupportedEvery matte mode including inverted — vector clip-path or a baked alpha mask.
Animated track matteSupportedThe "bar wipes a banner open" rig: a matte whose rect or ellipse path is keyframed exports as a real animated clip — no baked asset, crisp at any size. Content that moves under a static matte gets the matte pinned in comp space instead, so the shape travels through it as in After Effects.
Pathfinder / Merge PathsSupportedAdd, Subtract, Intersect and Difference, all live vector and all animating. Union and Difference are one clip-path; Subtract and Intersect become a chain of wrappers, one per cutter, so two overlapping cutters compose exactly as After Effects composites them instead of cancelling each other out. Only a radial-gradient merge still bakes.
Feather, Expansion & the harder mask modesPartialOn a layer mask (not to be confused with Merge Paths above), Feather, Expansion, Intersect and Difference bake the layer's alpha to a mask image — right pixels, one frame. Mask Opacity below 100% isn't read yet: the mask applies fully opaque.
Multi-mask compositingPartialOne active mask is live vector. More than one falls back to that same baked alpha mask — correct, but a single frame — except on a solid, where Add plus Subtract still composite as real vector. Stacking masks as live mask-composite layers is the next step.
Animated mask pathPartialAn animated mask on a solid drives real geometry — a keyframed circle, or the same morph machinery a shape path uses. Animating clip-path on any layer is designed but deliberately unshipped: it repaints on the main thread, so it will land scoped to constant-vertex paths.

Images, precomps & nesting

Smart image bakingSupportedAnything too dense for code — thick effect stacks, video, a whole precomp — bakes down to a single crisp image and ships. Everything vectors can reach stays code.
Nested precomps, any depthSupportedA precomp inside a precomp inside a precomp: every level keeps its own transform, paint order and opacity, and each container clips to the nested comp's bounds exactly as After Effects rasterizes it.
Collapse TransformationsSupportedA collapsed precomp exports instead of being refused — the switch lifts the clip, as in After Effects.
Looped precompSupportedA precomp looped through Time Remapping runs its contents on their own CSS clock, at their real period — not the same cycle copied across the master timeline.
Image layers (PNG / JPG / WebP)SupportedCopied as-is, or rendered when effects or video are applied.
Image + glow / blurSupportedBaked to a crisp PNG; CSS animates the layer over it.
Image precomp — BakeSupportedThe whole precomp becomes one image; the host layer's transforms animate.
Image precomp — Div / per-assetSupportedEach inner image becomes its own <img>, animated separately.
Master Properties / Essential GraphicsIncomingOverrides set on the precomp layer aren't read yet — the export uses the source comp's own values and reports the difference.

Systems & advanced

Native text layersSupportedReal, selectable, searchable HTML text — never a raster. Font, weight, size, tracking, leading and alignment come across, with a Google Fonts import for mapped families and a system stack for the rest. Per-character Text Animators — typewriter, fly-up — ride the first Range Selector and share the loop. Not yet: animated Source Text, text on a path, text stroke.
Particle systemsSupportedAuthored in our Particle Lab, exported as native CSS: each particle is a DOM node driven by pure CSS keyframes — fast, GPU-friendly, glow included. One small scoped module spawns them — no canvas, no generic engine.
RepeaterSupportedEach copy becomes a real clone of the layer carrying its own accumulated matrix — so it inherits the paint, masks, morphs and the layer's own animation for free. Compounding scale and rotation come out exact. Clamped at 40 copies, with a warning.
3D transformsPartialPer-layer 3D rotation, Orientation, Z-depth and AE's default perspective, emitted only when the scene truly goes 3D.
Cameras & lightsIncomingA comp with an animated camera exports as though the default camera never moved. Real camera and light rigs, with depth sorting, arrive with the full 3D scene.
Puppet / mesh warpIncomingThe core already finds the mesh and its pins, but true mesh deformation is a WebGL path — not representable as CSS — and it isn't wired into the panel yet.
Number count-up / odometerIncomingThe render is settled: a compositor-safe digit-strip measured at zero paints per second, against 421 for the naive version. What's left is reading the intent back out of After Effects, which doesn't count natively.

Shapes & paths

RectanglesSupportedFill, gradient, stroke and corner radius — animated, including a keyframed Size or Roundness.
Ellipses & circlesSupportedFill, gradient and stroke; true round corners. An animated Path Position rides a compositor-only translate().
Stars & polygonsSupportedSynthesized into a real contour, roundness included, then handed to the same readers a pen path uses — so animated radii, rotation and position ride the morph path for free. Animating the number of points changes the vertex count, so the star holds its first pose.
Donuts & ringsSupportedIncluding a keyframed (animated) hole radius.
Custom pen pathsSupportedArbitrary bezier shapes as inline SVG — fill, gradient and stroke. A path that is really a rect or an ellipse is recognized and shipped as a CSS box instead.
Shapes from TextSupportedPer-letter and per-group transforms, staggered reveals.
Shape-group transformsPartialA group's own Position, Scale, Rotation and Opacity animate — including the one-group case a spinner's orbiting dot is built from, which used to export complete, correctly painted and motionless. What's still frozen is a sub-group nested inside another group: its transform is composed once at its in-point.
Shape path operatorsIncomingOffset Paths, Round Corners, Pucker & Bloat, Twist, Zig Zag and Wiggle Paths aren't read — a layer using one exports its undistorted contour. Outline the shape in After Effects if you need one today.
Dashed strokesIncomingstroke-dasharray is a direct translation and it's on the list — dashes, line join, miter and taper aren't read yet.

Fills & color

Solid & animated fillSupportedColor and color-over-time, as native CSS. A Fill, Tint or Color Control effect wins over the source colour, with expression links resolved.
Gradients — linear & radialSupportedSampled pixel-accurate from After Effects; radial on ellipses, donuts and pen paths.
Transparent / alpha gradientsSupportedAlpha-aware sampling, emitted as rgba() stops.
Animated gradient coloursPartialThe gradient's geometry animates, but its stops are sampled from After Effects once, so the colours hold — After Effects gives a script no readable value for Gradient Colors. Highlight Length and Angle aren't read.

What ships

What lands in your export — and what never does.

Your animation becomes the page, not a payload it loads.

Zero runtime, by default

Shapes, gradients, masks, transforms, easing, affine morphs and images all export as plain HTML and CSS. No JavaScript, no JSON, no player to download or parse. The CSS is the animation.

A tiny runtime, only for two effects

Two things genuinely can't be pure CSS: particle systems and true shape-morphing (a real contour change, not a rotate or scale). Those ship one small, purpose-built animation-runtime.js — a few kilobytes scoped to that effect. Not a generic interpreter, not a Lottie-style player — and omitted entirely when your comp uses neither.

your-export/
  animation.html        ← semantic markup, minimal DOM
  animation.css         ← every transform, gradient & keyframe — pure CSS
  animation-runtime.js  ← OPTIONAL — only if you used particles or true morph
  images/               ← baked PNG/JPG assets, when needed
  masks/                ← baked alpha masks, when a mask needs one

JSON only lives in our tooling — the Particle Lab manifest you author against, plus dev diagnostics. It never leaves After Effects: nothing JSON-shaped, and no generic player, is written to your export.

"Lottie loads one general-purpose JSON player on every animation. AE2CSS loads nothing by default — and at most a small module for a single effect."

FAQ

The five things people assume can't be done.

Every one of them is a real limit of Lottie, and it gets repeated about CSS export by association. Here's where AE2CSS actually stands.

Does AE2CSS support shape morphing?
Yes — and in two ways, picked per path. A morph that is really a transform in disguise (square→diamond, a rotating or skewing outline) becomes a pure CSS transform: matrix() on the compositor, with no JavaScript at all. A genuine contour change — a blob wobbling, vertices moving independently — is drawn by a small canvas runtime scoped to that path alone, while every other layer stays CSS. The one condition is a constant point count: a path that gains or loses a vertex mid-animation is held static.
Does it export Glow and Drop Shadow?
Yes, both, as live CSS rather than a flattened image. After Effects' Glow becomes a calibrated box-shadow bloom whose colour model was matched against real AE renders; a blurred glow copy becomes filter: blur(); Drop Shadow becomes filter: drop-shadow() with its offset, softness, colour and opacity. It stays crisp at any zoom and a developer can recolour it in one line. Fill, Tint, Hue/Saturation, Brightness & Contrast and Invert map to CSS filters the same way.
Does it support luma mattes and track mattes?
Yes — all four After Effects modes: Alpha, Luma, and the inverted Stencil/Silhouette pair. Where the shape allows it the matte becomes a live vector clip-path; where it doesn't — feathered, gradient or luminance-driven — the matte layer is rendered to a real alpha mask and applied with CSS mask-image. Nothing about a luma matte forces a video or a flattened frame.
Does it support particle systems?
Yes, and they leave as web particles, not as a canvas or a sprite sheet: each particle is a page element the browser animates from pure CSS keyframes, glow included. One small scoped module spawns the swarm from a seed, so the preview and the export are the same thing — and a swarm costs the bytes of its recipe, not of its particle count.
Does the CSS get too long and unreadable on a big animation?
No, and it's the part we measure hardest. CSS stores rules rather than frames, so length costs nothing — a 30-second loop weighs what a 2-second one does. Identical @keyframes collapse into one block, values shared by several elements are lifted into a single /* Shared values */ rule, empty wrapper <div>s are folded away, and each keyframe has to earn its place against what After Effects actually draws. Our heaviest reference scene — 96 layers at 1920×1080 — is 48 KB of CSS, about 7 KB gzipped, with a legend at the top and every block commented with the layer it came from.
So what does it genuinely not export?
Puppet and mesh warp, camera and light rigs with depth sorting, Linear Wipe and Venetian Blinds, text on a path and per-character colour, the shape path operators (Offset Paths, Zig Zag and friends), and the heavy colour-grading effects (Levels, Curves, Lumetri). Two land halfway rather than not at all: more than one active mask on a layer, and an animated mask path — both come out right, but as a baked alpha mask instead of live vector, except on a solid where they stay real geometry. Expressions are evaluated for position, scale, rotation and opacity — not for arbitrary effect parameters. Generative and deforming effects such as Fractal Noise or Wave Warp bake to a crisp image instead of becoming code. The panel tells you when it hits one of these — with one gap it owns up to in the matrix above: Linear Wipe and Venetian Blinds aren't detected yet, so they pass in silence.

Don't see your animation?

The motion it can't read yet is our roadmap. Flag it in one click from inside After Effects — the most-requested gaps get built first and arrive through the updater.