Skip to content
Carl Victor Fontanos
Carl Victor Fontanos

Carl Victor Fontanos

Software Engineer

I build web applications and share what I learn along the way.

© 2026

Animating CSS Gradients (Yes, Really) with @property

C
Carlo Fontanos
· 2 min read

Try to transition a gradient and you get a hard swap at the halfway point. The browser can't interpolate between two background-image values, and for years the workarounds were all fakes: crossfading a second layer, sliding an oversized background-position. The real fix arrived quietly with @property.

Why gradients don't animate (and how types fix it)

Custom properties are just strings to the engine - it has no idea --angle: 45deg is an angle, so it can't compute the frames between 45deg and 225deg. @property registers the type:

@property --angle {
    syntax: '<angle>';
    initial-value: 45deg;
    inherits: false;
}

.card {
    background: linear-gradient(var(--angle), #4f46e5, #0ea5e9);
    transition: --angle 0.6s ease;
}

.card:hover {
    --angle: 225deg;
}

Now the variable itself interpolates, the gradient re-resolves every frame, and you have a smoothly rotating gradient on hover. Pure CSS.

Animating gradient colors

Same trick, color syntax:

@property --stop-1 {
    syntax: '<color>';
    initial-value: #4f46e5;
    inherits: false;
}
@property --stop-2 {
    syntax: '<color>';
    initial-value: #0ea5e9;
    inherits: false;
}

.hero {
    background: linear-gradient(120deg, var(--stop-1), var(--stop-2));
    transition: --stop-1 1s, --stop-2 1s;
}

.hero.night {
    --stop-1: #0f172a;
    --stop-2: #334155;
}

Toggle a class, watch the gradient melt from day to night. This also works inside @keyframes for ambient, endlessly shifting backgrounds - at compositor-friendly cost, since you're animating two color values, not repainting layers of images.

Beyond gradients

Typed properties animate anywhere a variable is used: numeric counters that tick up (syntax: '<integer>' animated in a pseudo-element's content via counter), conic-gradient pie charts that sweep to their percentage, underline widths, you name it. The pattern is always: register the type, transition the variable, use the variable somewhere visible.

Practical notes

  • All three descriptors are required in practice; initial-value must be a computationally independent value (no var() references, no em).
  • Support: Chromium for ages, Firefox 128+, Safari 16.4+ - all comfortably mainstream now. Browsers without it fall back to the un-animated swap, which is exactly what you had before.
  • Keep gradient animations subtle and respect prefers-reduced-motion - ambient movement is precisely the kind of thing motion-sensitive users need to be able to switch off.

Gradients were the flashy demo, but the real unlock is conceptual: CSS variables stopped being dumb strings. Typed, animatable variables are a small rendering engine feature with years of creative runway left.

C
Written by Carlo Fontanos

Full-stack web developer sharing practical tutorials and building tools that ship.

Got something on your mind?

My inbox is open - no forms disappearing into the void here.

  • Just say hello Found a tutorial useful? Spotted a mistake? Tell me.
  • Hire me for a project Have something custom in mind? Let's talk scope and timelines.
  • Product support Bought something here? I'll help you get it running.

I usually reply within 1-2 business days.

Message sent!

Your details are only used to reply to you.

Keep reading