DEV Community

Cover image for Pure HTML Animation - Animate SVG with <animate>
The Liquid Charcoal
The Liquid Charcoal

Posted on • Edited on

Pure HTML Animation - Animate SVG with <animate>

In this animation markup, there is no use of CSS or JS for animation purposes.

For a long time, everybody has been talking about CSS and JS animation or animation libraries. I am wondering why no one is talking about HTML <animate> tag.

I wish some big names around would have pushed this animate element of SVG to promote more development over it. Anyways, it is never too late to start something good. I am taking this initiative to start spreading awareness around the front-end community regarding animate element of SVG.

Let's understand SVG first in short.

first thing first - W3schools is always a great start.

What is SVG?

  • SVG stands for Scalable Vector Graphics
  • SVG is used to define vector-based graphics for the Web
  • SVG defines the graphics in XML format
  • Every element and every attribute in SVG files can be animated
  • SVG is a W3C recommendation
  • SVG integrates with other W3C standards such as the DOM and XSL

Why SVG? I'll tell you.

  • It's a Vector.
  • Being vector it is scalable.
  • Smaller file-size. (Average 5X smaller than png file.)
  • Easy to modify using CSS and JS.
  • Easily Animatable :) in less time. Also, no need for any animation software or image processors.

Note :
If you are a first timer to SVG, please get yourself some helpful information about SVG and it's relatives from Sara Soueidan's Blog on understanding SVG Coordinate Systems and Transformations.

Alright, enough talk let's get in action. Open your favorite code editor and start your browser. I have used sublime text 3 and chrome browser by google for this tutorial.

We will go step by step.

Step 1: Prepare html structure.

If you are familiar with Emmet. Just type html:5 in your emmet enabled editor and execute it for sublime text execution key is Tab Key.

--OR--

Copy the code from below.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>SVG wave animation</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- Wave SVG Animation -->
  <div class="waves"></div>

</body>
</html>

Enter fullscreen mode Exit fullscreen mode

Step 2: Drawing a wave-like shape.

I am not good at drawing but, I can tell you that cubic bezier is something we can consider as a wave. So, we will draw a cubic Bezier curve.

<div class="waves">
    <svg width="100%" height="200px" fill="none">
        <path
            fill="#454599"
            d="
                M 0 67 
                C 273,183
                  822,-40
                  1920,106 

                V 359 
                H 0 
                V 67 
                Z"> 
        </path>
    </svg>
</div>

Enter fullscreen mode Exit fullscreen mode

Result should something like this:

Drawing a cubic bezier curve

Here, I have styled background and positioned div using CSS. You can get the CSS from the codepen link of this project at the bottom.
Let me explain you first what's going on with those numbers and letters.

Welcome to the Matrix!
You need to know those green rainfall of numbers from the matrix. (Ignore it)

Okay So, there are three attributes attached to <svg width="100%" height="200px" fill="none"> and they explain themselves pretty well.

Also, inside the <svg> element there is the element <path> and attached with two attributes fill and d. You still can understand that we are starting to draw a path with <path> element and filling it with color with fill attribute inside. But, hey! What's that d ="1230948713294" about? That's what your question is right? And that's what I want you to understand the most as it is the thing we are going to play within this tutorial.

Curves Hannhh

There are three variants of smooth curves available to draw with SVG.

  1. Quadratic Bezier curve
  2. Cubic Bezier curve
  3. Arc

Three Variants of smooth Curves. From left -> *(i) Quadratic Bezier Curve, (ii) Cubic Bezier Curve (iii)Arc *

We will work with cubic bezier curve in this tutorial. So, let's understand how it works.

If you have any experience with Illustrator or Sketch like softwares, or something like the pen tool you will understand it easily. But, if you do not have any experience with the pen tool, nothing to worry about it. I will explain how bezier curve works at my best.

Bezier curve has two main points and we will call it a start point and end point, and each main point has their handles which we will call control points.

