5 Use Cases for Icon Fonts

Guest Author //

The following is a guest post by Tim Pietrusky. Tim knows this site has long been a proponent of using fonts for icons, and had his own interesting use cases to share. While creating the demos, to make things easier for himself, he created a free service for icon font hosting. It makes for a nice gift to the community as well. I'll let him tell you about it...

Icon fonts are great:

  • You can CSS the crap out of them and they don’t mind
  • They look good on any display or resolution
  • There is only one HTTP request for any size set of icons

Let's look at 5 typical uses cases for icon fonts.

Before we start

We won't be using any vendor prefixes to keep the example code clean and readable. We will be using things like animations, transitions, and transforms, all of which require vendor prefixes to ensure the best browser support. How you want to deal with vendor prefixes is up to you.

As you will see in the examples, I use the icon fonts hosting service weloveiconfonts.com. This is my own project. Here’s the story: I wanted to write an article about icon fonts and searched for a free icon fonts hosting service, but found none. So I created this service to be able to write this article.

1. CSS Loader

There are quite a few awesome, pure CSS loaders out there and you can even create your own at cssload.net. Another way of doing this is with icon fonts. You can use a character that looks like a loading symbol and animate it with CSS.

This is the basic HTML. The first three loaders are children of div.wrapper and and single elements. The forth (div.complex) is a combination of two icons.

<div class="wrapper">
  <span class="fontelico-spin1"></span>
  <span class="fontelico-spin3"></span>
  <span class="fontelico-spin5"></span>
</div>

<div class="complex">
  <span class="fontelico-emo-devil"></span>
  <span class="fontelico-spin4"></span>
</div>

Import the icon font Fontelico into your CSS:

