Question

I'm developing a web page and found FontAwesome as a pretty neat way to add nice icons to things, however by default font downloads are blocked by the NoScript plugin for Firefox.

This would not be an issue for normal fonts, but FontAwesome uses unicode characters which are deliberately outside the usual printable range of most fonts, so adding a font stack to the CSS (EG: font-family: FontAwesome, sans-serif;) will not work as all the icons just render as hex-squares.

I realise I can tweak NoScript to allow font downloads, but that is not the ideal solution for all users - I would rather the page degrade gracefully.

Of course, it would be easy to do this with Javascript/jQuery, but of course if it's NoScript that's doing the blocking that's no help either, and it fails the test if the user doesn't have javascript enabled.

What would be ideal would be to have some CSS style/rule that acts as the fallback for any FontAwesome objects, replacing them with some basic character or even just not displaying anything.

For those unfamiliar with FontAwesome / TL;DR:

All FontAwesome icons have the CSS class "fa":

.fa {
    display: inline-block;
    font-family: FontAwesome;
    font-style: normal;
    font-weight: normal;
    line-height: 1;
}

FontAwesome loads the custom font like this (I removed

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

And then a particular FontAwesome icon will have its own specific class that inserts the relevant unicode character, for example:

.fa-star:before {
    content: "";
}

The HTML for the icon will look like this:

<i class="fa fa-star"></i>

So the problem here is: We need some way, preferably in CSS, to replace, remove, or hide the content of items with the CSS class "fa" if the typeface "FontAwesome" is NOT loaded.

Was it helpful?

Solution

Well, I think I solved this thanks to you guys leading me in the right direction:

In the head, I put this:

<noscript>
    <style>
        [class*="fa-"]:before
        {
            content:"+";
        }
    </style>
</noscript>

This selects each fa-icon class item, which are all defined in the pattern:

.fa-heart:before {
  content: "\f004";
}

And replaces the content with a generic character, or indeed anything else we might care to insert (including nothing).

Does this seem reasonable or is there some terrible side-effect I've missed here?

I realise there is a remote possibility that someone has font-loading blocked but javascript enabled, but for now I'm happy to ignore that customer demographic ;)

Edit to add:

After all this time this answer is still getting votes (thanks!), clearly it's still an issue, so I thought I'd post this link about greatly improving (and trimming) FontAwesome in a variety of ways: FontAwesome Fixed

My favourite is actually embedding selected icons as inline Base64 coded SVG, either in the HTML or your CSS. This seems pretty elegant and efficient, especially if you only need a couple of icons out of the set. FA still feels like a fudge to me.

OTHER TIPS

One way to work around this would be to pull in another CSS file for <noscript> users, and override the .fa-* classes for images or sprites.

For example:

<noscript>
<link rel="stylesheet" type="text/css" href="safe-icons.css" />
</noscript>

Your safe-icons.css file might look something like this:

.fa {
    display: inline-block;
    overflow: hidden;
    color: transparent;
    font-family: sans-serif;
    width: 16px;
    height: 16px;
    background-position: center center;
    background-repeat: no-repeat;
}

.fa-star { background-image: url('star.png'); }

Of course, you'll have the issue of dealing with icons pulled in from FontAwesome that have different sizes, but this will certainly strike a balance, and render at least something to users with NoScript enabled.

I recently ran into problems where JS is enabled, but users are on a secured network that blocks either all web fonts, or FA specifically.

To fix it, I used something similar to this:

function css(element, property) {
  return window.getComputedStyle(element, null).getPropertyValue(property);
}

window.onload = function () {
  var span = document.createElement('span');

  span.className = 'fa';
  span.style.display = 'none';
  document.body.insertBefore(span, document.body.firstChild);

  if ((css(span, 'font-family')) !== 'FontAwesome') {
    // add a local fallback
  }
  document.body.removeChild(span);
};

Basically, it's a bit of jQuery that creates a FA element on the page and checks to see if the font was loaded correctly. If not, you can implement a fallback. In my case, the fallback was to insert an <img> tag with a generic placeholder graphic.

It's not pure CSS, but it (1) allows for more powerful fallback measures, and (2) covers more scenarios than just <noscript>

I realize this is an ancient question but I recently landed here wondering something similar.
I managed to solve my issue by just hosting the icons myself.

Example of my own html after following the above hosting guide.

 <head>
    <link rel="stylesheet" href="assets/css/all.css">
 </head>

 <footer>
    <a href="https://www.instagram.com/"><i class="fab fa-instagram"></i></a>
    <a href="https://www.facebook.com/"><i class="fab fa-facebook-f"></i></a>
 </footer>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top