<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hari</title>
    <description>The latest articles on DEV Community by Hari (@harijn72).</description>
    <link>https://dev.to/harijn72</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3848521%2Fddae64a5-1e71-4864-9deb-3a1924e327e0.jpeg</url>
      <title>DEV Community: Hari</title>
      <link>https://dev.to/harijn72</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/harijn72"/>
    <language>en</language>
    <item>
      <title>Animated Bell Icon: Anatomy of a SMIL Ringing Animation</title>
      <dc:creator>Hari</dc:creator>
      <pubDate>Tue, 26 May 2026 11:30:14 +0000</pubDate>
      <link>https://dev.to/harijn72/animated-bell-icon-anatomy-of-a-smil-ringing-animation-3c56</link>
      <guid>https://dev.to/harijn72/animated-bell-icon-anatomy-of-a-smil-ringing-animation-3c56</guid>
      <description>&lt;h2&gt;
  
  
  Introduction: Why SMIL for Animated Icons?
&lt;/h2&gt;

&lt;p&gt;When building a library of animated SVG icons, the choice of animation technology is critical. CSSVG Icons uses &lt;strong&gt;SMIL (Synchronized Multimedia Integration Language)&lt;/strong&gt;—an XML-based language native to SVG—because it offers declarative, per-element control without external dependencies. Unlike CSS animations that apply to entire elements, SMIL lets us animate individual attributes (like &lt;code&gt;transform&lt;/code&gt;, &lt;code&gt;stroke-dashoffset&lt;/code&gt;, or &lt;code&gt;opacity&lt;/code&gt;) with precise timing and easing, all within the SVG itself.&lt;/p&gt;

&lt;p&gt;For a bell icon, SMIL’s ability to chain multiple transforms—rotation, translation, and scaling—with different easing curves creates a natural, physics-inspired ringing motion. This post breaks down a hypothetical bell icon’s SMIL animation, using real patterns from the CSSVG codebase (like the &lt;code&gt;search&lt;/code&gt; and &lt;code&gt;menu&lt;/code&gt; icons) to explain the &lt;em&gt;why&lt;/em&gt; behind each decision.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bell’s Anatomy: SVG Structure for Animation
&lt;/h2&gt;

&lt;p&gt;A ringing bell requires two main moving parts: the &lt;strong&gt;bell body&lt;/strong&gt; (swinging back and forth) and the &lt;strong&gt;clapper&lt;/strong&gt; (striking the bell). In SVG, we group these elements to animate them independently:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Hypothetical bell icon structure (inspired by CSSVG patterns)&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;svg&lt;/span&gt; &lt;span class="na"&gt;viewBox&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0 0 40 40"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;g&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"bell-body"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt; &lt;span class="na"&gt;d&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"M10,30 Q20,10 30,30"&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;animateTransform&lt;/span&gt; 
      &lt;span class="na"&gt;attributeName&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"transform"&lt;/span&gt; 
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"rotate"&lt;/span&gt; 
      &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0,20,30; 20,20,30; -10,20,30; 0,20,30"&lt;/span&gt; 
      &lt;span class="na"&gt;dur&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"1.5s"&lt;/span&gt; 
      &lt;span class="na"&gt;repeatCount&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"indefinite"&lt;/span&gt;
      &lt;span class="na"&gt;additive&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"sum"&lt;/span&gt;
      &lt;span class="na"&gt;keyTimes&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0; 0.5; 0.75; 1"&lt;/span&gt;
      &lt;span class="na"&gt;keySplines&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0.25 0.1 0.25 1; 0.5 0 0.5 1; 0.25 0.1 0.25 1"&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;g&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;g&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"clapper"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;circle&lt;/span&gt; &lt;span class="na"&gt;cx&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"20"&lt;/span&gt; &lt;span class="na"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"25"&lt;/span&gt; &lt;span class="na"&gt;r&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"3"&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;animateTransform&lt;/span&gt; 
      &lt;span class="na"&gt;attributeName&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"transform"&lt;/span&gt; 
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"translate"&lt;/span&gt; 
      &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0,0; 0,5; 0,0"&lt;/span&gt; 
      &lt;span class="na"&gt;dur&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0.8s"&lt;/span&gt; 
      &lt;span class="na"&gt;repeatCount&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"indefinite"&lt;/span&gt;
      &lt;span class="na"&gt;additive&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"sum"&lt;/span&gt;
      &lt;span class="na"&gt;keyTimes&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0; 0.5; 1"&lt;/span&gt;
      &lt;span class="na"&gt;keySplines&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0.42 0 0.58 1; 0.42 0 0.58 1"&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;g&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;svg&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this structure?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Grouping the bell body and clapper separately allows independent animation loops. The &lt;code&gt;additive="sum"&lt;/code&gt; property is crucial—it combines the clapper’s vertical movement with the bell’s rotation, making the clapper swing &lt;em&gt;relative&lt;/em&gt; to the bell’s tilt. Without additive transforms, the clapper would move in absolute coordinates, breaking the illusion of a single mechanical system.&lt;/p&gt;


&lt;h2&gt;
  
  
  Decoding the Swing: &lt;code&gt;keyTimes&lt;/code&gt; and Pendulum Physics
&lt;/h2&gt;

&lt;p&gt;The bell’s rotation follows a pendulum-like arc. The &lt;code&gt;keyTimes&lt;/code&gt; attribute defines the animation’s timeline, while &lt;code&gt;keySplines&lt;/code&gt; control easing between keyframes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;animateTransform&lt;/span&gt; 
  &lt;span class="na"&gt;attributeName=&lt;/span&gt;&lt;span class="s"&gt;"transform"&lt;/span&gt; 
  &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"rotate"&lt;/span&gt; 
  &lt;span class="na"&gt;values=&lt;/span&gt;&lt;span class="s"&gt;"0,20,30; 20,20,30; -10,20,30; 0,20,30"&lt;/span&gt;
  &lt;span class="na"&gt;keyTimes=&lt;/span&gt;&lt;span class="s"&gt;"0; 0.5; 0.75; 1"&lt;/span&gt;
  &lt;span class="na"&gt;keySplines=&lt;/span&gt;&lt;span class="s"&gt;"0.25 0.1 0.25 1; 0.5 0 0.5 1; 0.25 0.1 0.25 1"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why these values?&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;values&lt;/code&gt;&lt;/strong&gt;: The rotation pivots around &lt;code&gt;(20,30)&lt;/code&gt; (the bell’s top). The sequence &lt;code&gt;0 → 20° → -10° → 0°&lt;/code&gt; mimics a bell’s natural swing: it starts at rest, swings forward (positive rotation), then backward past center due to momentum, and finally settles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;keyTimes&lt;/code&gt;&lt;/strong&gt;: The animation spends &lt;code&gt;50%&lt;/code&gt; of the time reaching the forward peak (&lt;code&gt;20°&lt;/code&gt;), &lt;code&gt;25%&lt;/code&gt; swinging back to &lt;code&gt;-10°&lt;/code&gt; (overshoot), and &lt;code&gt;25%&lt;/code&gt; returning to center. This asymmetry reflects real physics—a bell loses energy as it swings, so the forward stroke is slower than the return.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;keySplines&lt;/code&gt;&lt;/strong&gt;: The cubic-bezier curves create “slow-in, slow-out” motion. The first spline (&lt;code&gt;0.25 0.1 0.25 1&lt;/code&gt;) eases into the forward swing, the second (&lt;code&gt;0.5 0 0.5 1&lt;/code&gt;) accelerates the backswing, and the third mirrors the first for settling. This avoids mechanical, linear motion.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Comparison to CSSVG’s &lt;code&gt;search&lt;/code&gt; icon:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The &lt;code&gt;search&lt;/code&gt; icon uses similar splines for its scanning motion (&lt;code&gt;keySplines="0 0 1 1"&lt;/code&gt; for constant speed), but the bell requires variable speed to feel organic. The &lt;code&gt;menu&lt;/code&gt; icon’s scaling (&lt;code&gt;keySplines="0 0 1 1"&lt;/code&gt;) is linear because it’s a simple morph, not a physics-based swing.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Clapper’s Strike: Additive Translation and Timing
&lt;/h2&gt;

&lt;p&gt;The clapper must move independently of the bell’s rotation. Its &lt;code&gt;translate&lt;/code&gt; animation is set to &lt;code&gt;additive="sum"&lt;/code&gt; so it compounds with the bell’s transform:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;animateTransform&lt;/span&gt; 
  &lt;span class="na"&gt;attributeName=&lt;/span&gt;&lt;span class="s"&gt;"transform"&lt;/span&gt; 
  &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"translate"&lt;/span&gt; 
  &lt;span class="na"&gt;values=&lt;/span&gt;&lt;span class="s"&gt;"0,0; 0,5; 0,0"&lt;/span&gt; 
  &lt;span class="na"&gt;additive=&lt;/span&gt;&lt;span class="s"&gt;"sum"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why additive?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
