<animate> in SVG: animating an attribute without a line of JavaScript

Animates an SVG attribute between two values over time, no JavaScript or CSS required: the core building block of native SMIL animation.
5 min read
Believemy logo

When a notification badge pulses gently in the corner of an interface, or a progress bar fills itself in as soon as a page loads, chances are a simple <animate> is doing the work inside the SVG. This element changes an attribute over time, a width, an opacity, a color, directly inside the SVG file, without writing a single line of JavaScript and without depending on an external stylesheet.

This matters most when the SVG travels as a standalone image: dropped into an <img> tag, used as a CSS background, or embedded in an email. In those contexts neither JavaScript nor a CSS animation defined elsewhere can run, while a SMIL animation written with <animate> keeps working, because it is baked into the file itself.


Definition

<animate> is a SMIL (Synchronized Multimedia Integration Language) animation element built natively into SVG. It sits inside the element it animates and targets one specific attribute, named through attributeName, moving it from a starting value to an ending value over a given duration. Unlike a geometric transform, it does not animate an element’s position or scale but the raw value of a presentation attribute, for instance width, height, opacity, fill or r.


Main attributes

A handful of attributes cover most everyday cases.

AttributeRole
attributeNameThe name of the targeted attribute, such as width, opacity or fill.
from / toStarting value and ending value of the animation.
valuesA semicolon-separated list of intermediate values, for a multi-step path.
durTotal duration of the animation, for example 1.2s.
repeatCountNumber of repetitions, or indefinite for an endless loop.
fillState kept once it ends: freeze keeps the last value, remove (the default) jumps back to the initial state.


A concrete example

Here is a loading bar built from a <rect> whose width grows progressively from 0 to 200 pixels, a common way to signal that content is being prepared.

HTML
<svg viewBox="0 0 220 40" xmlns="http://www.w3.org/2000/svg">
  <rect x="10" y="10" width="200" height="20" rx="10" fill="#e5e7eb" />
  <rect x="10" y="10" width="0" height="20" rx="10" fill="#2563eb">
    <animate attributeName="width" from="0" to="200" dur="1.2s" fill="freeze" />
  </rect>
</svg>


How it differs from <set> and CSS animations

<animate> has a blunter cousin, <set>, which switches an attribute’s value in one go, with no gradual transition, while <animate> smoothly interpolates between every value on its path. Compared with CSS animations, the difference is mostly one of reach: a CSS animation needs a stylesheet loaded on the page, while an <animate> written inside the SVG keeps working even when the file is opened alone in a browser tab or dropped in as a plain image. Compared with the Web Animations API, the gap widens further: that API drives the animation from JavaScript, which gives fine-grained control such as pausing, reversing or syncing with other events, but it requires the SVG to be inline in the DOM and a script to actually run, two conditions a standalone <animate> never needs. One more detail is worth spelling out: historically, the transform attribute cannot be animated correctly with <animate>, you need <animateTransform> instead, which knows how to decompose a rotation, a translation or a scale without mixing them up.


A classic pitfall

The most common trap is the fill attribute on the animation itself, easy to confuse with the fill attribute that sets a shape’s color. Without fill="freeze", the animation snaps back to its starting value the moment it ends, which makes a progress bar look like it empties itself right after filling up in front of the user. The second trap concerns triggering: by default begin is 0s, so the animation starts the instant the SVG loads, which surprises developers expecting it to wait for a click or a hover.

Good to knowWithout fill="freeze", the animated attribute always jumps back to its starting value once the duration is over, even if the result looked frozen on screen moments earlier.


A real use case

A notification badge that pulses gently through an opacity animated between 1 and 0.4 on an endless loop draws the eye without being aggressive. A skill gauge on a profile page that fills in as soon as it loads makes a score feel more alive than a bare number ever could. It is also possible to animate the d attribute of a <path>, which lets a shape or a logo appear to draw itself, a technique often used on landing pages to catch attention gently.

QuestionDoes <animate> still work in modern browsers?

Yes, every current browser, Chrome, Firefox, Safari and Edge, supports SMIL animations. Google once considered dropping support back in 2016, then reversed course given how widely it was used in animated icons and illustrations across the web.

QuestionCan an <animate> animation be triggered by a click instead of on page load?

Yes, the begin attribute accepts an event syntax such as begin="myButton.click", which starts the animation only once the named element receives that click, without writing a single line of JavaScript to wire up a listener.

QuestionShould <animate> be preferred over CSS animations for an SVG?

It depends on context: for an SVG used as a standalone file, an icon or an email image, <animate> guarantees the animation works without any external dependency. For an SVG inlined in a page where CSS is already in place, a CSS animation is usually easier to maintain and keep in sync with the rest of the interface.

Related terms

Discover our hTML and CSS glossary

Browse the terms and definitions most commonly used in HTML and CSS development.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.