Inserting icon fonts to your layouts adds fun visual queues for your users and are especially successful as menu links or as replacements for larger graphics. Like standalone SVG files, they can be scaled losslessly and manipulated with CSS for easier customization. Icon fonts are normally displayed by including an icon font stylesheet, then inserting an HTML element where the icon should appear, such as <span class="icon123"> or <i class="xyz">, but using the HTML method is not always possible. This quick tip will show you how to add icon fonts to any element in your site safely with just CSS.

Install Your Icon Font

Before you jump into adding icons, you’ll need to choose an icon font library to use, such as Font Awesome or Themify Icons.

There are a couple ways to go about adding icon font libraries to your website:

  • Including a remote library (popular)
  • Downloading and hosting it yourself (best performance)

Themify WordPress themes already come with both FontAwesome and Themify Fonts installed. Learn more about Font Awesome install options or learn more about Themify Icon install options.

Exercise – Adding Icons to Menu Links

In the following demo, I’ve included the Font Awesome library and an example menu styled three different ways to show how you can add icons before (or after) the link, or replace the link with an icon.

icon-font-demo

View Full Screen Demo

Download Demo ZIP

Step 1 – Get Your Element’s Selector

The CSS3 pseudo-element ::before will place the icon before the link text.

In this example, the ID selector for the menu’s home link is #menu-link-1 which you can see by right-clicking the link and choosing Inspect in the browser menu.

font-icon-menu-id

The combined selector looks like this:

#menu-item-1 a::before{ }

You can also use the ::after pseudo-element to place an icon after the link text.

Here is a look at the menu HTML and CSS together:


...
  <ul>
    <li id="menu-link-1"><a href="#">Home</a></li>
    <li id="menu-link-2"><a href="#">About</a></li>
    <li id="menu-link-3"><a href="#">Contact</a></li>
    </ul>
</section>
    <style>
    /* icon-added icon styles */
    #icon-added a::before{
      padding-right: 10px;
      font-family: "FontAwesome"
    }
#menu-link-1 a::before{ content: "\f015"; } #menu-link-2 a::before{ content: "\f2b9"; } #menu-link-3 a::before{ content: "\f0e0"; } </style>

Step 2 - Drop In The Icon

There are only two critical pieces you need to get an icon font to display: the icon's unicode number, and the font-family, which is always "FontAwesome" for Font Awesome, or "themify" for Themify Icons.

font-family

Since this menu has an ID of "icon-added" we can use that ID to set a font family once for all links inside it that have a ::before pseudo-element.


#icon-added a::before{
  padding-right: 10px;
  font-family: "FontAwesome";
}

content

The icon is rendered in CSS by setting the content property to the icon's Unicode or ISO number. This number is listed at the top of each icon's detail page on the Font Awesome website:

font-awesome-unicode

You can also find this number by right-clicking an icon, such as those on the Themify Icons page, expanding the HTML to find the ::before element, then looking at the CSS style:

themify-icon-unicode


#menu-link-1 a::before{
    content: "\f015";
}

This will place the house before the Home text in the menu link.

icon-before

That's all there is to it!

Replacing Links With Icons

If you want to hide the text inside the link so only the icon appears, you can use this little trick. This technique can be applied to many different HTML elements and their content where you want to use an icon font, such as replacing images, sprites or spans.

First, we restyle the menu's default links:


#icon-replace a{
  color: transparent;
  overflow: hidden;
  max-height: 40px;
  width: 16px;
}
  • The transparent value for color is a safety measure in case the link text peeks out on a specific display.
  • The overflow and width resize the link element so only the icon is visible, and max-height ensures the link element doesn't expand if the link text wraps(set here to the same value as the menu's original height).

The font family and icon unicode are declared the same as in the last example:


#icon-replace a::before{
  font-family: "FontAwesome";
}
#menu-link-4 a::before{	
  content: "\f015";
}

icon-replace

Extra Tip: Icon Hover States

To apply a specific hover color to the icon, you can combine the :hover pseudo-selector with the ::before pseudo-element like this:


#icon-replace a:hover::before{
   color: #0CF;
}

To learn more about styling icons, or implementing them through custom HTML, see FontAwesome Examples

14 Comments

John
Nov 29, 2016 at 3:18 am

Don’t use icon fonts, use svgs instead. This has been common knowledge for some time now.

Nick La
Nov 29, 2016 at 10:47 am

If you use a lot of icons, using icon font can reduce http requests.

Alex
Nov 30, 2016 at 1:12 pm

@Nick La – Use svg sprites

Hans Koch
Nov 30, 2016 at 4:27 pm

SVG spritesheets or HTTP/2 ;)

Jess
Nov 30, 2016 at 4:38 pm

SVG sprite sheets solve that issue :)

rkgttr
Nov 30, 2016 at 9:48 pm

No Nick. The correct way to use a SVG icons system is to have all your icons defined as symbols in a single SVG file. So a single HTTP request is needed. These icons are then referenced (using the tag) into inline SVG elements in your markup.

Joost
Dec 1, 2016 at 3:57 am

Use an SVG-sprite in that case…

John
Dec 1, 2016 at 7:38 am

If you use a lot of icons, you can generate an SVG sprite using the build tool of your choice that bundles them as symbols. You can then access said icons via .

I’ll admit that you will still need BoomSVGLoader or a similar solution to have it work with an external sprite and still have it cacheable, but the solution in itself is far superior to icon fonts which have a ton of accessibility and rendering issues.

Nick La
Dec 1, 2016 at 12:44 pm

SVG-sprite is only good for custom/client sites when you have the exact icons. For WordPress themes that we do at Themify, icon font is the best solution because users can pick any icon and manipulate the color/size, etc. It depends on the situation and purpose.

John
Dec 3, 2016 at 8:27 am

You can manipulate everything on an SVG with CSS/JavaScript: color, shape, visibility, You can have multiple colors without hacks and umsupported ligature features and you’re not leaving people with disabilities in the cold.

I advise you read up on SVG. Read Sara Soueidan’s blog or Chris Coyier’s book on SVG and you’ll quickly realise there’s no upside to fonts over SVG for icons.

Johnny
Nov 29, 2016 at 11:39 am

Yesss!!! Thank you! I’ve been trying to figure this out!

L. Pillai
Nov 30, 2016 at 1:48 pm

What are SVGS? Why are they better than icons?

John
Dec 1, 2016 at 7:40 am

Ok, let’s try that again:
<svg><use xlink:href="#id-of-symbol /></svg>
of if that doesn’t work the following pseudo-code: svg – use xlink:href=”#id-of-symbol – /svg

Vail Joy
Dec 1, 2016 at 10:39 am

While this tutorial is aimed at cases where you need to modify existing markup (where injecting an SVG via CSS is not always possible or easily understood by everyone), I wanted to mention that Font Awesome 5 will be introducing an SVG framework for who like to use them, which will be as easily to implement as standard i tags. For those of you who are unsure what SVGs are and why there is debate over them, designer Ben Frain offers a balanced argument for why Icon Fonts are still viable, especially for the average web person, and is an excellent place to add your input on the debate: https://benfrain.com/seriously-use-icon-fonts/

If you do have an SVG or SVG sprite you want to use in this way, you can use a pseudo element in much the same way by either setting the content property to the SVG url like this:


.example a::before {
    content: url(http://www.yoursite.com/path/to/star.svg);
}

or by setting a background declaration as shown in this codepen.

Post Comment or Questions

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.