If the bell rotates &lt;code&gt;20°&lt;/code&gt; and the clapper translates &lt;code&gt;5px&lt;/code&gt; downward, &lt;code&gt;additive="sum"&lt;/code&gt; applies both transforms to the clapper’s coordinate space. Without it, the clapper would move relative to the SVG’s origin, not the bell’s tilted position.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Timing the strike:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The clapper’s &lt;code&gt;0.8s&lt;/code&gt; loop is shorter than the bell’s &lt;code&gt;1.5s&lt;/code&gt; loop. This offset creates a realistic ringing pattern: the clapper strikes the bell at the peak of its forward swing, then again as the bell swings back. The &lt;code&gt;keySplines="0.42 0 0.58 1"&lt;/code&gt; (a standard “ease-in-out”) gives the clapper a quick strike and immediate rebound.&lt;/p&gt;


&lt;h2&gt;
  
  
  Layering Transforms: Rotation + Translation for Realism
&lt;/h2&gt;

&lt;p&gt;A bell doesn’t just rotate—its pivot point shifts slightly as it swings. We combine &lt;code&gt;rotate&lt;/code&gt; and &lt;code&gt;translate&lt;/code&gt; using multiple &lt;code&gt;&amp;lt;animateTransform&amp;gt;&lt;/code&gt; elements with &lt;code&gt;additive="sum"&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;g&lt;/span&gt; &lt;span class="na"&gt;transform=&lt;/span&gt;&lt;span class="s"&gt;"translate(20,30)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;animateTransform&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"rotate"&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt; 
  &lt;span class="nt"&gt;&amp;lt;animateTransform&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"translate"&lt;/span&gt; &lt;span class="na"&gt;values=&lt;/span&gt;&lt;span class="s"&gt;"0,0; 0,2; 0,0"&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/g&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why both?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The &lt;code&gt;translate&lt;/code&gt; animation adds a subtle vertical bob to the bell’s pivot, simulating the slight lift at the end of a swing. This mimics a real bell’s motion: as it swings forward, the pivot point rises slightly due to the rope’s tension. The &lt;code&gt;search&lt;/code&gt; icon uses a similar combo (&lt;code&gt;translate&lt;/code&gt; + &lt;code&gt;rotate&lt;/code&gt;) for its magnifier’s arc, but the bell’s translation is smaller and faster.&lt;/p&gt;


&lt;h2&gt;
  
  
  Math Behind the Motion: Sine Waves vs. Keyframes
&lt;/h2&gt;

&lt;p&gt;Could we use a sine wave instead of keyframes? SMIL doesn’t support &lt;code&gt;calc()&lt;/code&gt; for complex easing, so keyframes with &lt;code&gt;keySplines&lt;/code&gt; are more flexible. However, the underlying math is similar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rotation(t) = A * sin(2πt/T + φ)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;A&lt;/code&gt; = amplitude (20°)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;T&lt;/code&gt; = period (1.5s)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;φ&lt;/code&gt; = phase shift (to align with clapper strike)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;keyTimes&lt;/code&gt; and &lt;code&gt;keySplines&lt;/code&gt; approximate this sine wave with manual control points. For example, the bell’s forward swing (&lt;code&gt;0 → 20°&lt;/code&gt;) covers &lt;code&gt;50%&lt;/code&gt; of the time, matching the sine wave’s first half-cycle. The overshoot (&lt;code&gt;20° → -10°&lt;/code&gt;) adds a decay factor, like friction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why not pure sine?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Real bells don’t swing in perfect harmonic motion—they lose energy and overshoot. Keyframes let us tweak each segment (acceleration, overshoot, settle) independently, which a single sine function can’t achieve.&lt;/p&gt;




&lt;h2&gt;
  
  
  Practical Takeaways: Applying These Patterns
&lt;/h2&gt;

&lt;p&gt;You can reuse these SMIL patterns in your own icons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;For pendulum motion&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Use &lt;code&gt;rotate&lt;/code&gt; with asymmetric &lt;code&gt;keyTimes&lt;/code&gt; (e.g., &lt;code&gt;0; 0.6; 0.8; 1&lt;/code&gt;) and &lt;code&gt;keySplines&lt;/code&gt; that ease in/out. Offset the clapper’s loop for striking.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;For layered transforms&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Combine &lt;code&gt;rotate&lt;/code&gt; and &lt;code&gt;translate&lt;/code&gt; with &lt;code&gt;additive="sum"&lt;/code&gt; to create complex motion (e.g., a bouncing icon that rotates while translating).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;For organic easing&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Avoid &lt;code&gt;keySplines="0 0 1 1"&lt;/code&gt; (linear) for natural motion. Use &lt;code&gt;0.25 0.1 0.25 1&lt;/code&gt; for slow-start/slow-stop, or &lt;code&gt;0.5 0 0.5 1&lt;/code&gt; for acceleration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;For independent loops&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Give different elements different &lt;code&gt;dur&lt;/code&gt; values and &lt;code&gt;repeatCount="indefinite"&lt;/code&gt;. The &lt;code&gt;menu&lt;/code&gt; icon’s lines have a &lt;code&gt;2s&lt;/code&gt; loop, while the &lt;code&gt;search&lt;/code&gt; icon’s magnifier has a &lt;code&gt;4s&lt;/code&gt; loop—both offset for visual interest.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Conclusion: The Power of Declarative SMIL
&lt;/h2&gt;

&lt;p&gt;The bell icon’s ringing animation demonstrates SMIL’s strength: fine-grained, physics-inspired motion without JavaScript. By combining &lt;code&gt;keyTimes&lt;/code&gt;, &lt;code&gt;keySplines&lt;/code&gt;, and &lt;code&gt;additive&lt;/code&gt; transforms, we create a believable mechanical system. These patterns are reusable across CSSVG’s icon library—whether it’s a bell, a swinging lantern, or a bouncing ball.&lt;/p&gt;

&lt;p&gt;To see these principles in action, explore the full collection at &lt;strong&gt;&lt;a href="https://icon.cssvg.com" rel="noopener noreferrer"&gt;cssvg.com&lt;/a&gt;&lt;/strong&gt;. Every icon is a study in efficient, declarative animation—ready to drop into your React or Next.js project.&lt;/p&gt;

</description>
      <category>svg</category>
      <category>smil</category>
      <category>animation</category>
      <category>icons</category>
    </item>
    <item>
      <title>Animated SVG Icons in React: Why SMIL Still Wins in 2026</title>
      <dc:creator>Hari</dc:creator>
      <pubDate>Wed, 20 May 2026 00:36:23 +0000</pubDate>
      <link>https://dev.to/harijn72/animated-svg-icons-in-react-why-smil-still-wins-in-2026-5p4</link>
      <guid>https://dev.to/harijn72/animated-svg-icons-in-react-why-smil-still-wins-in-2026-5p4</guid>
      <description>&lt;p&gt;For years, the default answer for adding motion to web interfaces has been to reach for a JavaScript animation library. But what if you could achieve complex, performant, and accessible animations with zero runtime JavaScript? That’s the promise of SMIL (Synchronized Multimedia Integration Language) animations inside SVG, and it’s the core technology powering the &lt;code&gt;cssvg-icons&lt;/code&gt; library for React and Next.js.&lt;/p&gt;

&lt;p&gt;In 2026, as web bundles grow and performance budgets tighten, SMIL offers a radically simple and self-contained alternative. Here’s why this decades-old web standard isn’t just viable—it’s often the superior choice for icon animation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Zero-JS Advantage: Animation Without the Bundle Weight
&lt;/h2&gt;

&lt;p&gt;The most compelling reason to use SMIL is its complete lack of JavaScript at runtime. The entire animation logic is embedded directly within the SVG markup.&lt;/p&gt;

&lt;p&gt;Consider the &lt;code&gt;Activity&lt;/code&gt; icon from the library. Its pulsing, scanning effect is defined by a series of &lt;code&gt;&amp;lt;animate&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;animateTransform&amp;gt;&lt;/code&gt; elements inside the SVG. The browser’s native renderer executes this without a single line of JS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// icons/activity/activity.tsx (excerpt)&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;animateTransform&lt;/span&gt;
  &lt;span class="na"&gt;attributeName&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"transform"&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"translate"&lt;/span&gt;
  &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"20,20;20,20;20,20"&lt;/span&gt;
  &lt;span class="na"&gt;dur&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"4s"&lt;/span&gt;
  &lt;span class="na"&gt;repeatCount&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"indefinite"&lt;/span&gt;
  &lt;span class="na"&gt;calcMode&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"spline"&lt;/span&gt;
  &lt;span class="na"&gt;keyTimes&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0;0.0025;1"&lt;/span&gt;
  &lt;span class="na"&gt;keySplines&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0 0 1 1;0 0 1 1"&lt;/span&gt;
  &lt;span class="na"&gt;additive&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"replace"&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern means your React component is just a declarative wrapper. The heavy lifting is done by the browser’s SVG engine. For a typical icon library, this can shave hundreds of kilobytes off your initial JavaScript bundle. In a world of Core Web Vitals, that’s a significant win.&lt;/p&gt;

