Using webfonts to insert characters or symbols in a website

Using webfonts to insert characters or symbols in a website—Or why is Opera screwing up my font stacks? Back in 2008, shortly after Apple started the new webfont revolution with the release of Safari 3.1, I wrote an article about how the webfont technology could be used to insert certain glyphs or vector objects like logos in a website. At this time this was more or less a proof of concept, because the browser support was still too poor. But now in 2012 this technique is ready to be used. Well, almost. (Opera, I am looking at you!)

In this article I am not gonna talk about the greatness of webfonts in general—the opportunity to pick any type style we want for our website; use scripts like Cherokee or the cuneiform alphabet which might not be available in any system font—or the possibility to use sets of vector pictograms instead of bitmap images. Even though closely related, this article is only about adding single characters to your existing text on a website. So why might this be necessary? Here are some examples …

Adding missing glyphs to a font

The character set of webfonts is often limited. And even the large system fonts like Arial or Lucida Grande can’t cover the whole Unicode range. New characters are added over time, but if a character has just been added to the Unicode (like the Indian rupee sign or the German Capital Sharp S), it can’t be available instantly on all computers and will probably never be on computers running older OS versions. So if you use such a character on a website, you never know, if your visitors will actually see the character. The browser might fall back to a system font, if it can find the character there, but it might also just show the .notdef sign instead.

Luckily, this problem can be solved with the use of webfonts, even if you can’t change the webfonts itself, because the license doesn’t allow it or you can’t even access the font files because they are delivered by a webfont service like Typekit or Fontdeck.

Recently we updated the design template of and switched from Georgia to Droid Serif for our copy texts in the forums. The font is delivered by Google, but it doesn’t contain a Capital Sharp S, which is used quite frequently on our website. In the case of Droid Serif we could have downloaded the fonts and create a custom version, but that’s not even necessary.

(Injected Capital Sharp S for Droid Serif in use. Screenshot from Safari on OS X)

The only thing we need to change is the font stack! So we went ahead and created a font, which uses the same metrics as Droid Serif and only contains one single character—the Capital Sharp S. The fantastic @font-face Kit Generator from Fontsquirrel makes it very easy to create a cross-browser compatible set of webfont files from just one source font. The font is then loaded via @font-face …