@import url(http://weloveiconfonts.com/api/?family=fontelico);
[class*="fontelico-"]:before {
  font-family: 'fontelico', sans-serif;
}

Add the animation named load to the elements, whichs spins them around (from 0deg to 360deg), scales up and down a little bit, and changes the color.

/* Normal (left) */
span {
  float: left;
  text-align: center;
  margin: 0 5em;
  animation: load 1.337s infinite ease-out reverse;
}
/* Fast (center) */
.wrapper span:nth-child(2) {
  animation: load .5s infinite linear;
}
/* Steps (right) */
.wrapper span:nth-child(3) {
  animation: load 1.25s infinite steps(18, end) forwards;
}
@keyframes load {
  0% {
    transform: rotate(0) scale(1, 1);
    color: rgba(0, 0, 0, .5);
  }
  10% { color: rgba(0, 120, 0, .5); }
  20% { color: rgba(0, 120, 120, .5); }
  30% { color: rgba(120, 120, 0, .5); }
  40% { color: rgba(0, 0, 120, .5); }
  50% {
    transform: rotate(180deg) scale(1.85, 1.85);
    color: rgba(120, 0, 0, .5);
  }
  100% {
    transform: rotate(360deg) scale(1, 1);
    color: rgba(0, 0, 0, .5);
  }
}

The last loader (div.complex) combines two icons and stacks them on top of each other. The first child is the devil element (using the animation named rotate) and the second child is the spin icon (using the animation named scale).

.complex span:nth-child(1),
.complex span:nth-child(2) {
  position: absolute;
  margin: 0;  
  width: 1em;
  height: 1em;
}
/* Devil icon  */
.complex span:nth-child(1) {
  animation: load 1.25s infinite steps(18, end) forwards;
}
/* Spin icon */
.complex span:nth-child(2) {
  font-size: 3em;
  left: -.35em;
  top: -.35em;
  color: rgba(0, 0, 0, .3);
  animation: devil 3s infinite linear reverse forwards;
}
@keyframes devil {
  0% {
    transform: scale(-1.85, 1.85);
  }
  50% {
    transform: scale(1.85, -1.85);
  }
  100% {
    transform: scale(-1.85, 1.85);
  }
}

Demo on CodePen:

2. SocialCount meets Style

People love using social sharing buttons on their sites to make it easier for visitors to spread the word. But when you combine Facebook, Twitter and Google+ you are facing an 309KB empty cache load size. That’s where the SocialCount jQuery plugin comes in. SocialCount is progressively enhanced, lazy loaded, and mobile friendly.

The default styling is simple and the iframe that contains the buttons is tiny. Let's enhance these buttons with some fancy CSS.

This is the HTML that was created with the SocialCount markup generator. Just an unordered list with with links and icons.

<ul
  class="socialcount"
  data-url="http://www.google.com/"
  data-counts="true"
  data-share-text="Google is a search engine">
 
  <li class="facebook">
    <a href="https://www.facebook.com/sharer/sharer.php?u=http://www.google.com/" title="Share on Facebook">
      <span class="count entypo-thumbs-up"></span>
    </a>
  </li>

  <li class="twitter">
    <a href="https://twitter.com/intent/tweet?text=http://www.google.com/" title="Share on Twitter">
      <span class="count entypo-twitter"></span>
    </a>
  </li>

  <li class="googleplus">
    <a href="https://plus.google.com/share?url=http://www.google.com/" title="Share on Google Plus">
        <span class="count entypo-gplus"></span>
    </a>
  </li>

</ul>

Import the icon font Entypo into your CSS:

@import url(http://weloveiconfonts.com/api/?family=entypo);
[class*="entypo-"]:before {
  font: 2.5em/1.9em 'entypo', sans-serif;
}

We'll override the default styling provided by SocialCount by:

  • Adding a transition
  • Scaling the iframe
  • Setting a custom background on the buttons
Editor's note: The CSS below is in SCSS format of Sass. A number of the following demos use this. If you want to see the regular CSS, you can visit the CodePen demo links provided and click the word "SCSS" in the header of the CSS editor to see the compiled CSS.
.socialcount {
  > li {
    width: 33%;
    border-radius: 0;
    transition: all .3s ease-in-out;
    cursor: pointer;
   
    &:hover [class*="entypo-"]:before {
      opacity: 0;  
    }
  }
 
  iframe {
    transform: scale(1.65, 1.65);    
  }
 
  .button {
    top: 50%;
    margin: -.75em 0 0 0;
    height: 2em;
  }
 
  .facebook {
    background: rgba(59, 89, 152, .7);
  }
   
  &.like .facebook iframe {
    width: 8em;
  }
 
  .twitter {
    background: rgba(0, 172, 237, .7);  
  }
 
  .googleplus {
    background: rgba(172, 0, 0, .7);  
  }
}

Demo on CodePen:

3. Enhanced lists

The following three examples are all based on this simle HTML.

<div>
  <h2>Title</h2>
  <ul class="style">
    <li data-text="">Text</li>
    <li data-text="">Text</li>
    <li data-text="">Text</li>
  </ul>
</div>

Import the icon font Font Awesome into your CSS:

@import url(http://weloveiconfonts.com/api/?family=fontawesome);
[class*="fontawesome-"]:before {
  font-family: 'FontAwesome', sans-serif;
}

Add the default styling for list, list elements, pseudo elements, and the button. Instead of using a class to set the icon on the list elements, we change the content property of the element, creating a pseudo element.

ul {
  list-style: none;
  padding: 0;
   
  li {
    position: relative;
    min-height: 2em;
    padding: .3em .3em .3em 1.5em;
    transition:
      background .3s ease-in-out,
      color .3s ease-in-out,
      box-shadow .1s ease-in-out,
      height .25s ease-in-out
   ;
   
    button {
      position: absolute;
      left: 1.45em;
      bottom: .35em;
      opacity: 0;
      height: 0;
      border: none;
      font-size: .8em;
      cursor: pointer;
      transition: all .4s ease-in-out;
    }
   
    &:before {
      position: absolute;
      top: .425em;
      font-family: 'FontAwesome', sans-serif;
      margin: 0 .35em 0 -1.35em;
      vertical-align: bottom;
    }
    &:hover {
      button {
        opacity: 1;
        height: 2em;
      }
     
      &:before {
        color: rgba(255, 255, 255, 1);
        right: 0;
        transform: scale(2.5, 2.5) translate(-.25em, .15em);
      }
      &:after {
        position: absolute;
        content: attr(data-text);
      }
    }
  }
}

3.1 Stuff You Love

The first examle is very easy. A heart instead of the default list-style and a special hover: The icon is moved to the right and the ::after pseudo-element gets the text of the data-attribute data-text.

.love {
  li {  
    &:before {
      /* fontawesome-heart */
      content: "\f004";
    }
    &:before,
    &:after {
      color: rgba(220, 20, 20, .6);
    }
    &:hover {
      background: rgba(220, 20, 20, .6);
   
      &:after {
        width: 2em;
        right: .445em;
      }
    }
  }
}

3.2 Downloads

This is a custom list of downloads with extended markup: A link and a button for every list element. The button is hidden by default and shown on hover.

.downloads {
  li {
    border-bottom: .15em solid rgba(0, 0, 0, .3);
   
    &:before {
      /* fontawesome-download-alt */
      content: "\f019";
      color: rgba(50, 50, 50, .5);
    }
    &:hover {
      background: rgba(0, 140, 0, .7);
      height: 4em;
   
      &:after {
        right: .35em;
      }
     
      &:before {
        color: rgba(255, 255, 255, .2);
      }
    }
  }
}

3.3 Your account

A UI concept for a user menu. When you hover over a list element, the icon is moved to the right and the box-shadow fills the whole background. Every list element has its own icon based on the :nth-child selector and the content property.

.account {
  padding: .75em;
  border: .15em solid rgba(0, 0, 0, .2);
  background-color: rgba(0, 0, 0, .7);
  background-image: radial-gradient(center, ellipse cover, rgba(104,104,104,0.6) 0%,rgba(23,23,23,0.7) 100%);
  box-shadow: inset 0 0 .35em 0 rgba(0, 0, 0, .2);
  color: rgba(255, 255, 255, .6);
  backface-visibility: hidden;
   
  li {  
    cursor: pointer;
       
    &:nth-child(1):before {
      /* fontawesome-heart-empty */
      content: "\f08a";
    }
    &:nth-child(2):before {
      /* fontawesome-glass */
      content: "\f000";
    }
    &:nth-child(3) {
      margin-bottom: 1em;
     
      &:before {
      /* fontawesome-comment */
        content: "\f075";
      }
    }
    &:nth-child(4) {
      margin-bottom: .5em;
     
      &:before {
      /* fontawesome-cog */
         content: "\f013";
      }
    }
    &:nth-child(5):before {
      /* fontawesome-signout */
      content: "\f08b";
    }
    &:hover {
      color: rgba(255, 255, 255, 1);
      padding-left: 1.5em;
      box-shadow: inset 0 0 0 10em rgba(255, 255, 255, .5);
   
      &:before {
        color: rgba(255, 255, 255, 1);
        transform: none;
      }  
    }
  }
}

Demo of all three list types on CodePen:

4. Emocons.js jQuery Plugin

Emojons.js is a jQuery plugin which searches the content of an element for specific character sequences. All matches are replaced with a span and the HTML class of the corresponding icon. For example, a chat app:

<div class="chat">
    :D :) ;) :'( :o :/ :( B) :P :|
    :beer: :devil: :shoot: :coffee: :thumbsup: :angry: :ueber-happy:
</div>

Then call the Emocons.js plugin method on your element:

$('.chat').emocons();

All elements inside chat are now transformed into something like this

<span class="fontelico-emo-grin go" title=":D"></span>

Import the icon font Fontelico into your CSS:

@import url(http://weloveiconfonts.com/api/?family=fontelico);
[class*="fontelico-"]:before {
  font-family: 'fontelico', sans-serif;
}

When Emocons.js transforms a string into an emoticon, it adds the class go (which calls an animation) to the span element.

.go {
  animation: hey .55s 1 linear;
}
@keyframes hey {
  0% {
    transform: scale(1, 1);
  }
  50% {
    transform: scale(1.85, -1.85);
  }
  100% {
    transform: scale(1, 1);
  }
}

Some of the emoticons get a special style (e.g. a color change) or add something via an ::after pseudo element.

.fontelico-emo-devil {
  color:rgba(180, 0, 0, .9);
}
.fontelico-emo-beer:after {
  box-shadow:
    -.475em .75em 0 .275em rgba(220, 220, 0, 1),
    -.185em .675em 0 .175em rgba(220, 220, 0, 1)
  ;    
}
.fontelico-emo-coffee:after {
  box-shadow:
    -.475em .78em 0 .235em rgba(222, 184, 135, 1),
    -.215em .715em 0 .155em rgba(222, 184, 135, 1)
  ;    
}
.fontelico-emo-shoot:after {
  border-radius: .15em;
  box-shadow: .315em .525em 0 .1em rgba(0, 0, 0, 1);    
}
.fontelico-emo-angry:after {
  border-radius: .15em;
  box-shadow: -.695em .455em 0 .085em rgba(0, 220, 0, .6);
  z-index: 2;
}

Demo on CodePen:

5. Parallax Movie #1337

The last example is just for fun. It’s just an experiment to create an endless parallax movie with one icon font. The he HTML consists of many elements to create the scene:

  • The setting: sky, ground, night and sun
  • Fixed element: bicycle
  • Animated elements: Trees, giraffe, shopping cart, buildings and heliport
<div class="night"></div>
<div class="wrapper">
  <div class="sun">
    <div class="maki-fast-food"></div>
  </div>
 
  <div class="sky"></div>
  <span class="maki-bicycle"></span>
   
  <span class="maki-tree-1" data-child="1"></span>
  <span class="maki-tree-1" data-child="2"></span>
  <span class="maki-tree-1" data-child="3"></span>
   
  <span class="maki-giraffe"></span>
  <span class="maki-grocery-store"></span>
   
  <span class="maki-commerical-building" data-child="1"></span>
  <span class="maki-commerical-building" data-child="2"></span>
   
  <span class="maki-heliport"></span>
   
  <div class="ground"></div>
</div>

Import the icon font Maki into your CSS:

@import url(http://weloveiconfonts.com/api/?family=maki);
[class*="maki-"] {
  position: absolute;
  margin: 0;  
  color: #fff;
  font-size: 2em;
}
[class*="maki-"]:before{
  font-family: 'maki', sans-serif;
}
*:after {
  position: absolute;
  top: 0;
  right: 0;
  content: '';
  z-index: -1;
  width: 0;
  height: 0;
}

The wrapper rotates the whole scene -3deg.

.wrapper {
  height: 140%;
  width: 120%;
  transform: rotate(-3deg) translate(-10%, -15%);    
}

When the sun goes down, the night rises.

.night {
  position: absolute;
  z-index: 5;
  width: 100%;
  height: 100%;
  animation: night 45s infinite forwards;
}
@keyframes night {
  0%, 30%, 100% {background:rgba(0, 0, 0, 0);}  
  55% {background: rgba(0, 0, 0, .6);}
}

The sky and the ground both use the same background-position animation, but at different speeds.

.sky {
  position: relative;
  z-index: 0;
  background: url(http://subtlepatterns.subtlepatterns.netdna-cdn.com/patterns/bedge_grunge.png);
  height: 50%;    
  width: 100%;
  animation: rollin-bg 25s linear infinite forwards;
}
.ground {
  position: absolute;
  z-index: 1;
  background: url(http://subtlepatterns.subtlepatterns.netdna-cdn.com/patterns/blackorchid.png);
  height: 50%;    
  width: 100%;
  animation: rollin-bg 7s linear infinite forwards;
}
@keyframes rollin-bg {
  0% { background-position: 100%; }  
  100% { background-position: 0; }
}

Moving an element along a circle is an awesome article from Lea Verou which is used here to animate the burger-sun.

.sun {
  position: absolute;
  z-index: 1;
  left: 50%;
  top: 10%;
  width: 2em;
  height: 2em;
  font-size: 4em;
  line-height: 1;
  animation: circle 45s linear infinite;
  transform-origin: 50% 3.85em;
}
.sun [class*="maki-"] {
  color: rgba(240, 180, 0, .2);
  text-shadow: 0 0 .35em rgba(240, 240, 0, .7);
}
.sun > div {
  animation: inner-circle 45s linear infinite;
}
@keyframes circle {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
@keyframes inner-circle {
  from { transform: rotate(0deg); }
  to { transform: rotate(-360deg); }
}

This is the only element which has no animation. But it should look like it’s moving.

.maki-bicycle {
  left: 50%;
  z-index: 4;
  margin: -.85em 0 0 -.5em;
  color: rgba(30, 30, 140, .95);
}

And here are the animated elements which use all the same rolling animation at different speed.

.maki-tree-1[data-child="1"] {
  margin: -1em 0 0 5%;
  z-index: 5;
  animation: rollin 5s linear infinite;
  font-size: 2.4em;
  color: rgba(0, 110, 0, .8);
}
.maki-tree-1[data-child="2"] {
  margin: -1em 0 0 85%;  
  z-index: 2;
  animation: rollin 12s linear infinite;
  font-size: 1.6em;
  color: rgba(0, 110, 0, .5);
}
.maki-tree-1[data-child="3"] {
  margin: -1em 0 0 25%;  
  z-index: 2;
  animation: rollin 17s linear infinite;
  font-size: 1.2em;
  color: rgba(0, 110, 0, .3);
}
.maki-giraffe {
  margin: .25em 0 0 5%;  
  z-index: 6;
  animation: rollin 12s linear infinite reverse;
  font-size: 10em;
  color: rgba(255, 255, 10, .9);
}
.maki-giraffe:after {
  right: -3em;
  content: '\e82a \e82a \e82a \e82a \e82a';
  font: .2em 'Maki', sans-serif;
  letter-spacing: .2em;
  width: 3em;
  color: rgba(0, 0, 0, .6);
  box-shadow:
    0 .45em 0 .75em rgba(255, 255, 255, .4),
    1em .35em 0 .75em rgba(255, 255, 255, .4),
    2.25em .25em 0 1.05em rgba(255, 255, 255, .4)  
  ;
  border-radius: 50%;
  transform: translate(2.3em, .55em) rotateY(-180deg);
}
.maki-grocery-store {
  margin: -.35em 0 0 5%;
  z-index: 5;
  animation: rollin 22s linear infinite;
  font-size: 4em;
  color: rgba(220, 0, 10, .7);
}
.maki-commerical-building[data-child="1"] {
  margin: -1em 0 0 5%;
  z-index: 3;
  animation: rollin 6s linear infinite;
  font-size: 7em;
  color: rgba(120, 0, 120, .8);
}
.maki-commerical-building[data-child="2"] {
  margin: -1em 0 0 5%;
  z-index: 2;
  animation: rollin 14s linear infinite;
  font-size: 4em;
  color: rgba(0, 120, 120, .4);
}
.maki-heliport {
  margin: -3.5em 0 0 2em;  
  z-index: 1;
  color: rgba(30, 30, 30, .45);
  font-size: 1.25em;
  animation: rollin 26s linear infinite reverse 2s;
}
@keyframes rollin {
  0% {margin-left:105%}  
  100% {margin-left:-15%;}
}

Demo on CodePen:

Further reading

Thanks for your time! And of course this isn't all you can do with icon fonts. Don't be afraid to experiment yourself.