&lt;h2&gt;
  
  
  Declarative and Portable: Animation as Data
&lt;/h2&gt;

&lt;p&gt;SMIL animations are pure data. They are not tied to any framework’s lifecycle or re-render cycles. This makes them incredibly portable.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;cssvg-icons&lt;/code&gt; library exports standard React components, but the animation logic is framework-agnostic. You could take the raw SVG from &lt;code&gt;icons/crown/crown.svg&lt;/code&gt; and drop it into an Angular, Vue, or Svelte project with identical behavior. The animation is a property of the SVG itself, not the component wrapper.&lt;/p&gt;

&lt;p&gt;This declarative nature also aligns perfectly with React’s philosophy. The component’s props (&lt;code&gt;size&lt;/code&gt;, &lt;code&gt;color&lt;/code&gt;, &lt;code&gt;strokeWidth&lt;/code&gt;) control presentation, while the SVG’s internal SMIL tags control motion. There’s no &lt;code&gt;useEffect&lt;/code&gt; hook to clean up, no &lt;code&gt;requestAnimationFrame&lt;/code&gt; loop to manage. The animation state is isolated and self-maintaining.&lt;/p&gt;

&lt;h2&gt;
  
  
  Complex Motion Without the Code Complexity
&lt;/h2&gt;

&lt;p&gt;A common misconception is that SMIL is only for simple fades and slides. The &lt;code&gt;Menu&lt;/code&gt; icon proves otherwise. It uses multiple, staggered animations on three separate lines to create a smooth morphing effect from a hamburger menu to an "X".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// icons/menu/menu.tsx (excerpt)&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;g&lt;/span&gt; &lt;span class="na"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"translate(20,11.97) rotate(0,0,0) scale(0.2,0.2)"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;animateTransform&lt;/span&gt;
    &lt;span class="na"&gt;attributeName&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"transform"&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"scale"&lt;/span&gt;
    &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0.2,0.2;0.15,0.15;0.2,0.2"&lt;/span&gt;
    &lt;span class="na"&gt;dur&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"2s"&lt;/span&gt;
    &lt;span class="na"&gt;repeatCount&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"indefinite"&lt;/span&gt;
    &lt;span class="na"&gt;calcMode&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"spline"&lt;/span&gt;
    &lt;span class="na"&gt;keyTimes&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0;0.5;1"&lt;/span&gt;
    &lt;span class="na"&gt;keySplines&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0 0 1 1;0 0 1 1"&lt;/span&gt;
    &lt;span class="na"&gt;additive&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"sum"&lt;/span&gt;
  &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;line&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;g&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To achieve this with a JavaScript library, you’d need to calculate keyframes, manage timing offsets, and ensure the animation restarts cleanly on component mount. With SMIL, it’s a few lines of declarative markup. The browser handles the interpolation, timing functions, and lifecycle automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessibility and the Shadow DOM
&lt;/h2&gt;

&lt;p&gt;SVG icons are often used as decorative elements or interactive controls. SMIL animations, being part of the DOM, respect browser accessibility features in ways that canvas or WebGL-based animations often do not.&lt;/p&gt;

&lt;p&gt;Because the animation is defined in the DOM, screen readers can still parse the SVG’s semantic structure (&lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;desc&amp;gt;&lt;/code&gt;) even while it’s moving. The &lt;code&gt;aria-hidden="true"&lt;/code&gt; attribute used in &lt;code&gt;cssvg-icons&lt;/code&gt; components ensures icons are ignored by assistive tech when purely decorative, but for interactive icons, the underlying structure remains accessible.&lt;/p&gt;

&lt;p&gt;Furthermore, SMIL animations are contained within the SVG’s coordinate system. They don’t leak into the global CSS namespace or require complex CSS class management to isolate styles. This containment is a natural fit for component-based architectures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance and the Main Thread
&lt;/h2&gt;

&lt;p&gt;JavaScript animations run on the main thread, competing for resources with your React app’s state updates, event handlers, and other logic. SMIL animations are typically handled by the browser’s compositor thread, which is optimized for graphics rendering.&lt;/p&gt;

&lt;p&gt;This means smoother animations, especially on mobile devices, and less jank when your UI is under heavy interaction load. The &lt;code&gt;Search&lt;/code&gt; icon’s scanning magnifier animation, for instance, runs independently of any JS-driven UI updates on the page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// icons/search/search.tsx (excerpt)&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;animateTransform&lt;/span&gt;
  &lt;span class="na"&gt;attributeName&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"transform"&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"translate"&lt;/span&gt;
  &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"20,20;22.48,15.52;16.16,17.76;23.12,20.72;20,20"&lt;/span&gt;
  &lt;span class="na"&gt;dur&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"4s"&lt;/span&gt;
  &lt;span class="na"&gt;repeatCount&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"indefinite"&lt;/span&gt;
  &lt;span class="na"&gt;calcMode&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"spline"&lt;/span&gt;
  &lt;span class="na"&gt;keyTimes&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0;0.2475;0.5;0.7525;1"&lt;/span&gt;
  &lt;span class="na"&gt;keySplines&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0 0 1 1;0 0 1 1;0 0 1 1;0 0 1 1"&lt;/span&gt;
  &lt;span class="na"&gt;additive&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"replace"&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser can often offload SMIL animation frames to the GPU, resulting in 60fps motion with minimal CPU impact.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Browser Support Reality in 2026
&lt;/h2&gt;

&lt;p&gt;It’s true that SMIL support has been inconsistent historically. But in 2026, the landscape is different. All modern browsers (Chrome, Firefox, Safari, Edge) have mature, stable SVG implementations. SMIL is a W3C recommendation from 1999—it’s one of the most battle-tested web standards we have.&lt;/p&gt;

&lt;p&gt;For the rare edge case (like an old version of Internet Explorer), the &lt;code&gt;cssvg-icons&lt;/code&gt; components are designed to fall back gracefully. The SVG is still a valid, static icon. The animation is a progressive enhancement. This is a more robust strategy than depending on a third-party JS library that might fail to load or execute.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Would You &lt;em&gt;Not&lt;/em&gt; Use SMIL?
&lt;/h2&gt;

&lt;p&gt;SMIL isn’t a silver bullet. For highly interactive, gesture-driven animations that respond to complex user physics, a JS library like Framer Motion might be necessary. SMIL is best for predefined, looping, or triggered animations—exactly the kind used in icon sets, loaders, and micro-interactions.&lt;/p&gt;

&lt;p&gt;If your animation needs to change dynamically based on complex state (e.g., a graph that morphs based on live data), SMIL’s declarative nature can become a limitation. But for the vast majority of UI icons, it’s more than sufficient.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started with SMIL in Your React Project
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;cssvg-icons&lt;/code&gt; library demonstrates the pattern:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Create a simple React wrapper&lt;/strong&gt; that accepts props for &lt;code&gt;size&lt;/code&gt;, &lt;code&gt;color&lt;/code&gt;, and &lt;code&gt;strokeWidth&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Embed the SVG&lt;/strong&gt; with your SMIL animation tags directly inside the return statement.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Use it like any other component&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Bell&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cssvg-icons/icons/bell&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;NotificationBell&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"relative"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Bell&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"red"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"absolute -top-1 -right-1 bg-red-500 text-white text-xs rounded-full"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;unreadCount&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The animation plays automatically on mount. No &lt;code&gt;useEffect&lt;/code&gt;, no cleanup function, no bundle tax.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;SMIL animations in SVG offer a path to lightweight, performant, and accessible motion that integrates seamlessly with React’s declarative model. In 2026, as we optimize for faster load times and smoother experiences, revisiting this mature web standard isn’t just nostalgic—it’s a practical engineering decision.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;cssvg-icons&lt;/code&gt; library exists to prove this point: you can have beautiful, complex, animated icons without the JavaScript overhead. It’s a testament to the power of web platform APIs done right.&lt;/p&gt;

