Chapter 2. Animating with CSS

You may find working with SVG code feels very familiar, mostly because an SVG has a DOM, just like standard HTML markup. This is hugely valuable when working with CSS animations, as manipulating markup with CSS is already a very comfortable process for most frontend developers.

For a very brief review, let’s first establish that a CSS animation is created by defining two parameters. First, there are the keyframes themselves:

@keyframes animation-name-you-pick {
  0% {
   background: blue;
   transform: translateX(0);
 }
  50% {
   background: purple;
   transform: translateX(50px);
 }
  100% {
   background: red;
   transform: translateX(100px);
 }
}

Keyframe Syntax Hint

You can also define from and to instead of percentages. If you declare nothing in either the initial keyframe or the ending keyframe, the animation will use the default or declared properties on the element. It may be worth double-checking your work in all browsers if you do remove them, though, due to strange and inconsistent browser bugs.

After you define the keyframe values, you have two options for animation syntax declaration. Here’s an example of the long form, with each declaration defined separately:

.ball {
  animation-name: animation-name-you-pick;
  animation-duration: 2s;
  animation-delay: 2s;
  animation-iteration-count: 3;
  animation-direction: alternate;
  animation-timing-function: ease-in-out;
  animation-fill-mode: forwards;
}

And here’s the shorthand (my preferred method, as it uses less code):

.ball {
  animation: animation-name-you-pick 2s 2s 3 alternate ease-in-out forwards;
}

The order of the declarations is interchangeable in a space-separated list, except for the number values, which must be defined in this order: duration, delay, and iteration count.

Let’s apply this animation to this very simple .ball div (shown in Figure 2-1):

.ball {
  border-radius: 50%;
  width: 50px;
  height: 50px;
  margin: 20px; // so that it's not hitting the edge of the page
  background: black;
}
Figure 2-1. The result of applying .ball div

We get the result in Figure 2-2, with interstitial states shown less opaque.

Figure 2-2. The result of adjusting the ball div

You can see all the code in action in a demo I created.

For more information and further detail about each animation property, such as what animation-fill-mode is, what eases are available in CSS, and which properties are animatable, see Transitions and Animations in CSS by Estelle Weyl (O’Reilly).

You can also consult Pro CSS3 Animation, by Dudley Storey (Apress).

Animating with SVG

Let’s say instead of drawing the ball with CSS, we had drawn it with SVG. We know how to do that from the last chapter. To get the same black circle as in Figure 2-1, we would write:

<svg width="70px" height="70px" viewBox="0 0 70 70">
  <circle fill="black" cx="45" cy="45" r="25"/>
</svg>

We define the radius as half of 50, so 25 px. Then we move the center of the circle on both the x- and y-axes (cx and cy) to half the radius, plus that 20 px margin we added in the CSS. We could also use margin on the SVG element to move it, but here I’m illustrating that you can draw coordinates directly in the SVG itself. If we move the circle over, though, the viewBox has to be larger to accommodate these coordinates: it’s the width plus the margin of space to the edge.

Now, if we place a class on the whole SVG called ball, using the same animation declaration, we get what’s shown in Figure 2-3.

Figure 2-3. The result of placing the ball class on the SVG

What happened here? It still moved across, as we were expecting. But the background is filling in the full background of the SVG, thus the entire viewBox. That’s not really what we want. So what happens if we move that class and target the circle instead? See Figure 2-4.

Figure 2-4. The result of moving the ball class

You may have guessed why we have this output. There are two reasons:

  1. The circle is moving inside the viewBox. Remember, if we move an internal SVG attribute, the viewBox will quite literally be a window through which we view these elements. So if we move the circle without making the viewBox large enough to accommodate those coordinates, it will be cut off when the circle moves out of the viewBox.

  2. The SVG DOM looks like the HTML DOM, but it’s slightly different. We don’t use background on SVG attributes; we use fill and stroke. An external stylesheet will also have a hard time overriding what is defined inline within the SVG. So let’s take out the fill definition, and move that into our stylesheet.

The resulting code should be this:

<svg width="200px" height="70px" viewBox="0 0 200 70">
 <circle class="ball3" cx="45" cy="45" r="25"/>
</svg>

And here’s the CSS:

.ball3 {
 animation: second-animation 2s 2s 3 alternate ease-in-out forwards;
}

@keyframes second-animation {
  0% {
   fill: blue;
   transform: translateX(0);
 }
  50% {
   fill: purple;
   transform: translateX(50px);
 }
  100% {
   fill: red;
   transform: translateX(100px);
 }
}

The result is Figure 2-5, but with an SVG instead of an HTML div.

Figure 2-5. The result of taking out the fill definition and moving it to the stylesheet

Benefits of Drawing with SVG

So, why learn SVG when you could build something in CSS-styled HTML and animate that way?

First of all, even that small, simple circle was four lines less than the CSS version. SVG was built for drawing—unlike CSS, which was built for presentational formatting. Let’s look at the code for the star from the first chapter of this book:

<polygon fill="white" stroke="black" points="279,5 294,35 328,40 
   303,62 309,94 279,79 248,94 254,62 230,39 263,35 "/>

It would be incredibly difficult to draw a star in CSS with such a small amount of code, and impossible for the code to be that concise once compiled, if using a preprocessor.

Figure 2-6 is something I drew in Illustrator.

Figure 2-6. An example of the ease of Illustrator

We could also probably draw this in CSS, but to what end? If you’re working with a designer on a project, having them draw something for you in CSS is not typically an option, and drawings that you want to animate can get much more complex than this. In SVG you can also make the whole image scale easily, and therefore, your whole animation can be responsive.

All of the information for the illustration is just 2 KB gzipped, and it can fill up a whole screen. That’s pretty amazing if you consider raster image alternatives.

Applying what we just learned about the circle, we can look at some of these shapes and think about what we can do with them. We could group all of the parts of the cow together and make it jump over the moon. We could make the astronaut’s “surprised” expression disappear and appear. We can even make the helmet go up and down so it looks like the astronaut is looking up. (That is actually what I did in the final animation.)

Silky-Smooth Animation

It’s tempting to use all of the same properties that you use to affect layout with CSS: margin, top, left, etc. But browsers do not update values for all properties equally. To animate cheaply, your best bet is to use transforms and opacity. That might seem limiting, but transforms offer translation (positioning), scale, and rotation. Using these in combination with opacity can be extremely powerful. It’s surprising how much can be achieved with these properties in standard animations.

Throughout this book, I will use these properties wherever possible while demonstrating various techniques. It is important to note that SVG DOM elements are currently hardware-accelerated only in some browsers (for instance, hardware acceleration is supported in Firefox but not Chrome), but you should still be moving the SVG DOM with transforms, not margins or other CSS positioning.

At the time of publishing, Microsoft Internet Explorer (IE) and Edge did not support transforms on SVG elements at all—but you can vote on these issues and more on the Windows Developer Feedback site.

Until this is supported, your best bet for Edge is using either native SVG transforms (which are a pain and you’ll need JavaScript for) or the GreenSock Animation API, which has support back to IE9.

For more information on how to properly keep your layout repaint costs low (these are Chrome-specific resources), check out Jank Free and High Performance Animations.

For information on the costs of individual properties, see CSS Triggers.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.65.247