Let's understand with the figure below.
Cubic Bezier Curve

In the figure above:

M x,y is Start Point
C dx1,dy1 is Control Point for Start Point

C x2,y2 is End Point
C dx2,dy2 is Control Point for End Point

That means,

M 0 67                   M x,y
C 273,183                C dX1,dy1
  822,-40      -->         dx2,dy2
  1920,106                 x2,y2
Enter fullscreen mode Exit fullscreen mode

Important: we are using absolute Bezier curve in this example by using C 273 .... If you want to use a relative Bezier curve you can change the **UPPERCASE* C 273 ... to LOWERCASE c 273... however it will need modification in defining points.*

Mozilla developer community has a great explanation guide for absolute and relative curves please visit Mozilla Documentation for Cubic Bezier Curves

Step 3: Start waving the wave.

Before we start animating wave, let's quickly review how we are going to do it.

We will do it with <animate> element of SVG. In addition, we will use some attributes of <animate> element. Firstly as we want the wave to keep waving itself, we will use repeatCount="indefinite". Secondly, we will fill our wave with some color by adding fill="#454599" attribute. After that, we will target the d attribute from <svg> element with attributeName="d" and we will define the duration for the animation by adding dur="12s" attribute. Coming up next, we will talk about the values="" attribute.

<animate 
          repeatCount="indefinite" 
          fill="#454599" 
          attributeName="d" 
          dur="12s" 
          values=""
></animate>
Enter fullscreen mode Exit fullscreen mode

values="" attribute can be written in several ways depending upon the context where it is being used. On the other hand, if interpreter finds the specification of the list of values, the interpreter will ignore the values of the attributes to, from and by. Recommended article for more details.

In our case, we are targeting d attribute of <svg> element to modify the curve. We also have defined the duration of 12s, that means we can break the iterations in 4 phases of 3 seconds each. Let's start now...

values="
        M0 77 
        C 473,283
          822,-40
          1920,116 

        V 359 
        H 0 
        V 67 
        Z;

        *second and third iteration will go here*       

        M0 77 
        C 473,283
          822,-40
          1920,116 

        V 359 
        H 0 
        V 67 
        Z;

"

Enter fullscreen mode Exit fullscreen mode

You might be wondering why I am using the same value for two times?
It is because we will come back to where we started by the end of the fourth iteration of our animation cycle, and we will make some movements in the shape during the second and the third iteration.

Let's make the second and the third animation iteration now.

second iteration

M0 77 
C 473,-40
  1222,283
  1920,136 

V 359 
H 0 
V 67 
Z; 
Enter fullscreen mode Exit fullscreen mode

third iteration

M0 77 
C 973,260
  1722,-53
  1920,120 

V 359 
H 0 
V 67 
Z; 

Enter fullscreen mode Exit fullscreen mode

Basically, we are modifying values of points and handles between iterations and <animate> element will smoothen the transformation of points according to the duration of the animation defined with dur="..." attribute.

So, the final code should be something like this:


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>SVG wave animation</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- Wave SVG Animation -->
  <div class="waves">
    <svg width="100%" height="200px" fill="none">
      <path 
        fill="#454599" 
        d="
          M0 67
          C 273,183
            822,-40
            1920.00,106 

          V 359 
          H 0 
          V 67
          Z">
        <animate 
          repeatCount="indefinite" 
          fill="#454599" 
          attributeName="d" 
          dur="15s" 
          values="
            M0 77 
            C 473,283
              822,-40
              1920,116 

            V 359 
            H 0 
            V 67 
            Z; 

            M0 77 
            C 473,-40
              1222,283
              1920,136 

            V 359 
            H 0 
            V 67 
            Z; 

            M0 77 
            C 973,260
              1722,-53
              1920,120 

            V 359 
            H 0 
            V 67 
            Z; 

            M0 77 
            C 473,283
              822,-40
              1920,116 

            V 359 
            H 0 
            V 67 
            Z
            ">
        </animate>
      </path>
    </svg>
  </div>