&lt;p&gt;Explore the full collection of animated SVG icons and see the SMIL patterns in action at &lt;a href="https://icon.cssvg.com" rel="noopener noreferrer"&gt;https://icon.cssvg.com&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>svg</category>
      <category>react</category>
      <category>animation</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Animated SVG Icons in React: Why SMIL Still Wins in 2026</title>
      <dc:creator>Hari</dc:creator>
      <pubDate>Mon, 18 May 2026 02:49:44 +0000</pubDate>
      <link>https://dev.to/harijn72/animated-svg-icons-in-react-why-smil-still-wins-in-2026-2mf5</link>
      <guid>https://dev.to/harijn72/animated-svg-icons-in-react-why-smil-still-wins-in-2026-2mf5</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsjk9x3djwmu9jlzv9t8m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsjk9x3djwmu9jlzv9t8m.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For years, the default answer for adding motion to web interfaces has been to reach for a JavaScript animation library. But what if you could achieve complex, performant, and accessible animations with zero runtime JavaScript? That’s the promise of SMIL (Synchronized Multimedia Integration Language) animations inside SVG, and it’s the core technology powering the &lt;code&gt;cssvg-icons&lt;/code&gt; library for React and Next.js.&lt;/p&gt;

&lt;p&gt;In 2026, as web bundles grow and performance budgets tighten, SMIL offers a radically simple and self-contained alternative. Here’s why this decades-old web standard isn’t just viable—it’s often the superior choice for icon animation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Zero-JS Advantage: Animation Without the Bundle Weight
&lt;/h2&gt;

&lt;p&gt;The most compelling reason to use SMIL is its complete lack of JavaScript at runtime. The entire animation logic is embedded directly within the SVG markup.&lt;/p&gt;

&lt;p&gt;Consider the &lt;code&gt;Activity&lt;/code&gt; icon from the library. Its pulsing, scanning effect is defined by a series of &lt;code&gt;&amp;lt;animate&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;animateTransform&amp;gt;&lt;/code&gt; elements inside the SVG. The browser’s native renderer executes this without a single line of JS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// icons/activity/activity.tsx (excerpt)&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;animateTransform&lt;/span&gt;
  &lt;span class="na"&gt;attributeName&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"transform"&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"translate"&lt;/span&gt;
  &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"20,20;20,20;20,20"&lt;/span&gt;
  &lt;span class="na"&gt;dur&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"4s"&lt;/span&gt;
  &lt;span class="na"&gt;repeatCount&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"indefinite"&lt;/span&gt;
  &lt;span class="na"&gt;calcMode&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"spline"&lt;/span&gt;
  &lt;span class="na"&gt;keyTimes&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0;0.0025;1"&lt;/span&gt;
  &lt;span class="na"&gt;keySplines&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0 0 1 1;0 0 1 1"&lt;/span&gt;
  &lt;span class="na"&gt;additive&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"replace"&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern means your React component is just a declarative wrapper. The heavy lifting is done by the browser’s SVG engine. For a typical icon library, this can shave hundreds of kilobytes off your initial JavaScript bundle. In a world of Core Web Vitals, that’s a significant win.&lt;/p&gt;

&lt;h2&gt;
  
  
  Declarative and Portable: Animation as Data
&lt;/h2&gt;

&lt;p&gt;SMIL animations are pure data. They are not tied to any framework’s lifecycle or re-render cycles. This makes them incredibly portable.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;cssvg-icons&lt;/code&gt; library exports standard React components, but the animation logic is framework-agnostic. You could take the raw SVG from &lt;code&gt;icons/crown/crown.svg&lt;/code&gt; and drop it into an Angular, Vue, or Svelte project with identical behavior. The animation is a property of the SVG itself, not the component wrapper.&lt;/p&gt;

&lt;p&gt;This declarative nature also aligns perfectly with React’s philosophy. The component’s props (&lt;code&gt;size&lt;/code&gt;, &lt;code&gt;color&lt;/code&gt;, &lt;code&gt;strokeWidth&lt;/code&gt;) control presentation, while the SVG’s internal SMIL tags control motion. There’s no &lt;code&gt;useEffect&lt;/code&gt; hook to clean up, no &lt;code&gt;requestAnimationFrame&lt;/code&gt; loop to manage. The animation state is isolated and self-maintaining.&lt;/p&gt;

&lt;h2&gt;
  
  
  Complex Motion Without the Code Complexity
&lt;/h2&gt;

&lt;p&gt;A common misconception is that SMIL is only for simple fades and slides. The &lt;code&gt;Menu&lt;/code&gt; icon proves otherwise. It uses multiple, staggered animations on three separate lines to create a smooth morphing effect from a hamburger menu to an "X".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// icons/menu/menu.tsx (excerpt)&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;g&lt;/span&gt; &lt;span class="na"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"translate(20,11.97) rotate(0,0,0) scale(0.2,0.2)"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;animateTransform&lt;/span&gt;
    &lt;span class="na"&gt;attributeName&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"transform"&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"scale"&lt;/span&gt;
    &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0.2,0.2;0.15,0.15;0.2,0.2"&lt;/span&gt;
    &lt;span class="na"&gt;dur&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"2s"&lt;/span&gt;
    &lt;span class="na"&gt;repeatCount&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"indefinite"&lt;/span&gt;
    &lt;span class="na"&gt;calcMode&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"spline"&lt;/span&gt;
    &lt;span class="na"&gt;keyTimes&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0;0.5;1"&lt;/span&gt;
    &lt;span class="na"&gt;keySplines&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0 0 1 1;0 0 1 1"&lt;/span&gt;
    &lt;span class="na"&gt;additive&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"sum"&lt;/span&gt;
  &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;line&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;g&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To achieve this with a JavaScript library, you’d need to calculate keyframes, manage timing offsets, and ensure the animation restarts cleanly on component mount. With SMIL, it’s a few lines of declarative markup. The browser handles the interpolation, timing functions, and lifecycle automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessibility and the Shadow DOM
&lt;/h2&gt;

&lt;p&gt;SVG icons are often used as decorative elements or interactive controls. SMIL animations, being part of the DOM, respect browser accessibility features in ways that canvas or WebGL-based animations often do not.&lt;/p&gt;

&lt;p&gt;Because the animation is defined in the DOM, screen readers can still parse the SVG’s semantic structure (&lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;desc&amp;gt;&lt;/code&gt;) even while it’s moving. The &lt;code&gt;aria-hidden="true"&lt;/code&gt; attribute used in &lt;code&gt;cssvg-icons&lt;/code&gt; components ensures icons are ignored by assistive tech when purely decorative, but for interactive icons, the underlying structure remains accessible.&lt;/p&gt;

&lt;p&gt;Furthermore, SMIL animations are contained within the SVG’s coordinate system. They don’t leak into the global CSS namespace or require complex CSS class management to isolate styles. This containment is a natural fit for component-based architectures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance and the Main Thread
&lt;/h2&gt;

&lt;p&gt;JavaScript animations run on the main thread, competing for resources with your React app’s state updates, event handlers, and other logic. SMIL animations are typically handled by the browser’s compositor thread, which is optimized for graphics rendering.&lt;/p&gt;

&lt;p&gt;This means smoother animations, especially on mobile devices, and less jank when your UI is under heavy interaction load. The &lt;code&gt;Search&lt;/code&gt; icon’s scanning magnifier animation, for instance, runs independently of any JS-driven UI updates on the page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// icons/search/search.tsx (excerpt)&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;animateTransform&lt;/span&gt;
  &lt;span class="na"&gt;attributeName&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"transform"&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"translate"&lt;/span&gt;
  &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"20,20;22.48,15.52;16.16,17.76;23.12,20.72;20,20"&lt;/span&gt;
  &lt;span class="na"&gt;dur&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"4s"&lt;/span&gt;
  &lt;span class="na"&gt;repeatCount&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"indefinite"&lt;/span&gt;
  &lt;span class="na"&gt;calcMode&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"spline"&lt;/span&gt;
  &lt;span class="na"&gt;keyTimes&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0;0.2475;0.5;0.7525;1"&lt;/span&gt;
  &lt;span class="na"&gt;keySplines&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0 0 1 1;0 0 1 1;0 0 1 1;0 0 1 1"&lt;/span&gt;
  &lt;span class="na"&gt;additive&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"replace"&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser can often offload SMIL animation frames to the GPU, resulting in 60fps motion with minimal CPU impact.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Browser Support Reality in 2026
&lt;/h2&gt;

&lt;p&gt;It’s true that SMIL support has been inconsistent historically. But in 2026, the landscape is different. All modern browsers (Chrome, Firefox, Safari, Edge) have mature, stable SVG implementations. SMIL is a W3C recommendation from 1999—it’s one of the most battle-tested web standards we have.&lt;/p&gt;

&lt;p&gt;For the rare edge case (like an old version of Internet Explorer), the &lt;code&gt;cssvg-icons&lt;/code&gt; components are designed to fall back gracefully. The SVG is still a valid, static icon. The animation is a progressive enhancement. This is a more robust strategy than depending on a third-party JS library that might fail to load or execute.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Would You &lt;em&gt;Not&lt;/em&gt; Use SMIL?
&lt;/h2&gt;