@font-face {
font-family:'Droid SZ';
src:url('dssz.eot.eot?#iefix') format('embedded-opentype'),
url('dssz.eot.ttf') format('truetype');

… and used in the font stack behind the regular webfont:
font-family:'Droid Serif','Droid SZ', Georgia, serif;

When the browser can’t find a certain character in the used font, it should look for it in the other fonts of the font stack. So when someone uses a Capital Sharp S, it will just be taken from the single-character font. Since the Droid Serif font will only be used, when there is webfont support, the additional character will also only be used, when there is webfont support.

Live Demo (Capital Sharp S injected in system fonts)

Does it work? Picking up a missing character from the next font in the font stack does work great in IE 7+ and all current versions of Safari, Chrome and Firefox. It does however not work in Opera, even though this bug is known for quite some time. As it seems, even the most recent versions will ignore the font stack when a character is missing and just pick a local font from the system to show the character (if even available).

The good thing about this injection method is, that I don’t have to create a custom version of Droid Serif. It can still be delivered by Google and future updates to the fonts can be applied without the need to change anything on my side.

Overriding glyphs in a local font or webfont

In the last example we put the single-character font behind our regular font in the font stack. But we could also put it in front of it to override just this character in the font—if the font already has it. So if I don’t wan’t to rely on the Rupee sign that Microsoft might put into Arial, I could create a one-character font of it and inject it like this:

font-family:’My Rupee font’,Arial, sans-serif;

Here is an example of this technique where the ampersand character is replaced by a more decorative script version.

Live Demo (webfont ampersand overriding a local font)

Does it work? Not perfectly. This technique has still some problems. Internet Explorer 6 will use the single-character font as standard font and not fall back to the other fonts in the font stack, showing all but our injected character as .notdef symbols. So IE until version 6 must be excluded from this replacement with conditional comments. But Opera really fails in this case. Since it doesn’t honor the font stack once it found a working font, it will only render the single-character font correctly and show all other characters in a local font, no matter what we have defined in our font stack. And we can’t define in any way, which font this will be. This image shows the mess Opera creates. The live demo can be tested here.

This screenshot is from Opera 11.6 on OS X. It should show Courier New in regular/italic/bold with a matching Capital Sharp S as fallback (left column) and override glyph (right column). But instead, Opera falls back to the locally installed Adobe Text beginning from the first missing character (left column) or shows the correct Capital Sharp S but renders the surrounding text in Times New Roman instead of Courier New.

Embedding logos or other vector objects in a website

This technique is not limited to characters of certain alphabets. Any vector object can be embedded in a website. The advantage is the great flexibility. In contrast to bitmap images, such webfont objects can easily be styled and scaled and the will always maintain a correct position to surrounding text—because the object itself is threaded as text. Here is an example. The logo is called using a SPAN tag within a regular headline. Since the content of the SPAN tag contains the full text of the logo, this text can be indexed and copied and when there is no webfont support, the browser will just show the text. This works in all browsers supporting webfonts, this time even including Opera.

Live Demo (embedding a vector logo in a website)

Conclusion: Very old browsers like IE 6 are once again a troubler-maker, but overall, the technique of embedding single glyphs as webfonts works fine in all recent browsers except Opera. As Dustin Wilson has pointed out, the fact that missing glyphs should be taken from the other fonts in the font stack would be the obvious thing to do and this is also written down in the CSS3 Fonts Module Specification. So I hope Opera will fix this problem soon. I hope I could give some examples where this behavior would really be helpful. If anyone knows any work-arounds for this Opera problem, I would be happy to hear about it.




  1. Michael Calkins 2012/01/12 at 9:25 PM #

    Like 5 people use Opera.

  2. James W 2012/01/12 at 9:40 PM #

    I looked at web fonts as a way of implementing icons in an interface, but certain browsers don’t always anti-alias and small jagged icons are ugly, or even illegible. Even at larger sizes, jagged edges on your logo does not look good. Foiled by Microsoft again.

  3. Si 2012/01/13 at 3:19 AM #

    >but certain browsers don’t always anti-alias

    If you’re worried about these browsers (or more accurately OS’s / user settings) then you shouldn’t be using web fonts at all. :-) Oh and be sure to set the gasp table properly.

  4. batteur 2012/01/14 at 4:24 AM #

    Specifying fonts for special characters: “Creating Custom Font Stacks with Unicode-Range”

  5. Crissov 2012/01/14 at 9:18 PM #

    Did you try using
    @font-face {
    font-family: Droid Serif/*note: the same as usual */;
    unicode-range: U+1E9E;
    src:url('dssz.eot'); src:url('dssz.eot.eot?#iefix') format('embedded-opentype'), url('dssz.eot.ttf') format('truetype');
    } …
    foo {font-family: "Droid Serif"; Georgia, serif;}}


  6. Ralf Herrmann 2012/01/14 at 9:23 PM #

    Thanks for the mentions of the Unicode-Range feature. I was also using this in my demo in 2008 because Safari already supported it back then:

    Still, it doesn’t work across all browsers either, so it doesn’t help in this regard.

  7. Richard Fink 2012/01/16 at 7:32 AM #

    Nice piece, Ralph. I’ve been thinking a lot about the unique possibilities provided by font stacks and so it was good to see somebody else also thinking - and doing quite creatively - along the same lines.


  8. vernon adams 2013/02/05 at 5:09 PM #

    Great piece. Thanks. Another way things can go is the the symbolset route. When the browser space is 100% opentype savvy, symbols can be added using opentype features, e.g. contextual chain substitutions. I am dong this at the moment with a few webfonts; extending to add symbol & icon ‘sister’ fonts. E.g. there’ll be an “Oswald-icon webfont”. For example, via css, the text ‘fire’ set in Oswald, will read as ‘fire’, but set in Oswald-icon, the text ‘fire’ will display Oswald’s fire icon. ‘Sister fonts’ are probably not necessary, it could probly be done via subsetting too. On the downside, this is when the long lengths of some unicode descriptions are an issue; if i set the text ‘U+2794′, ‘u+2794′, or ‘right arrow’ in Oswald-icon then Oswald’s Heavy wide-headed rightward arrow would render. That’s fine & handy, but i’m not sure it’s worth creating a contextual substitution to switch the text ‘Heavy wide-headed rightward arrow’ to the right arrow icon too :)


Leave a Reply


More in Web Design & Webfonts (6 of 27 articles)