Grow your CSS skills. Land your dream job.

Stackicons: Doing More with Icon Fonts

Published by Guest Author

The following is a guest post by by Parker Bennett. While icon fonts are efficient and easy to use and scaleable and all that, one of the classic "strikes" against them is that the icon can only be one color. Parker has a brand new project that solves that issue in a simple and clever way. I'll let him introduce it for you.

Even though the future of icons will likely be SVG, here in the present, icon fonts still offer a compelling alternative — with super easy styling of color, size, text-shadows, hover effects and more using just CSS. Icon fonts are still awesome.

One big advantage SVG has over icon fonts is full color. But icon fonts don’t have to be limited to just a single color. By overlapping two or more elements we can create unique “multi-color” icons with a contemporary flat look. If you’ve ever done any two-color or screen printing, it’s a similar idea.

I call them Stackicons.

Dribbble
Github

For each color, we use a separate pseudo element, then use absolute positioning to stack them on top of each other. (If you want more than two colors, it will cost you a non-semantic span.)

/* @font-face to load icon font... */

/* horizontal button row: inline-block vs float makes positioning easier using text-align */

/* any class that starts with "st-icon-" */
[class^="st-icon-"] {
  display: inline-block;
  vertical-align: top;
  white-space: nowrap;
  /* child elements absolute */
  position: relative;
  /* remove inline-block white-space */
  margin-right: -.16em; /* 5px */
  /* if not already universally applied */
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  /* padding here for text, icons replicate this using size and position:absolute - padding makes touch-target bigger */
  padding: 0.143em;
  /* units used in font: 1em = 2048, icons 2400 wide, so icons are 1.171875em (2400/2048). Add padding x2 to get size: */
  height: 1.45788em;
  width: 1.45788em;
  font-size: 1.815em;
  /* text hidden old-school */
  text-align: left;
  text-indent: -9999px; }

/* position:absolute stacks pseudo elements - extra <span> in markup = 2 extra pseudo elements */
[class^="st-icon-"]:before,
[class^="st-icon-"]:after,
[class^="st-icon-"] span:before,
[class^="st-icon-"] span:after {
  display: block;
  position: absolute;
  white-space: normal;
  /* match padding above */
  top: 0.143em;
  left: 0.143em;
  /* undo text hidden */
  text-indent: 0;
  /* inherits size from parent, ems cascade */
  font-size: 1em;
  font-family: "Stackicons-Social";
  font-weight: 400 !important;
  font-style: normal !important;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-smoothing: antialiased;
  /* screenreaders */
  speak: none;
  /* transitions here */ }

.st-icon-amazon:before {
  /* character code - unicode private use area */
  content: "\e079"; /* black "a" */
  color: black; }