&lt;p&gt;SMIL isn’t a silver bullet. For highly interactive, gesture-driven animations that respond to complex user physics, a JS library like Framer Motion might be necessary. SMIL is best for predefined, looping, or triggered animations—exactly the kind used in icon sets, loaders, and micro-interactions.&lt;/p&gt;

&lt;p&gt;If your animation needs to change dynamically based on complex state (e.g., a graph that morphs based on live data), SMIL’s declarative nature can become a limitation. But for the vast majority of UI icons, it’s more than sufficient.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started with SMIL in Your React Project
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;cssvg-icons&lt;/code&gt; library demonstrates the pattern:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Create a simple React wrapper&lt;/strong&gt; that accepts props for &lt;code&gt;size&lt;/code&gt;, &lt;code&gt;color&lt;/code&gt;, and &lt;code&gt;strokeWidth&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Embed the SVG&lt;/strong&gt; with your SMIL animation tags directly inside the return statement.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Use it like any other component&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Bell&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cssvg-icons/icons/bell&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;NotificationBell&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"relative"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Bell&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"red"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"absolute -top-1 -right-1 bg-red-500 text-white text-xs rounded-full"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;unreadCount&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The animation plays automatically on mount. No &lt;code&gt;useEffect&lt;/code&gt;, no cleanup function, no bundle tax.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;SMIL animations in SVG offer a path to lightweight, performant, and accessible motion that integrates seamlessly with React’s declarative model. In 2026, as we optimize for faster load times and smoother experiences, revisiting this mature web standard isn’t just nostalgic—it’s a practical engineering decision.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;cssvg-icons&lt;/code&gt; library exists to prove this point: you can have beautiful, complex, animated icons without the JavaScript overhead. It’s a testament to the power of web platform APIs done right.&lt;/p&gt;

&lt;p&gt;Explore the full collection of animated SVG icons and see the SMIL patterns in action at &lt;a href="https://icon.cssvg.com" rel="noopener noreferrer"&gt;https://icon.cssvg.com&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>svg</category>
      <category>react</category>
      <category>animation</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Export SVG + CSS Animations: Ship Zero-JS Motion to Production</title>
      <dc:creator>Hari</dc:creator>
      <pubDate>Tue, 12 May 2026 11:24:03 +0000</pubDate>
      <link>https://dev.to/harijn72/export-svg-css-animations-ship-zero-js-motion-to-production-1bp9</link>
      <guid>https://dev.to/harijn72/export-svg-css-animations-ship-zero-js-motion-to-production-1bp9</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This article is part of a series on CSS + SVG animations — the zero-JavaScript motion stack.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Modern browsers have a powerful, underappreciated animation system built right in: &lt;strong&gt;SVG + CSS keyframes&lt;/strong&gt;. No runtime, no bundler magic — just markup and styles that the browser hardware-accelerates automatically.&lt;/p&gt;

&lt;p&gt;In this article we'll explore &lt;strong&gt;Export SVG + CSS Animations: Ship Zero-JS Motion to Production&lt;/strong&gt; and look at practical, copy-paste examples you can drop into any React, Vue, or plain HTML project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why SVG + CSS?
&lt;/h2&gt;

&lt;p&gt;SVG shapes live in the DOM. CSS already knows how to animate DOM elements with &lt;code&gt;@keyframes&lt;/code&gt;. The browser's compositor thread handles the rest at a smooth 60 fps — and you ship &lt;strong&gt;zero extra bytes&lt;/strong&gt; to your users.&lt;/p&gt;




&lt;h2&gt;
  
  
  Core Concept
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.05&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.my-shape&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="m"&gt;0.6s&lt;/span&gt; &lt;span class="n"&gt;cubic-bezier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.34&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1.56&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;forwards&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 200 200"&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2000/svg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"my-shape"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"80"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#6366f1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Key Techniques
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Target SVG elements with CSS class selectors
&lt;/h3&gt;

&lt;p&gt;Any SVG element (circle, path, rect, g…) can receive a &lt;code&gt;class&lt;/code&gt; and be animated just like a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Prefer &lt;code&gt;transform&lt;/code&gt; + &lt;code&gt;opacity&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;These two properties trigger GPU compositing — no layout recalculation, no repaint. Always reach for them first.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Use &lt;code&gt;animation-delay&lt;/code&gt; for staggering
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.1s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.2s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Practical Example
&lt;/h2&gt;

&lt;p&gt;Below is a complete, self-contained SVG + CSS animation you can paste anywhere:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;orbit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;to&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;360deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-360deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nc"&gt;.dot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;orbit&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt; &lt;span class="n"&gt;linear&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform-origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 200 200"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"20"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#6366f1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dot"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#f472b6"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Using CSSVG
&lt;/h2&gt;

&lt;p&gt;If you want a visual timeline editor to design motions like this without writing keyframe math by hand, check out &lt;strong&gt;&lt;a href="https://cssvg.com" rel="noopener noreferrer"&gt;CSSVG&lt;/a&gt;&lt;/strong&gt; — it exports clean SVG + CSS that you paste directly into your project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;SVG shapes are DOM elements → CSS can animate them natively&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@keyframes&lt;/code&gt; + &lt;code&gt;transform&lt;/code&gt;/&lt;code&gt;opacity&lt;/code&gt; = GPU-composited, zero-JS animation&lt;/li&gt;
&lt;li&gt;The output is portable markup — works in React, Vue, Svelte, or plain HTML&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Drop a question in the comments if you want me to cover a specific animation technique next!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with &lt;a href="https://cssvg.com" rel="noopener noreferrer"&gt;CSSVG&lt;/a&gt; — the visual CSS + SVG animation editor.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>svg</category>
      <category>css</category>
      <category>performance</category>
      <category>production</category>
    </item>
    <item>
      <title>CSS Keyframe Animation: Orchestrating Complex SVG Sequences</title>
      <dc:creator>Hari</dc:creator>
      <pubDate>Sun, 10 May 2026 10:18:43 +0000</pubDate>
      <link>https://dev.to/harijn72/css-keyframe-animation-orchestrating-complex-svg-sequences-1eed</link>
      <guid>https://dev.to/harijn72/css-keyframe-animation-orchestrating-complex-svg-sequences-1eed</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This article is part of a series on CSS + SVG animations — the zero-JavaScript motion stack.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Modern browsers have a powerful, underappreciated animation system built right in: &lt;strong&gt;SVG + CSS keyframes&lt;/strong&gt;. No runtime, no bundler magic — just markup and styles that the browser hardware-accelerates automatically.&lt;/p&gt;

&lt;p&gt;In this article we'll explore &lt;strong&gt;CSS Keyframe Animation: Orchestrating Complex SVG Sequences&lt;/strong&gt; and look at practical, copy-paste examples you can drop into any React, Vue, or plain HTML project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why SVG + CSS?
&lt;/h2&gt;

&lt;p&gt;SVG shapes live in the DOM. CSS already knows how to animate DOM elements with &lt;code&gt;@keyframes&lt;/code&gt;. The browser's compositor thread handles the rest at a smooth 60 fps — and you ship &lt;strong&gt;zero extra bytes&lt;/strong&gt; to your users.&lt;/p&gt;




&lt;h2&gt;
  
  
  Core Concept
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.05&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.my-shape&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="m"&gt;0.6s&lt;/span&gt; &lt;span class="n"&gt;cubic-bezier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.34&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1.56&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;forwards&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 200 200"&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2000/svg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"my-shape"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"80"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#6366f1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Key Techniques
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Target SVG elements with CSS class selectors
&lt;/h3&gt;

&lt;p&gt;Any SVG element (circle, path, rect, g…) can receive a &lt;code&gt;class&lt;/code&gt; and be animated just like a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Prefer &lt;code&gt;transform&lt;/code&gt; + &lt;code&gt;opacity&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;These two properties trigger GPU compositing — no layout recalculation, no repaint. Always reach for them first.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Use &lt;code&gt;animation-delay&lt;/code&gt; for staggering
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.1s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.2s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Practical Example
&lt;/h2&gt;

&lt;p&gt;Below is a complete, self-contained SVG + CSS animation you can paste anywhere:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;orbit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;to&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;360deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-360deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nc"&gt;.dot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;orbit&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt; &lt;span class="n"&gt;linear&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform-origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 200 200"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"20"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#6366f1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dot"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#f472b6"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Using CSSVG
&lt;/h2&gt;