</body>
</html>

Enter fullscreen mode Exit fullscreen mode

Ohh, wait... Since this is my first article ever. I have a bonus for you.

Let me tell you how you can add the gradient to the wave.

To add gradient, we will add <linearGradient> element right before <path> element. Also, we will provide some attributes to <linearGradient> such as id and positions of gradient start and end, something like this <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">.

Inside <linearGradient> element we will define the stop points of colors we want to use in our gradient. for more details over working with gradients in SVG please read this article on Mozilla developer network : Grdients in SVG.

The id of linearGradient can be used in <path> element's fill="" attribute.

check the code below.

<svg width="100%" height="200px" fill="none">

  <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
    <stop offset="0%" stop-color="#00B4DB" />
    <stop offset="50%" stop-color="#224488" />
    <stop offset="100%" stop-color="#0083B0" />
  </linearGradient>

  <path
    fill="url(#grad1)"
    d="
       M0 67 
       C 273,183
         822,-40
         1920.00,106 

         V 359 
         H 0 
         V 67 
         Z">
  </path>

...


Enter fullscreen mode Exit fullscreen mode

Final output: Check out the pen

Top comments (11)

Collapse
 
damlight profile image
Daei_F

Hello, what about performance against CSS or Canvas animations? This is pure gold, I tell you, it's a shame nobody seems to support it, but I may just be missinformed, is this being used extensively in current web design?

Collapse
 
theliquidcharcoal profile image
The Liquid Charcoal

Yes It is, infact there are many people using my code now a days.

Collapse
 
theliquidcharcoal profile image
The Liquid Charcoal • Edited

Hello Daei_F,

Thanks for the complement :)

I am a big fan of CSS and Canvas and have done couple of experiment with them for this kind of designs. However, I would consider doing animation with SVG in every possible way as at the end its pure HTML which is natively working on its own without any other support like css and javascript. Also it will reduce load on browser's rendering engine. People will soon start supporting this as I am seeing this kind of animation on a lot of webpages.

Collapse
 
lola7721 profile image
Lola7721

Excellent post!! and it's sooo cool! I really love this kind of tutorials. Your interpretation of Bezier curve is super clear. I felt confused about this before. Figure with text is a good way. Looking forward to more tutorials from you.

Collapse
 
johndavis profile image
HumbleVibe

I've learned multiple things here.

Firstly pure html animation isn't anything I've explored or even knew about so I'm thrilled to try this out.

Secondly, you explained the curves perfectly.

Thanks for sharing!

Collapse
 
anonymouser profile image
Anonymous!

Very nice! How can the color be added to the animate tag to change the wave color, e.g. either with keyframes to suddenly alternate/flash green, then blue, then red, or to gradually transform the color via HTML hex code (#00ff00 to #00aaff for example)? I had a try using fill with values and keyframes timings with no success.

Collapse
 
vuild profile image
Vuild

Interesting. Good post.

I just added waves to my site, I might use this technique.

Thanks

Collapse
 
theliquidcharcoal profile image
The Liquid Charcoal

Feel free to use it. Let me know if you have any issue. I would be happy resolve.

Collapse
 
vuild profile image
Vuild

Thanks. Appreciated. 👍

I'll give it a test & see how it works out.

Collapse
 
johnbro11827613 profile image
John Brown

I thing that GSAP animations is performs better than CSS. examples of the GSAP logo animations: adsspirit.com/portfolio/animated-s...

Collapse
 
theliquidcharcoal profile image
The Liquid Charcoal

Thanks for the comment.

I do agree with you that Green Sock has a great library to deal with. However, the primary goal here is to avoid use Javascript for such simple animation that can be done with html. Also, code of this tutorial is not even 1% in size of script that GSAP has. So, I would prefer using such HTML based animation if I am going to design just a section with such animation on my personal portfolio or landing page like website.

Hope you got my point. :)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.