.st-icon-amazon:hover:before {
  color: #626262; }

.st-icon-amazon:after {
  content: "\e080"; /* orange smile */
  color: #ff9900; }

.st-icon-amazon:hover:after {
  color: #ffbd59; }

Using rgba values, we can even do some color mixing to give us more colors. If we really want to push the limits, we can use -webkit-background-clip: text to give icons a -webkit-linear-gradient background.

Yes, it’s a bit on the hacky side: It takes some design forethought, and the ability to generate an icon font. There are more moving parts to manage. But it also offers a lot of flexibility, especially using Sass variables.



This :hover effect would be hard to do in SVG

Stackicons-Social

To show how it works, I made a free, open source icon font, Stackicons-Social, and created a Sass “Construction Kit” to generate the CSS for both single color icons and “multi-color” versions of over 60 social brands.

Stackicons-Social

View Stackicons-Social

I also created a range of button shapes in the font, from square to circle (plus icon-only), and have classes that override the shape on the fly. Want circular icons? Just add the .st-shape-circle class. iOS style? .st-shape-rounded3.

Try it on CodePen

Putting It Together with Sass

Behind the scenes, there is a group of .scss _partial files that Sass compiles. If you’re comfortable using Sass you can customize things extensively just by changing variables in this "construction kit":

  • fonts-stackicons-social - Path to stackicons-social font.
  • colors-social–2014 - Color variables for social brands.
  • unicodes-stackicons-social - Font unicode characters abstracted into variables.
  • construction-kit-stackicons-social - This is where we generate default values for icon size, margin, padding, shape, color, hover-style, etc. (Play here.)
  • css-defaults-stackicons-social - This does the CSS grunt work to create each .st-icon-($brand) class.*
  • override-shapes-stackicons-social - Let’s you override the button shape on single-color icons using classes: st-shape-square to st-shape-circle, plus st-shape-icon.*
  • override-colors-stackicons-social - Some examples of “color-styles” for single-color icons to demo different options. Lots of extra CSS, so it’s commented out by default.*
  • multi-color-kit-stackicons-social.scss - Like “construction-kit” above, but for the .st-multi-color class: generates default shape, color-style, etc.
  • multi-color-css-stackicons-social.scss - Like “css-defaults” above, this does the CSS grunt work to generate each multi-color .st-icon-($brand) class.*
  • multi-color-override-shapes-stackicons-social - This allows you to change icon shapes using classes on multi-color icons.*

* Because Sass doesn’t allow us to use variables within variables, this uses a lot of @if statements to generate the .st-icon-($brand) classes. Ugly, but marginally maintainable. There are several @each statements, listing the brands to output. Ideally, you would go through and edit these lists to limit the CSS output to only the brands you need.

Rolling Your Own

There are some great free resources for creating icon fonts, including icomoon.io and fontello.com. I use Adobe Illustrator and Glyphs on the Mac. (Glyphs Mini is a lower cost option that limits the units per em to 1000. They also offer student pricing.) To generate the web font versions, I recommend FontPrep, which Brian Gonzalez just made open source. FontSquirrel is another good free option. (If you’re interested in more workflow details, let me know in the comments.)

You should also check out some random dude (P.J. Onori) and his iconic project. He also has some helpful tips on using icon fonts.

As always, if you have any questions, comments, or corrections you can email me at parker@parkerbennett.com.

Comments

  1. Those look AMAZING. This has opened up my eyes to new possibilities in SVG. Thanks Parker!

    • I want blogger and github stackicons add to my blogger blog, any easy solution?.
      Also I’m find many custom fonts but Their is not include blogger icon :)

  2. Will B.
    Permalink to comment#

    Seems kinda cool, but also seems a bit heavier than just using a simple image icon. What would you see as the major advantages?

    • Kyrodes
      Permalink to comment#

      Smaller file, scale up and down with quality, responsible, CSS transitions, animation, shadow, border, color…

    • Permalink to comment#

      @WillB.

      1) No need for separate images for high-retina and non high-retina displays

      2) No additional http requests to fetch images.

      3) what @Kyrodes said

  3. For whatever reason I haven’t tried so just asking about this. But can’t you just export a multi colour vector form Illustrator and use that instead of one of these?

    • Cory
      Permalink to comment#

      You can, but you won’t have as much control over the styling of said icon.

    • So if you already know what your colours are going to be then you’ll be fine? I’m up for anything that’s a great idea, but I’m just comparing the length of time it would take to change the colour in Illustrator with a pipette and re-saving, as opposed to trawling through a stylesheet to locate and change pseudo selector colours. But then again, what’s the difference in load time as that is also a factor?

      I’d better do some experimenting… unless anyone on here has already done this?

    • Permalink to comment#

      What about if you wanted to use the same icon in multiple places with multiple styles? You either have x number of images you’d have to create, or one 1 icon in your font with x number of styles applied in x number of places. I’d find the latter much easier, personally.

    • Cory
      Permalink to comment#

      SVG’s work perfectly fine if you’re not worried about changing the color or whathaveyou on the fly. I use icon fonts when I want a particular icon to change colors on :hover. With SVGs, this would mean swapping out two separate files or maybe manipulating the SVG with some fancy JavaScript. Then another SVG file for :active. It’s not impossible, but it’s a considerable amount of work. With an icon font, you just treat the icon as a character. Being able to manipulate the icon in CSS also has the added bonus of making it super simple to add a transition to the color property.

    • Hi Cory, that’s a very good point! This is the kind of stuff that I want to hear.

    • SVG’s work perfectly fine if you’re not worried about changing the color or whathaveyou on the fly. I use icon fonts when I want a particular icon to change colors on :hover. With SVGs, this would mean swapping out two separate files or maybe manipulating the SVG with some fancy JavaScript.

      It very much depends on how you use them. If you use inline <svg> you can target the shapes within an absolutely change aspects of them (including background) with CSS. If you use svg-as-img or background-image, you can’t though.

    • Hi Chris, what’s appealing about that is the control you would have during an animation. Morphing shapes and colours into various other shapes and colours. I haven’t tried any of these techniques yet, but will do.

  4. Permalink to comment#

    The advantages you would already have when using font icons over image icons and its hassle of a sprites image. Author named a few advantages in the post such as scalable. efficient, CSS ‘styleable & animatable’.

  5. David
    Permalink to comment#

    No mention of browser compatibility.

    Can we expect the exact same level of compatibility as with regular font icons?

  6. Red Feet
    Permalink to comment#

    Did I do something wrong or are http://stackicons.com/ and http://www.stackicons.com/ both inaccessible right now?
    as in:
    403 Forbidden
    You don't have permission to access / on this server.
    Apache/2.2.22 Server at www.stackicons.com Port 80

  7. Super cool article. I’ve actually stacked and combined icon fonts when in a pinch, it’s doable but far from perfect.

    By the way, we need to that CodePen icon into FontAwesome. Thanks Parker for the sweet icon font set!

  8. Eduardo Suarez
    Permalink to comment#

    I’m here wondering… Can you use letter-spacing to stack characters? Obviously you need to make a monospaced font (I don’t know if Stakicons is monospaced) to align properly, but you don’t need all position properties.

  9. This is a sweet idea, I totally dig it. While one color font awesome icons typically suffice for me and my projects, I’ll keep this one in my back pocket for a rainy day. Nice work Parker.

  10. Mike Loffland
    Permalink to comment#

    What are the browser compatability gotchas in the CSS generated by SASS?

  11. Lutz Rosema
    Permalink to comment#

    Looking back to the 80′s, I remember a similar technique on my first 8 bit computer, the Amstrad CPC 464: Drawing multiple characters overlapped was the simplest way to get multi-colored sprites in BASIC :)

  12. Permalink to comment#

    Honestly, I’d rather just use svg sprites instead of this. Yes, it’s an interesting technique, but kinda overkill.

  13. GreLI
    Permalink to comment#

    Don’t open it in Opera Mini!

  14. Anon
    Permalink to comment#

    This looks nice. But how can i create the font file needed for this technique?

    • Permalink to comment#

      Good question. I am wondering the same.

      I realize each layer is a different character but is there a way to quickly position each character without guessing and checking?

      As William mentioned below http://glyphter.com/ is a great way to create the base icon fonts.

  15. Permalink to comment#

    Thanks for the article! You can stack up to four icons in one single HTML element, by using only CSS. I wrote a small blog post on it: http://pixelambacht.nl/2014/multicolor-icons/

    This would eliminate the extra span in your HTML.

  16. Permalink to comment#

    Personally, I think single-colour fonts look cleaner, but this is a nice trick; bookmarked. :)

  17. Permalink to comment#

    Glyphter.com is another good resource for creating icon fonts.

  18. Julz
    Permalink to comment#

    http://fontawesome.io was already doing this and have classes built in to layer the icons.

  19. Permalink to comment#

    My friends and coworkers Nik Wise and Paul Pederson did something along the same lines last year that focused on using ligatures for a semantic fallback. Different technique but very similar concept. Worth taking a look:

    github.com/nikolaswise/three-color-icons
    paulcpederson.com/articles/devicons
    nikolaswise.github.io/devicons

  20. Permalink to comment#

    I think svg has some capabilities that not a lot of people are aware of it.

    People who knows should inform so that others gets more familiar with these great possibilies that svg has.

  21. Awsome! I have used your great tutorial to make some stacked icons for credit cards:

    http://williamrandol.github.io/CreditCardIconFont/

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".