&lt;p&gt;If you want a visual timeline editor to design motions like this without writing keyframe math by hand, check out &lt;strong&gt;&lt;a href="https://cssvg.com" rel="noopener noreferrer"&gt;CSSVG&lt;/a&gt;&lt;/strong&gt; — it exports clean SVG + CSS that you paste directly into your project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;SVG shapes are DOM elements → CSS can animate them natively&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@keyframes&lt;/code&gt; + &lt;code&gt;transform&lt;/code&gt;/&lt;code&gt;opacity&lt;/code&gt; = GPU-composited, zero-JS animation&lt;/li&gt;
&lt;li&gt;The output is portable markup — works in React, Vue, Svelte, or plain HTML&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Drop a question in the comments if you want me to cover a specific animation technique next!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with &lt;a href="https://cssvg.com" rel="noopener noreferrer"&gt;CSSVG&lt;/a&gt; — the visual CSS + SVG animation editor.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>svg</category>
      <category>keyframes</category>
      <category>advanced</category>
    </item>
    <item>
      <title>Building an Animated SVG Icon System with CSS</title>
      <dc:creator>Hari</dc:creator>
      <pubDate>Fri, 08 May 2026 10:27:13 +0000</pubDate>
      <link>https://dev.to/harijn72/building-an-animated-svg-icon-system-with-css-1bnl</link>
      <guid>https://dev.to/harijn72/building-an-animated-svg-icon-system-with-css-1bnl</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This article is part of a series on CSS + SVG animations — the zero-JavaScript motion stack.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Modern browsers have a powerful, underappreciated animation system built right in: &lt;strong&gt;SVG + CSS keyframes&lt;/strong&gt;. No runtime, no bundler magic — just markup and styles that the browser hardware-accelerates automatically.&lt;/p&gt;

&lt;p&gt;In this article we'll explore &lt;strong&gt;Building an Animated SVG Icon System with CSS&lt;/strong&gt; and look at practical, copy-paste examples you can drop into any React, Vue, or plain HTML project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why SVG + CSS?
&lt;/h2&gt;

&lt;p&gt;SVG shapes live in the DOM. CSS already knows how to animate DOM elements with &lt;code&gt;@keyframes&lt;/code&gt;. The browser's compositor thread handles the rest at a smooth 60 fps — and you ship &lt;strong&gt;zero extra bytes&lt;/strong&gt; to your users.&lt;/p&gt;




&lt;h2&gt;
  
  
  Core Concept
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.05&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.my-shape&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="m"&gt;0.6s&lt;/span&gt; &lt;span class="n"&gt;cubic-bezier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.34&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1.56&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;forwards&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 200 200"&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2000/svg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"my-shape"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"80"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#6366f1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Key Techniques
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Target SVG elements with CSS class selectors
&lt;/h3&gt;

&lt;p&gt;Any SVG element (circle, path, rect, g…) can receive a &lt;code&gt;class&lt;/code&gt; and be animated just like a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Prefer &lt;code&gt;transform&lt;/code&gt; + &lt;code&gt;opacity&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;These two properties trigger GPU compositing — no layout recalculation, no repaint. Always reach for them first.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Use &lt;code&gt;animation-delay&lt;/code&gt; for staggering
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.1s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.2s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Practical Example
&lt;/h2&gt;

&lt;p&gt;Below is a complete, self-contained SVG + CSS animation you can paste anywhere:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;orbit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;to&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;360deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-360deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nc"&gt;.dot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;orbit&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt; &lt;span class="n"&gt;linear&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform-origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 200 200"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"20"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#6366f1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dot"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#f472b6"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Using CSSVG
&lt;/h2&gt;

&lt;p&gt;If you want a visual timeline editor to design motions like this without writing keyframe math by hand, check out &lt;strong&gt;&lt;a href="https://cssvg.com" rel="noopener noreferrer"&gt;CSSVG&lt;/a&gt;&lt;/strong&gt; — it exports clean SVG + CSS that you paste directly into your project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;SVG shapes are DOM elements → CSS can animate them natively&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@keyframes&lt;/code&gt; + &lt;code&gt;transform&lt;/code&gt;/&lt;code&gt;opacity&lt;/code&gt; = GPU-composited, zero-JS animation&lt;/li&gt;
&lt;li&gt;The output is portable markup — works in React, Vue, Svelte, or plain HTML&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Drop a question in the comments if you want me to cover a specific animation technique next!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with &lt;a href="https://cssvg.com" rel="noopener noreferrer"&gt;CSSVG&lt;/a&gt; — the visual CSS + SVG animation editor.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>svg</category>
      <category>css</category>
      <category>icons</category>
      <category>ui</category>
    </item>
    <item>
      <title>CSS Animation with SVG clip-path: Creative Masking Effects</title>
      <dc:creator>Hari</dc:creator>
      <pubDate>Thu, 07 May 2026 08:13:09 +0000</pubDate>
      <link>https://dev.to/harijn72/css-animation-with-svg-clip-path-creative-masking-effects-1581</link>
      <guid>https://dev.to/harijn72/css-animation-with-svg-clip-path-creative-masking-effects-1581</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This article is part of a series on CSS + SVG animations — the zero-JavaScript motion stack.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Modern browsers have a powerful, underappreciated animation system built right in: &lt;strong&gt;SVG + CSS keyframes&lt;/strong&gt;. No runtime, no bundler magic — just markup and styles that the browser hardware-accelerates automatically.&lt;/p&gt;

&lt;p&gt;In this article we'll explore &lt;strong&gt;CSS Animation with SVG clip-path: Creative Masking Effects&lt;/strong&gt; and look at practical, copy-paste examples you can drop into any React, Vue, or plain HTML project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why SVG + CSS?
&lt;/h2&gt;

&lt;p&gt;SVG shapes live in the DOM. CSS already knows how to animate DOM elements with &lt;code&gt;@keyframes&lt;/code&gt;. The browser's compositor thread handles the rest at a smooth 60 fps — and you ship &lt;strong&gt;zero extra bytes&lt;/strong&gt; to your users.&lt;/p&gt;




&lt;h2&gt;
  
  
  Core Concept
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.05&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.my-shape&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="m"&gt;0.6s&lt;/span&gt; &lt;span class="n"&gt;cubic-bezier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.34&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1.56&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;forwards&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 200 200"&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2000/svg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"my-shape"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"80"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#6366f1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Key Techniques
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Target SVG elements with CSS class selectors
&lt;/h3&gt;

&lt;p&gt;Any SVG element (circle, path, rect, g…) can receive a &lt;code&gt;class&lt;/code&gt; and be animated just like a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Prefer &lt;code&gt;transform&lt;/code&gt; + &lt;code&gt;opacity&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;These two properties trigger GPU compositing — no layout recalculation, no repaint. Always reach for them first.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Use &lt;code&gt;animation-delay&lt;/code&gt; for staggering
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.1s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.2s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Practical Example
&lt;/h2&gt;

&lt;p&gt;Below is a complete, self-contained SVG + CSS animation you can paste anywhere:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;orbit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;to&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;360deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-360deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nc"&gt;.dot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;orbit&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt; &lt;span class="n"&gt;linear&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform-origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 200 200"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"20"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#6366f1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dot"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#f472b6"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Using CSSVG
&lt;/h2&gt;

&lt;p&gt;If you want a visual timeline editor to design motions like this without writing keyframe math by hand, check out &lt;strong&gt;&lt;a href="https://cssvg.com" rel="noopener noreferrer"&gt;CSSVG&lt;/a&gt;&lt;/strong&gt; — it exports clean SVG + CSS that you paste directly into your project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;SVG shapes are DOM elements → CSS can animate them natively&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@keyframes&lt;/code&gt; + &lt;code&gt;transform&lt;/code&gt;/&lt;code&gt;opacity&lt;/code&gt; = GPU-composited, zero-JS animation&lt;/li&gt;
&lt;li&gt;The output is portable markup — works in React, Vue, Svelte, or plain HTML&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Drop a question in the comments if you want me to cover a specific animation technique next!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with &lt;a href="https://cssvg.com" rel="noopener noreferrer"&gt;CSSVG&lt;/a&gt; — the visual CSS + SVG animation editor.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>svg</category>
      <category>clippath</category>
      <category>effects</category>
    </item>
    <item>
      <title>Responsive SVG Animations That Scale with CSS</title>
      <dc:creator>Hari</dc:creator>
      <pubDate>Sun, 03 May 2026 10:10:11 +0000</pubDate>
      <link>https://dev.to/harijn72/responsive-svg-animations-that-scale-with-css-2h79</link>
      <guid>https://dev.to/harijn72/responsive-svg-animations-that-scale-with-css-2h79</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This article is part of a series on CSS + SVG animations — the zero-JavaScript motion stack.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Modern browsers have a powerful, underappreciated animation system built right in: &lt;strong&gt;SVG + CSS keyframes&lt;/strong&gt;. No runtime, no bundler magic — just markup and styles that the browser hardware-accelerates automatically.&lt;/p&gt;

