Infinite CSS Animations

November 2013

You may have seen my other article about Ampersand Conference, which really just goes to show that I learned a lot. In any case, Trent Walton’s talk on various CSS tricks was very informative and I wanted to try out some of the things he went over right away, hence, the lab.

Icon Fonts

You’ve probably already heard all about how icon fonts are amazing, but what I hadn't understood was how to make one or how they worked. Turns how it’s fairly simple. Here’s how Font Awesome, an open-source icon font from Twitter, structures their font.

First, they link up their files with the expected @font-face stuff:


      @font-face {
        font-family: 'FontAwesome';
        src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}');
        src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'),
          url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'),
          url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'),
          url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg');
        font-weight: normal;
        font-style: normal;
      }
    

The .fa class is where they make the font declaration:


      .fa {
          font-family: ’font-awesome’;
      }
    

Finally, a few of the icons themselves:


      .fa-camera:before {
        content: "\f030";
      }

      .fa-headphones:before {
        content: "\f025";
      }

      .fa-search:before {
        content: "\f002";
      }
    

The logic here is that you can hide the weird, unicode strings that don't really map to anything in more semantic classes (e.g., .fa-headphones). Neat! Using this, we have a basis for our glowing lightning bolt.

When I set out to make this, I knew I wanted it to glow forever, to use the icon font jazz I'd just learned about, and for it to me scalable. (If it's not scalable, what's the point).

I decided to make the lightning bolt glow using Trent Walton's fake stroke effect, which essentially is just a text-shadow on all sides of the bolt:


      text-shadow: 5px 5px 10px darken($secondary-color,10%),
                     -5px -5px 10px darken($secondary-color,10%),
                      5px -4px 10px darken($secondary-color,10%),
                     -5px 5px 10px darken($secondary-color,10%);
    

To make the bolt scalable, I used percentages, although there's a hearty debate on what the best practice for setting type size is (check the comments in this blog post for a taste). Seems like the verdict in 2013 is that pixels are global while ems and percentages are local. I went with percentages since the bolt is relative to the viewport anyway:


      // Sizing
      $base-font: 3500%;
    

To then make our lightning bolt glow and pulse, we define the animation and then apply it:


      @-webkit-keyframes pulse {
      // Fake stroke with text shadows code
      0% { text-shadow: 5px 5px 10px darken($secondary-color,10%),
                     -5px -5px 10px darken($secondary-color,10%),
                      5px -4px 10px darken($secondary-color,10%),
                     -5px 5px 10px darken($secondary-color,10%); }
      50% { text-shadow: none; }
      100% { text-shadow: 5px 5px 10px darken($secondary-color,10%),
                       -5px -5px 10px darken($secondary-color,10%),
                        5px -4px 10px darken($secondary-color,10%),
                       -5px 5px 10px darken($secondary-color,10%); }
      }
    

Here's where I set the icon (:after) and then called the animation:


      i {
      // Positioning
      position: absolute;
      top: 50%;
      left: 50%;
      margin-left: -0.25em;
      margin-top: -0.51em;
          &:after {
              content: '\f0e7';

              // Position it
              position: absolute;
              left: 0;
              right: 0;
              top: 0;
          }

      // Transitions
      transition: text-shadow 0.7s ease;
      -webkit-transition: text-shadow 0.7s ease;

      // Handles the pulse
      -webkit-animation-name: pulse;
      -webkit-animation-duration: 1.2s;
      -webkit-transform-origin: 50% 50%;
      -webkit-animation-iteration-count: infinite;
      -webkit-animation-timing-function: linear;
      }
    

Obviously I don't have all of the browser prefixes in there, which you'd need if you were being serious about implementing something like this. That's why it's called The Lab.

If you thought this was helpful, tell me on Twitter.