CSS Animations with Franklin

by Joni Trythall

Drawings are a great way to exercise all your CSS muscles. So much positioning, so much style manipulation, so much experimenting. After creating a CSS fish one day the desire to make him move was inevitable. I mean, look at that face! Learning became a much more organic process going forward in that I quickly realized what I needed to know to bring this guy to life. You start out casually tinkering and end up planning an entire syllabus in order to make your demo all you ever dreamed of.

Meet Franklin. Franklin threw me into the world of CSS animations, and I would like to walk with you through the details.

CSS Drawing

Franklin was built using only HTML and CSS. The HTML is comprised of <div> elements and their styling comes together with rounded corners, color, and positioning. You can sneak a peek at Franklin’s demo as a guide. Concerning animations and browser support Can I Use should clear some things up for you before we get started. For this example I will not be using vendor prefixes.

Keyframes

Once our Franklin drawing is complete we need to name and set up our @keyframes rule below the styling in our CSS. The magic of CSS animations exist inside the @keyframes rule. Name your keyframes something that describes the action you will create. We will use @keyframes swim:

@keyframes swim {
 
    /* We will set up our animation commands here */
 
}

Keyframe Moments

Within our keyframe we will use percentages as reference points. Each percentage listed within the keyframe represents a point in time for the animation. What do we want Franklin to do at the beginning of the animation?Where should he be at this point? How about halfway through? And so on. You can also use keywords “to” and “from” in place of “0%” and “100%”, as shown here at CSS-Tricks, but I will be using percentages. So, let’s get our keyframe started at 0%.

@keyframes swim {
 
  0% {
 
    transform: translateY(-50px) translateX(0);
 
  }
 
  25% {
 
    transform: translateY(50px) translateX(250px);
 
  }
 
}

Point of Origin

To understand what is going on behind the scenes in an animation, we must understand from what point we are moving an element. The default point of origin for a transform is its center, which serves as a reference point for our translate() values. We will be moving Franklin’s container, so we need to make sure its dimensions are the same as his body. This allows our animation to use the same point of origin.

.fish {
 
  height: 100px;
 
  width: 150px;
 
}

Translate

Our translateY() values set the distance of our animation from the top of the screen, while translateX() values set its distance from the left. In the above keyframe we have told this animation to start the element near the top left corner, and then 25% through the animation we want it to be 50px from the top and 250px left of the screen. At 25% our animation will be exactly as we have told it to be, and the time between the percentages we list are transition points for the action taking place. Now, we are ready to set up our remaining animation details for the following moments: 50%, 75%, 100%.

@keyframes swim {
 
  50% {
 
    transform: translateY(100px) translateX(500px);
 
  }
 
  75% {
 
    transform: translateY(50px) translateX(850px);
 
  }
 
  100% {
 
    transform: translateY(-170px) translateX(1200px);
 
  }
 
}

We are telling our animation to move right by gradually increasing its distance from the left through a total of five moments in time. By increasing and decreasing the distance from the top within these same moments we are telling the animation to move the element down and up again as it is progressing across the screen.

Rotation

We will now add rotate values within our transform properties so we can have Franklin’s body start out turned slightly downwards and then turn up by decreasing his rotation angle throughout our percentages. We are so bossy and good at math. Let’s take a look at the completed keyframe.

@keyframes swim {
 
  0% {
 
    transform: translateY(-50px) translateX(0) rotate(30deg);
 
  }
 
  25% {
 
    transform: translateY(50px) translateX(250px) rotate(20deg);
 
  }
 
  50% {
 
    transform: translateY(100px) translateX(500px);
 
  }
 
  75% {
 
    transform: translateY(50px) translateX(850px) rotate(-20deg);
 
  }
 
  100% {
 
    transform: translateY(-170px) translateX(1200px) rotate(-40deg);
 
  }
 
}

At the 50% point, for example, our animation will be 100px from the top, 500px from the left, and halfway through transitioning from a 20 degree angle to a -20 degree angle. Our animation (aka Franklin) finishes at a -40 degree angle by gradually turning upwards with the advancing decline of his angle.

Assigning Animation

To assign our completed @keyframes swim to Franklin we will add the following animation property to his container element:

.fish {
 
  height: 100px;
 
  width: 150px;
 
  animation: swim 3s infinite;
 
}

Within these values we have spelled out the animation name, duration, and iteration-count. So, we are telling .fish to take on the commands of @keyframes swim, to complete the entire animation within 3 seconds, and to do it for all of time. He’s alive and kicking! Well, swimming.

Experimenting

At this point, you and your CSS fish are unstoppable. Until infinity ends at least. Here is a great resource from the Mozilla Developer Network on other animation properties and values you can experiment with to really knock your slippers off. Just remember to also make time for sleep and food.

Happy keyframing!

Para obtener información más completa sobre las optimizaciones del compilador, consulte nuestro Aviso de optimización.