&lt;p&gt;In this article we'll explore &lt;strong&gt;Responsive SVG Animations That Scale with CSS&lt;/strong&gt; and look at practical, copy-paste examples you can drop into any React, Vue, or plain HTML project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why SVG + CSS?
&lt;/h2&gt;

&lt;p&gt;SVG shapes live in the DOM. CSS already knows how to animate DOM elements with &lt;code&gt;@keyframes&lt;/code&gt;. The browser's compositor thread handles the rest at a smooth 60 fps — and you ship &lt;strong&gt;zero extra bytes&lt;/strong&gt; to your users.&lt;/p&gt;




&lt;h2&gt;
  
  
  Core Concept
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.05&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.my-shape&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="m"&gt;0.6s&lt;/span&gt; &lt;span class="n"&gt;cubic-bezier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.34&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1.56&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;forwards&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 200 200"&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2000/svg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"my-shape"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"80"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#6366f1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Key Techniques
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Target SVG elements with CSS class selectors
&lt;/h3&gt;

&lt;p&gt;Any SVG element (circle, path, rect, g…) can receive a &lt;code&gt;class&lt;/code&gt; and be animated just like a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Prefer &lt;code&gt;transform&lt;/code&gt; + &lt;code&gt;opacity&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;These two properties trigger GPU compositing — no layout recalculation, no repaint. Always reach for them first.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Use &lt;code&gt;animation-delay&lt;/code&gt; for staggering
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.1s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.2s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Practical Example
&lt;/h2&gt;

&lt;p&gt;Below is a complete, self-contained SVG + CSS animation you can paste anywhere:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;orbit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;to&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;360deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-360deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nc"&gt;.dot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;orbit&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt; &lt;span class="n"&gt;linear&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform-origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 200 200"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"20"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#6366f1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dot"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#f472b6"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Using CSSVG
&lt;/h2&gt;

&lt;p&gt;If you want a visual timeline editor to design motions like this without writing keyframe math by hand, check out &lt;strong&gt;&lt;a href="https://cssvg.com" rel="noopener noreferrer"&gt;CSSVG&lt;/a&gt;&lt;/strong&gt; — it exports clean SVG + CSS that you paste directly into your project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;SVG shapes are DOM elements → CSS can animate them natively&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@keyframes&lt;/code&gt; + &lt;code&gt;transform&lt;/code&gt;/&lt;code&gt;opacity&lt;/code&gt; = GPU-composited, zero-JS animation&lt;/li&gt;
&lt;li&gt;The output is portable markup — works in React, Vue, Svelte, or plain HTML&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Drop a question in the comments if you want me to cover a specific animation technique next!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with &lt;a href="https://cssvg.com" rel="noopener noreferrer"&gt;CSSVG&lt;/a&gt; — the visual CSS + SVG animation editor.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>svg</category>
      <category>css</category>
      <category>responsive</category>
      <category>animation</category>
    </item>
    <item>
      <title>CSS Animation vs SMIL: Why CSS Always Wins for SVG</title>
      <dc:creator>Hari</dc:creator>
      <pubDate>Fri, 01 May 2026 10:25:59 +0000</pubDate>
      <link>https://dev.to/harijn72/css-animation-vs-smil-why-css-always-wins-for-svg-amk</link>
      <guid>https://dev.to/harijn72/css-animation-vs-smil-why-css-always-wins-for-svg-amk</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This article is part of a series on CSS + SVG animations — the zero-JavaScript motion stack.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Modern browsers have a powerful, underappreciated animation system built right in: &lt;strong&gt;SVG + CSS keyframes&lt;/strong&gt;. No runtime, no bundler magic — just markup and styles that the browser hardware-accelerates automatically.&lt;/p&gt;

&lt;p&gt;In this article we'll explore &lt;strong&gt;CSS Animation vs SMIL: Why CSS Always Wins for SVG&lt;/strong&gt; and look at practical, copy-paste examples you can drop into any React, Vue, or plain HTML project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why SVG + CSS?
&lt;/h2&gt;

&lt;p&gt;SVG shapes live in the DOM. CSS already knows how to animate DOM elements with &lt;code&gt;@keyframes&lt;/code&gt;. The browser's compositor thread handles the rest at a smooth 60 fps — and you ship &lt;strong&gt;zero extra bytes&lt;/strong&gt; to your users.&lt;/p&gt;




&lt;h2&gt;
  
  
  Core Concept
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.05&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.my-shape&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="m"&gt;0.6s&lt;/span&gt; &lt;span class="n"&gt;cubic-bezier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.34&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1.56&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;forwards&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 200 200"&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2000/svg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"my-shape"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"80"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#6366f1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Key Techniques
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Target SVG elements with CSS class selectors
&lt;/h3&gt;

&lt;p&gt;Any SVG element (circle, path, rect, g…) can receive a &lt;code&gt;class&lt;/code&gt; and be animated just like a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Prefer &lt;code&gt;transform&lt;/code&gt; + &lt;code&gt;opacity&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;These two properties trigger GPU compositing — no layout recalculation, no repaint. Always reach for them first.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Use &lt;code&gt;animation-delay&lt;/code&gt; for staggering
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.1s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.2s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Practical Example
&lt;/h2&gt;

&lt;p&gt;Below is a complete, self-contained SVG + CSS animation you can paste anywhere:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;orbit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;to&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;360deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-360deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nc"&gt;.dot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;orbit&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt; &lt;span class="n"&gt;linear&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform-origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 200 200"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"20"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#6366f1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dot"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#f472b6"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Using CSSVG
&lt;/h2&gt;

&lt;p&gt;If you want a visual timeline editor to design motions like this without writing keyframe math by hand, check out &lt;strong&gt;&lt;a href="https://cssvg.com" rel="noopener noreferrer"&gt;CSSVG&lt;/a&gt;&lt;/strong&gt; — it exports clean SVG + CSS that you paste directly into your project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;SVG shapes are DOM elements → CSS can animate them natively&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@keyframes&lt;/code&gt; + &lt;code&gt;transform&lt;/code&gt;/&lt;code&gt;opacity&lt;/code&gt; = GPU-composited, zero-JS animation&lt;/li&gt;
&lt;li&gt;The output is portable markup — works in React, Vue, Svelte, or plain HTML&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Drop a question in the comments if you want me to cover a specific animation technique next!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with &lt;a href="https://cssvg.com" rel="noopener noreferrer"&gt;CSSVG&lt;/a&gt; — the visual CSS + SVG animation editor.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>svg</category>
      <category>smil</category>
      <category>comparison</category>
    </item>
    <item>
      <title>SVG Text Animations with CSS: Typewriter, Fade &amp; Reveal</title>
      <dc:creator>Hari</dc:creator>
      <pubDate>Wed, 29 Apr 2026 11:00:17 +0000</pubDate>
      <link>https://dev.to/harijn72/svg-text-animations-with-css-typewriter-fade-reveal-1167</link>
      <guid>https://dev.to/harijn72/svg-text-animations-with-css-typewriter-fade-reveal-1167</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This article is part of a series on CSS + SVG animations — the zero-JavaScript motion stack.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Modern browsers have a powerful, underappreciated animation system built right in: &lt;strong&gt;SVG + CSS keyframes&lt;/strong&gt;. No runtime, no bundler magic — just markup and styles that the browser hardware-accelerates automatically.&lt;/p&gt;

&lt;p&gt;In this article we'll explore &lt;strong&gt;SVG Text Animations with CSS: Typewriter, Fade &amp;amp; Reveal&lt;/strong&gt; and look at practical, copy-paste examples you can drop into any React, Vue, or plain HTML project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why SVG + CSS?
&lt;/h2&gt;

&lt;p&gt;SVG shapes live in the DOM. CSS already knows how to animate DOM elements with &lt;code&gt;@keyframes&lt;/code&gt;. The browser's compositor thread handles the rest at a smooth 60 fps — and you ship &lt;strong&gt;zero extra bytes&lt;/strong&gt; to your users.&lt;/p&gt;




&lt;h2&gt;
  
  
  Core Concept
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.05&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.my-shape&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="m"&gt;0.6s&lt;/span&gt; &lt;span class="n"&gt;cubic-bezier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.34&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1.56&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;forwards&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 200 200"&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2000/svg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"my-shape"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"80"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#6366f1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Key Techniques
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Target SVG elements with CSS class selectors
&lt;/h3&gt;

&lt;p&gt;Any SVG element (circle, path, rect, g…) can receive a &lt;code&gt;class&lt;/code&gt; and be animated just like a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Prefer &lt;code&gt;transform&lt;/code&gt; + &lt;code&gt;opacity&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;These two properties trigger GPU compositing — no layout recalculation, no repaint. Always reach for them first.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Use &lt;code&gt;animation-delay&lt;/code&gt; for staggering
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.1s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.2s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Practical Example
&lt;/h2&gt;

