Creating the Treehouse Frog Animation

By  on  

The following post has been written by Brazilian developer Jones Dias. His English is much better than my Portuguese but since it isn't his native language, I've sprinkled in some extra detail to the post. Enjoy!

Free Treehouse Account

Before we start, I want to say thank you to David for giving me this awesome opportunity to share this experience with you guys and say that I'm really flattered. I think that CSS animations are really great. When I first learned how CSS animations worked, a big world of possibilities opened up in front of my eyes. If you learn how to create CSS animations, you'll be able to create animated buttons, forms, pages, menus, sliders, cartoon characters, etc.

I chose to animate Mike the Frog, the Treehouse mascot.

The HTML

A new element is created for each relevant part of the mascot's face:

<div class="mike">
  <div class="head">
    <div class="eyes">
      <div class="eye">
        <div class="pupil"></div>
      </div>
      <div class="eye">
        <div class="pupil"></div>
      </div>
    </div>
    <div class="nose">
      <div class="ball"></div>
      <div class="ball"></div>
    </div>
    <div class="mouth"></div>
  </div>
</div>

This example uses DIV elements but any block element type may be used.

The CSS

Once the HTML is done, I start setting the dimensions, background colors, borders and positioning properties:

div {
  border-radius: 50%;
  box-sizing: border-box;
}

.mike {
  width: 400px;
  margin: 0 auto;
  padding-top: 2%;
  transition: all 1s;
}

.mike:hover {
  transform: scale(1.5) rotate(360deg);
}

.head {
  width: 195px;
  height: 120px;
  background: #92ae57;
  position: relative;
  z-index: 1;
  margin-left: 103px;
}

.eyes {
  width:200px;
  position: absolute;
  bottom: 45px;
}

.eye {
  width: 95px;
  height: 93px;
  background-color: #ffe13b;
  border: 10px solid #92ae57;
  display: inline-block;
  z-index: 2;
  animation: eyes 5s infinite step-start 0s;
}

.eye:last-child {
  float:right;
}

.pupil {
  width: 1px;
  height: 1px;
  border: 10px solid #353535;
  display: inline-block;
  position: absolute;
  top: 38px;
  margin-left:27px;  
  z-index: 3;
  animation: pupil 5s infinite step-start 0s;
}

.pupil:last-child{
  float:right;
}

.ball {
  width: 1px;
  height: 1px;
  border: 5px solid #6f8346;
  position: absolute;
  top: 70px;
  left: 88px;
}

.ball:last-child {
  float:left;
  margin-left: 14px;
}

.mouth {
  height: 100px;
  width: 180px;
  border-bottom: 4px solid #6f8346;
  position: relative;
  top: 8px;
  left: 7px;
}

/* Animations */

@keyframes eyes {
   0%, 100% {
    background: #92ae57;
    border-radius: 50%;
    border: 10px solid #92ae57;
  } 

   5%, 95% {  
    background:#ffe13b;
    border-radius: 50%;
    border: 10px solid #92ae57;
  }
}

@keyframes pupil {
  0%, 100% {
    opacity: 0;
  }
  5%, 95% {
    opacity: 1;
 }
}

When I got Mike ready to be animated, I started by blinking his eyes. I created 2 keyframe rules to do it:

@keyframes eyes {
  0%, 100% {
    background: #92ae57;
    border-radius: 50%;
    border: 10px solid #92ae57;
  } 

  5%, 95% {
    background: #ffe13b;
    border-radius: 50%;
    border: 10px solid #92ae57;
   }
}

In this part, I set the eye to be opened during the periods between 5% and 95%. And to be closed in the 0% and 100%.

@keyframes pupil {
  0%, 100% {
    opacity: 0;
  }
  5%, 95% {
    opacity: 1;
 }
}

I set the pupil to be hidden in two points, 0% and 100%, and to stay showing during the period between 5% and 95%. But setting this up won't make the animation work, so I put the animation property to the eye and pupil with a duration of 5s infinitely using the step-start timing function. I set a hover with transform to the .mike element, making it scaled at 1.5 as big as it was and rotate it 360 degrees.

.mike:hover{
  transform: scale(1.5) rotate(360deg);
}

Finally, I selected all possible animating properties in the mike class, giving it a duration of 1 second.

.mike{
  transition: all 1s;
}

That's all folks! Creating this animation was easier than many may think -- no canvas or even JavaScript required, just pure CSS!

Jones Dias

About Jones Dias

Jones Dias is an up and coming web designer and front-end developer plying his trade in Brazil.

Recent Features

  • By
    fetch API

    One of the worst kept secrets about AJAX on the web is that the underlying API for it, XMLHttpRequest, wasn't really made for what we've been using it for.  We've done well to create elegant APIs around XHR but we know we can do better.  Our effort to...

  • By
    Detect DOM Node Insertions with JavaScript and CSS Animations

    I work with an awesome cast of developers at Mozilla, and one of them in Daniel Buchner. Daniel's shared with me an awesome strategy for detecting when nodes have been injected into a parent node without using the deprecated DOM Events API.

Incredible Demos

  • By
    Detect Vendor Prefix with JavaScript

    Regardless of our position on vendor prefixes, we have to live with them and occasionally use them to make things work.  These prefixes can be used in two formats:  the CSS format (-moz-, as in -moz-element) and the JS format (navigator.mozApps).  The awesome X-Tag project has...

  • By
    MooTools Wall Plugin

    One of the more impressive MooTools plugins to hit the Forge recently was The Wall by Marco Dell'Anna.  The Wall creates an endless grid of elements which can be grabbed and dragged, fading in elements as they are encountered.  Let me show...

Discussion

  1. WOW. Simple. Demo looks cool…Great job dude…

  2. Jones Dias

    Thanks, Akhil! I’m glad you like it ;)

  3. Awesome, haha. I got an idea to write a similar tutorial. Thanks Jones!

    • Jones Dias

      Great man! When you write the tutorial, send it to me, please.

      Thanks for reading, Toan.

  4. Tarun Elankath

    Isn’t this much, much simpler with SVG ?

  5. wow just amazing

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!