I love Sass, and I love using icon fonts.

However, I do not like the limitations of using inline non-semantic, presentational markup to place these wonderful symbols, e.g.

<i class="fa fa-trash-o"></i>

What if we could keep the embellishments in our stylesheet, minimize the HTML markup, and keep things a bit more semantic?

I think we can, and this is what we’ll accomplish in a few steps. I first came across this approach from Jayden Seric’s post, Fun With Sass & Font Icons.

We’ll be using the Font Awesome icon library for this example. Font Awesome offers a comprehensive library of icons, and they’re all free and GPL compatible.

Set a Sass variable for font-family of icon font

Let’s say we want to set up a social nav, and a Search bar icon as featured on our site.
Screenshot of WDS social nav and search

We’ll assume we already have Font Awesome enqueued properly in our WordPress theme (see wd_s for example). First, let’s declare our Font Awesome font-family as a Sass variable:

$font-icon: "FontAwesome";

Sass @mixin for icon fonts

We can use our newly defined $font-icon variable (line 18 below) within our new handy mixin to Kiss It Simple, Stupid (K.I.S.S.):

// For adding font icons to elements using CSS pseudo-elements
// http://jaydenseric.com/blog/fun-with-sass-and-font-icons
@mixin icon($position: before, $icon: false, $styles: true) {
    @if $position == both {
        $position: 'before, &:after';
    // Either a :before or :after pseudo-element, or both, defaulting to :before
    &:#{$position} {
        @if $icon {
            // A particular icon has been specified
            content: "#{map-get($icons, $icon)}";
        @if $styles {
            // Supportive icon styles required
            speak: none;
            font-style: normal;
            font-weight: normal;
            font-family: $font-icon;
        // Include any extra rules supplied for the pseudo-element

Map Unicode Characters to Custom Aliases

Now here is where it gets interesting, because typically Font Awesome gives us icon classes with unicode characters, like:

  • .fa-search / Unicode: f002
  • .fa-facebook / Unicode: f09a
  • .fa-twitter / Unicode: f099
  • and so on

But now we can create our own mapping, and use any semantic, or non-semantic aliases:

// Map icon names to font unicode characters
$icons: (
    search: "\f002",
    facebook: "\f09a",
    twitter: "\f099",

    // or goofy aliases, like
    magnifying-doohickey: "\f002"

And now we use our mixin to assign our custom magnifying-doohickey icon to our Search, like so:

[href^="#search-popup"] {
    @include icon(before, magnifying-doohickey) {
        color: #b4b4b6;
        font-size: 24px;

At first, this may seem like a bit of extra overhead because you’re having to manage the font mapping. However, this opens up the ability to mix-and-match your own custom SVG icons with existing libraries, like Font Awesome. Tools like Font Custom can auto-magically generate the icon mapping for you.

How often do we see icons that do not align with their contextual information, like the bullhorn icon sitting next to “Contact” in a main navigation?
screenshot of icon navigation

Now we can map an alias so in our project we can use @include icon(before, contact); instead of @include icon(before, bullhorn);, or better yet put it all in an @each loop

$icons: (
    // Font Awesome's .fa-user
    about: "\f007",
    // Font Awesome's .fa-bullhorn
    contact: "\f0a1",
    // Font Awesome's .fa-newspaper-o
    news: "\f1ea",
@each $nav-item in about, news, contact {
    & > li.#{$nav-item} > a {
        @include icon(before, #{$nav-item});

I find this easier to manage in the long run, and hope you find it useful!

Further Reading


2 thoughts on “Mapping Icon Fonts with Sass

  1. Hi!
    Good tips, I like it.

    For my everyday call to icon-font on custom class, I used @extend, like this:

    @extend .fa-facebook;

    It’s very usefull when you use custom icon-font (like fontello) where the code can change on every edit.

Have a comment?

Your email address will not be published. Required fields are marked *

accessibilityadminaggregationanchorarrow-rightattach-iconbackupsblogbookmarksbuddypresscachingcalendarcaret-downcartunifiedcouponcrediblecredit-cardcustommigrationdesigndevecomfriendsgallerygoodgroupsgrowthhostingideasinternationalizationiphoneloyaltymailmaphealthmessagingArtboard 1migrationsmultiple-sourcesmultisitenewsnotificationsperformancephonepluginprofilesresearcharrowscalablescrapingsecuresecureseosharearrowarrowsourcestreamsupporttwitchunifiedupdatesvaultwebsitewordpress