&lt;p&gt;Below is a complete, self-contained SVG + CSS animation you can paste anywhere:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;orbit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;to&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;360deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-360deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nc"&gt;.dot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;orbit&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt; &lt;span class="n"&gt;linear&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform-origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 200 200"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"20"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#6366f1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dot"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#f472b6"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Using CSSVG
&lt;/h2&gt;

&lt;p&gt;If you want a visual timeline editor to design motions like this without writing keyframe math by hand, check out &lt;strong&gt;&lt;a href="https://cssvg.com" rel="noopener noreferrer"&gt;CSSVG&lt;/a&gt;&lt;/strong&gt; — it exports clean SVG + CSS that you paste directly into your project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;SVG shapes are DOM elements → CSS can animate them natively&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@keyframes&lt;/code&gt; + &lt;code&gt;transform&lt;/code&gt;/&lt;code&gt;opacity&lt;/code&gt; = GPU-composited, zero-JS animation&lt;/li&gt;
&lt;li&gt;The output is portable markup — works in React, Vue, Svelte, or plain HTML&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Drop a question in the comments if you want me to cover a specific animation technique next!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with &lt;a href="https://cssvg.com" rel="noopener noreferrer"&gt;CSSVG&lt;/a&gt; — the visual CSS + SVG animation editor.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>svg</category>
      <category>css</category>
      <category>text</category>
      <category>animation</category>
    </item>
    <item>
      <title>Infinite CSS Animations: Creating Seamless SVG Loops</title>
      <dc:creator>Hari</dc:creator>
      <pubDate>Mon, 27 Apr 2026 11:08:28 +0000</pubDate>
      <link>https://dev.to/harijn72/infinite-css-animations-creating-seamless-svg-loops-558k</link>
      <guid>https://dev.to/harijn72/infinite-css-animations-creating-seamless-svg-loops-558k</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This article is part of a series on CSS + SVG animations — the zero-JavaScript motion stack.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Modern browsers have a powerful, underappreciated animation system built right in: &lt;strong&gt;SVG + CSS keyframes&lt;/strong&gt;. No runtime, no bundler magic — just markup and styles that the browser hardware-accelerates automatically.&lt;/p&gt;

&lt;p&gt;In this article we'll explore &lt;strong&gt;Infinite CSS Animations: Creating Seamless SVG Loops&lt;/strong&gt; and look at practical, copy-paste examples you can drop into any React, Vue, or plain HTML project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why SVG + CSS?
&lt;/h2&gt;

&lt;p&gt;SVG shapes live in the DOM. CSS already knows how to animate DOM elements with &lt;code&gt;@keyframes&lt;/code&gt;. The browser's compositor thread handles the rest at a smooth 60 fps — and you ship &lt;strong&gt;zero extra bytes&lt;/strong&gt; to your users.&lt;/p&gt;




&lt;h2&gt;
  
  
  Core Concept
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.05&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.my-shape&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="m"&gt;0.6s&lt;/span&gt; &lt;span class="n"&gt;cubic-bezier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.34&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1.56&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;forwards&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 200 200"&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2000/svg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"my-shape"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"80"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#6366f1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Key Techniques
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Target SVG elements with CSS class selectors
&lt;/h3&gt;

&lt;p&gt;Any SVG element (circle, path, rect, g…) can receive a &lt;code&gt;class&lt;/code&gt; and be animated just like a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Prefer &lt;code&gt;transform&lt;/code&gt; + &lt;code&gt;opacity&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;These two properties trigger GPU compositing — no layout recalculation, no repaint. Always reach for them first.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Use &lt;code&gt;animation-delay&lt;/code&gt; for staggering
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.1s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.2s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Practical Example
&lt;/h2&gt;

&lt;p&gt;Below is a complete, self-contained SVG + CSS animation you can paste anywhere:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;orbit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;to&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;360deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-360deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nc"&gt;.dot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;orbit&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt; &lt;span class="n"&gt;linear&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform-origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 200 200"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"20"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#6366f1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dot"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#f472b6"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Using CSSVG
&lt;/h2&gt;

&lt;p&gt;If you want a visual timeline editor to design motions like this without writing keyframe math by hand, check out &lt;strong&gt;&lt;a href="https://cssvg.com" rel="noopener noreferrer"&gt;CSSVG&lt;/a&gt;&lt;/strong&gt; — it exports clean SVG + CSS that you paste directly into your project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;SVG shapes are DOM elements → CSS can animate them natively&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@keyframes&lt;/code&gt; + &lt;code&gt;transform&lt;/code&gt;/&lt;code&gt;opacity&lt;/code&gt; = GPU-composited, zero-JS animation&lt;/li&gt;
&lt;li&gt;The output is portable markup — works in React, Vue, Svelte, or plain HTML&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Drop a question in the comments if you want me to cover a specific animation technique next!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with &lt;a href="https://cssvg.com" rel="noopener noreferrer"&gt;CSSVG&lt;/a&gt; — the visual CSS + SVG animation editor.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>svg</category>
      <category>infinite</category>
      <category>animation</category>
    </item>
    <item>
      <title>SVG Filter Animations with CSS: Glow, Blur &amp; Drop Shadow</title>
      <dc:creator>Hari</dc:creator>
      <pubDate>Sat, 25 Apr 2026 09:56:40 +0000</pubDate>
      <link>https://dev.to/harijn72/svg-filter-animations-with-css-glow-blur-drop-shadow-3kli</link>
      <guid>https://dev.to/harijn72/svg-filter-animations-with-css-glow-blur-drop-shadow-3kli</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This article is part of a series on CSS + SVG animations — the zero-JavaScript motion stack.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Modern browsers have a powerful, underappreciated animation system built right in: &lt;strong&gt;SVG + CSS keyframes&lt;/strong&gt;. No runtime, no bundler magic — just markup and styles that the browser hardware-accelerates automatically.&lt;/p&gt;

&lt;p&gt;In this article we'll explore &lt;strong&gt;SVG Filter Animations with CSS: Glow, Blur &amp;amp; Drop Shadow&lt;/strong&gt; and look at practical, copy-paste examples you can drop into any React, Vue, or plain HTML project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why SVG + CSS?
&lt;/h2&gt;

&lt;p&gt;SVG shapes live in the DOM. CSS already knows how to animate DOM elements with &lt;code&gt;@keyframes&lt;/code&gt;. The browser's compositor thread handles the rest at a smooth 60 fps — and you ship &lt;strong&gt;zero extra bytes&lt;/strong&gt; to your users.&lt;/p&gt;




&lt;h2&gt;
  
  
  Core Concept
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.05&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.my-shape&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="m"&gt;0.6s&lt;/span&gt; &lt;span class="n"&gt;cubic-bezier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.34&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1.56&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;forwards&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 200 200"&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2000/svg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"my-shape"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"80"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#6366f1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Key Techniques
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Target SVG elements with CSS class selectors
&lt;/h3&gt;

&lt;p&gt;Any SVG element (circle, path, rect, g…) can receive a &lt;code&gt;class&lt;/code&gt; and be animated just like a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Prefer &lt;code&gt;transform&lt;/code&gt; + &lt;code&gt;opacity&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;These two properties trigger GPU compositing — no layout recalculation, no repaint. Always reach for them first.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Use &lt;code&gt;animation-delay&lt;/code&gt; for staggering
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.1s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.item&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.2s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Practical Example
&lt;/h2&gt;

&lt;p&gt;Below is a complete, self-contained SVG + CSS animation you can paste anywhere:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;orbit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;to&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;360deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-360deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nc"&gt;.dot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;orbit&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt; &lt;span class="n"&gt;linear&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;transform-origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 200 200"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"20"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#6366f1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dot"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#f472b6"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Using CSSVG
&lt;/h2&gt;

&lt;p&gt;If you want a visual timeline editor to design motions like this without writing keyframe math by hand, check out &lt;strong&gt;&lt;a href="https://cssvg.com" rel="noopener noreferrer"&gt;CSSVG&lt;/a&gt;&lt;/strong&gt; — it exports clean SVG + CSS that you paste directly into your project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;SVG shapes are DOM elements → CSS can animate them natively&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@keyframes&lt;/code&gt; + &lt;code&gt;transform&lt;/code&gt;/&lt;code&gt;opacity&lt;/code&gt; = GPU-composited, zero-JS animation&lt;/li&gt;
&lt;li&gt;The output is portable markup — works in React, Vue, Svelte, or plain HTML&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Drop a question in the comments if you want me to cover a specific animation technique next!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with &lt;a href="https://cssvg.com" rel="noopener noreferrer"&gt;CSSVG&lt;/a&gt; — the visual CSS + SVG animation editor.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>svg</category>
      <category>css</category>
      <category>filters</category>
      <category>effects</category>
    </item>
  </channel>
</rss>
