How to create perfect web-fonts in 3 steps

Web-fonts are a hassle. Once you think that you’ve finally nailed it, whoops there comes another special case where all fonts are totally [insert swearword of your choice here]. Same happened to me after my last post on how to create nice web-fonts for every browser. The font I created following this howto worked in all of my test-cases, but soon after I had published the post several comments popped up that told me different. Some of these were only small glitches I could either ignore or fix easily, but in the end I had to admit that my proposed solution is at least incomplete. So I again went on a quest to find the best way to create perfect webfonts.

This took me on a long an dangerous journey, but you might want to take the shortcut and use Fontie, the magic web-font generator, instead. However, since you’re still reading I assume you want to know everything! So here my young fellows is my story on how to create webfonts that look good on any operations system and browser.

Prepare yourself

As with every big journey a good preparation is the insurance to come back happy and healthy. So let’s start: To create nice webfonts you need four tools:

  • Font Forge: The open-source swiss army knife for font creation.
  • ttfautohint: A neat little tool that makes your fonts look better.
  • eotfast: A command-line TrueType to Embedded OpenType converter.
  • scour: A python script to clean up Scalable Vector Graphics.

Font Forge, ttfautohint and Python are available for Windows, OSX and Linux. eotfast is available for Windows only, but you can use ttf2eot or wine on OSX and Linux instead, so this howto should work for everyone. For the rest of the howto I assume that you’ve installed the programs as well as some kind of command line.

Step 1: Create an optimized TrueType font

This one is pretty easy if you ignore the “optimized” in the headline. All you have to do is to open your font in Font Forge, press CTRL+SHIFT+G, select TrueType as format and save everything. Done. If you start with a Truetype font already, you can even ignore this step completely.

But this howto is about creating perfect webfonts, right? ;) So we should not ignore the “optimized” here, but dip our toe a bit deeper into the waters of Font Forge:

Subsetting

Subsetting basically means that you only include the glyphs in the web-font that you actually use on your website. This can reduce the file-size of the final web-fonts dramatically so it’s a good idea to subset your font in general.

To subset a font you first have to open it in Font Forge and select all glyph you want to have in your web-font. You can achieve this by holding SHIFT and clicking on the glyphs (in the default colorset selected glyph have a yellow background). When you’ve selected all glyphs you press CTRL+ESC to invert the selection and remove the now selected unwanted glyphs by clicking “Encoding>Detach & Remove Glyphs” in the menu. After this is done you can generate a TrueType file from the opened font by pressing CTRL+SHIFT+G.

To make subsetting a bit simpler some guys at Google wrote a Python-script calles subset.py that automates subsetting based on Unicode ranges. Using the script is a bit tricky, but it’s actually pretty neat after you’ve mastered it. It is also the core of the Fontie web-font generator, so you might just use Fontie if you’re not interesed in some command-line magic ;)

Font name fixes

If you also want to generate EOT font-files (you most probably want this ^^), you should also take care of the internal font-names. The EOT-standard requires the font-name to start with the family-name of the font (e.g. if the family-name is “MyFont”, the font-name “MyFont-regular” is ok, but “MyRegular” is not). You can edit the names in the “PS Names” section of Font Forge’s font-info dialog (press CTRL+SHIFT+F).

Step 2: Add additional hinting information

First of all: Take a deep breath. The first step might have been tricky, but this one is easy. What we’re doing here is to add some hinting information to the newly generated font. We have to do this, because hinting is THE key to have good looking fonts on windows.

Without the hinting information the windows font-renderer won’t know what are the “important parts” of a font-face and therefore would have problems to render a clear (and readable) font on small sizes. The Mac and Linux font render engines are smarter and can calculate the hinting information automatically, so they don’t care about missing or bad hints.

Fortunately Werner Lemberg started the project ttfautohint, which aims to auto-generate high-quality hinting information for web-fonts, and as far as I can tell it does a very good job. The tool offers some options to refine the results, but for me the default values worked well so far. Here is what we have to do to add some hinting information to our TrueType font from step 1:

  1. Open a console
  2. cd /path/to/font/from/step1
  3. ttfautohint step1font.ttf step2font.ttf

Don’t be irritated if ttfautohint takes less than a second to complete. Auto-hinting is meant to be done on the fly when displaying a font, so it is really fast.

That’s it for step 2. However, ttfautohint offers three different ways to hint the font and has some other features as well, so it might be good idea to play a bit around with the ttfautohint options, if you’re still not satisfied with font-rendering. Smashing Magazine took a closer look at font rendering, which might be of some help, but let’s continue with step 3 now…

Step 3: Generate the required webfonts

With all preparations done, the final step is to generate the font in all formats, which are needed to support all browsers. By name these are WOFF for Webkit- and Mozilla-based browsers, EOT for the Internet Explorer as well as TTF and SVG as fallback formats.

You have the TTF-font already and WOFF and SVG can be generated easly with Font Forge (press CTRL+SHIFT+G, select the format and save). The SVG font however needs a bit cleanup afterwards (here we need python-scour):

  1. Open a console
  2. cd /path/to/font/from/step3
  3. python scour.py --indent=none --remove-metadata --quiet -i step3font.svg -o step3font_cleaned.svg

The last format missing is EOT. Font Forge cannot generate EOT files, so I recommend to use eotfast, because it is able to create compressed EOT files. These are a lot smaller than the files generated by ttf2eot. The commands to generate an EOT file from a TrueType font are:

  1. Open a console
  2. cd /path/to/font/from/step2
  3. eotfast setp2font.ttf step3font.eot

Some finishing

Congratulation my young friend, you have mastered all challenges of this gruesome quest! You should now have a well-hinted and subsetted web-font in the formats TTF, WOFF, SVG and EOT. There are just two last things, which might be of some interest for you.

Cascading Style Sheets

The first thing is the CSS. The code in general is pretty straight forward, but you should take care of the order in which you mention the different formats to ensure that each browser gets the files it can handle best. I use a derivative of FontSquirrel’s CSS that looks like this:

@font-face {
   font-family:'MyFont-regular';
   src: url('step3font.eot');
   src: url('step3font.eot?#iefix') format('embedded-opentype'),
     url('step3font.woff') format('woff'),
     url('step3font.ttf') format('truetype'),
     url('step3font_cleaned.svg#MyFont-regular') format('svg');
   font-weight: normal;
   font-style: normal;
   font-stretch: normal;
}

Smooth fonts on Windows XP

The second thing is Windows XP. Even though XP has the capabilities to render smooth fonts with Microsoft’s own ClearType technology, it is not enabled by default – for whatever reason. This is no problem for IE and Firefox, but Chrome, Safari and Opera obey to the system settings, which can result in some pretty messed up fonts.

Luckily this doesn’t count for SVG fonts, which always look smooth. Unfortunately they aren’t as crisp as their hinted counterparts if they are rendered on system that have font-smoothing enabled. Therefore I developed a small JavaScript called Font Smoothie, which switches to SVG fonts only if font-smoothing is actually disabled. You can find the code in my Font Smoothie GIST over at GitHub.

The usage is pretty easy. Just download the Font Smoothie script and include it anywhere in your page:

<script src="fontsmoothie.min.js" type="text/javascript"></script>

The shortcut

For those of you who don’t have the time to go on the big quest of creating perfect webfonts, I’ve created a magic webfont-generator called Fontie. This does all the work of the steps above (and some additionally magic) 100% automatically and within seconds. Just upload a TTF or OTF file and Fontie will generate you a nice little webfont-package with everything you need.

I use it regularly for my own work and it works without any problems, but please feel free to post comments and bug reports here :)

42 thoughts on “How to create perfect web-fonts in 3 steps”

  1. Pingback: Nice web-fonts for every browser | Pixels vs. Bytes
  2. Man, you are my lifesaver ^_^
    Great article, all needed info in one place. Thank you!

  3. Thank you so much ! This is the most useful and easy-to-use web font generator i’ve seen so far. After spending days looking for solutions to my problems (subsetting, hinting, font smoothing…), you finally provide (gracefully) a one-shot solution. The other guy is right, you are a lifesaver !

    Oh, and the Win XP font smoother is a gift from heaven.

    Thank you

  4. Hi,

    First of all I want to thank you for creating Fontie, it is really a great tool. I do have a few questions, if you don’t mind.

    I am converting a font that has many ligatures, alternates, swishes, etc. If I choose only Latin subsetting, I don’t get anything of that stuff, if I choose keep existing, I get what I want, but it increases the file size considerably, because the font is offering many languages by default.

    There is no way to just select the things I want, ligatures and all the fancy extras alone, with a basic Latin subset?

    My other question is what hinting option is the best to choose, I am not familiar with it:))?

    Thanks

    1. Hej Mirko,

      I guess in your special case you have to use a font-editor (like Fontforge) and do the subsetting by hand for now. We’re might add per-character-subsetting to Fontie some day, but right now there’s just too much other stuff we have to code.

      Regarding your other question I recommend to read the Smashing article on font rendering I’ve linked in the article. This explains all the basics and the rest is just trial and error ;P

      Bai
      Torben

  5. Thanks for this fantastic explanation. Are there times when the longer process has different results than Fontie? I tried to use Fontie, but actually saw no improvement in my fonts. (The thorn in my side is Firefox/Windows 7.)

    1. Since Fontie got some updates after this article was written, it actually does even some more things than the ones described here in the article. Have you tried the different hinting-options? However, Fontie can just fix some general issues. If you want/need to fine-tune your font you should use a font-editor.

  6. I’ve been using the Font Squirrel generator up to now; but Fontie seems to generate webfonts which look closer to the same font as installed locally on my PC, and across all browsers, without the need for text-shadow or other ‘tweaks’ – well done! Two questions though:

    1) the Fontie generator defaults to ‘Windows GDI’ as the hinting mode. Does this have any adverse impact on font rendering on Mac or Android machines?;

    2) will the fontsmoothie.js script work with any set of webfonts which include an SVG, or only those generated by Fontie? Incidentally, I seem to recall that Windows XP does use font smoothing in Internet Explorer, even if it is turned off in the system; but presumably not when other browsers are used. Unfortunately I no longer have any means of testing that!

  7. Hi, you’ve done a great job in this article in explaining things. However, I’m still confused about using the ttfautohint or the scour. You mentioned about opneing a console and typing ‘cd /path /to …etc’. What is that mean, exactly? I’ve downloaded the scour and it doesn’t even have a .exe that I can run. Are you running this using the Command Prompt? If so, can you show me what to type in?
    With the EOTFAST-1, when I double click the .EXE a cmd window pops up and disappear immediately.
    I’ve tried the Fontie, but when I ran it, there’s a warning saying ‘SyntaxError: Unexpected token B in JSON at position 5’. And it happened with other fonts as well. Perhaps you can explain how to solve this.
    I’m not exactly a coder, so that’s why I’m kinda in the need for an easy-to-understand-step-by-step. Thank you.

    1. Hej Remmy,

      Fontie has some stability issues during the lasts months, but I’m pretty sure that I’ve fixed them now (Fontie is now up for more than one week without crashing). So recommend you to try Fontie again.

      Bai
      Torben

  8. First of all thank you for this article. I’ve been trying to subset fonts for a while now and I keep having the error shown on this screenshot: https://bannerwise-dev.azurewebsites.net/font/example.png

    This error only occurs in Internet Explorer. I’m not sure if it happens in all version so far I tested 11.

    This is what I did:
    Use font forge to create a subset for the word Double.

    Upload that subset in Forgie and downloaded the webfonts. After that I added a break in the word Double(see screenshot) and the error or unwanted character appears. Do you have any idea how this is possible?

    I’ve also tried the generator created by fontsquirrel and at that moment the error doesn’t occur. However I’ve not yet found any information on how fontsquirrel approaching subsetting and font conversion.

    You can find the font file here: https://bannerwise-dev.azurewebsites.net/font/Brighton%20Light%20Plain.ttf

    Thank again, Miguel

    1. Thanks for reporting this problem. I’ve added it to the Fontie bug-tracker and will try to find a solution once I’ve got some time. I’ll keep you updated.

  9. Thank you very much for this informative article. Is it possible to compile and run Fontie locally (similar to http://www.useragentman.com/blog/the-css3-font-converter/)

    Thanks again.

    1. No, Fontie is a pure online service and I don’t have any plans to offer Fontie as an offline tool right now. However, maybe I’ll add some kind of API to it, to make it possible to use Fontie from a local script.

      1. Thanks for the update, I hope your new year is going well.

        It would be nice to have Fontie as an API, it’s a great tool. Maybe have the local API Fontie as a bonus given to those who donate through a PayPal link. I, for one, would donate.

        Thanks again.

  10. It looks fontie doesn’t use the default settings on ttfautohint. I tested the same way in this article with ttfautohint though different results compare to fontie. Can I know what settings do you use for fontie? Thanks.

    1. As default Fontie uses: ttfautohint --windows-compatibility --strong-stem-width=G. For directwrite hinting --strong-stem-width=d and for grayscale hinting --strong-stem-width=g. However, Fontie optimizes the font in a number of other ways, which are not related to ttfautohint. These optimizations are more complex and not so easy to explain, as they are written an Python using the Fontforge-Python module.

  11. Hi,
    Do you plan to open source Fontie ?

    I’m looking for a solution to automatically optimize fonts but I can’t find anything closed to Fontie or Font Squirrel.

    Best

    1. Hi Anthony,

      yes I’m actually plannign something like that. But I haven’t found the time to prepare the code for a release so far. Hopefully this will happen during the next two months…

      Bye
      Torben

      1. Excellent, I would also be very interested in this. Please let us know when it is open sourced

      2. Hi Torben,

        Do you any news about your progression on this open source release ? I would be happy to help in any way.

        I stay tuned,
        Best,
        Anthony

  12. I’ve been using your web font generator and have to say, I think it is fantastic! I would however like the option to have more control over the subsetting. There are cases in which I want to only have uppercase letters in a produced font. Perhaps, having the ability to specify Unicode characters or ranges would be a solution to this?

  13. This is a fantastic service you’re providing, thank you so much Torben!
    Open-Sourcing the code would be a great idea, especially considering the possibility for other people to run instances as well so your server load goes down :)

    Cheers,
    Felix

    1. I’m going to spend some time on Fontie this weekend and will hopefully be able to release Fontie as open-source. Sry for the delay.

        1. Hi Oscar,

          actually yes – finally… Originally I wanted to refactor the code and write some documentation, but I’ve never found the time to do so. That’s why I postponed the release of the code took again and again. Sry for that :/

          I think you all have waited more than enough. so I’ve just put the code for the backend on GitHub. The backend is where “the magic” happens. The frontend is just an interface to upload the font-files and trigger the genration of the font-package by the backend.

          Here is the URL to the repo: https://github.com/letorbi/fontie

          I really, really appreciate any clean-up/optimizing PRs from experienced Python developers as this is my first python project. But also other PRs are nice, too :)

          1. Thank you so much Torben for your hard work. This will definitely come in handy for us in the future.

  14. Hi i am not able to convert web font of this https://fonts.google.com/specimen/Roboto+Slab?selection.family=Roboto+Slab into https://fontie.pixelsvsbytes.com/webfont-generator

    1. Hej Milan,

      thanks for your feedback. I’m going to spend some time on Fontie this weekend and will investigate the issue.

      Bye
      Torben

    2. Why do you need to convert fonts from Google Fonts? They’re already available as web fonts.
      If you want to serve them on your own web page, just download the CSS, and from there you can get URLs to the font files to download them as well.
      Honestly though, why not serve from Google? Their CDN is probably faster than any alternatives, and serving from multiple hosts can speed up your site.

      I’m having issues with Fontie as well though, only getting 502 Bad Gateway when trying to convert fonts, are you having the same issue?

      1. Sorry about the 502 error. There was a software update on Thursday that broke the Fontie backend. It is fixed now.

        1. Hey there, having a lot of “HTTP error 504: Gateway Time-out” right now. Funny thing is, this error brought me to this great article :)

          1. Hej Bosco,

            I don’t have any gateway timeouts with Fontie rigth now. Can you confirm that the timeouts still happen?

            Bye
            Torben

  15. Please could you add the ability, in Fontie, to have more control over the fixing of the font name? Ideally, we would have a text box to specify the font name

    1. Nice idea :) Are you requesting it, because you want to rename a font or because the automatic font fixing returns gibberish?

      1. I often get a collection of fonts and the font family in each file is different:
        e.g.
        font-name-bold
        font-name-italic

        I am referring to the font family, not the font name.

        I have not experienced it returning gibberish

  16. First of all, thanks for the nice and handy tool you have developed.

    I believe I have found a couple of bugs (may come from the tools you use). I am trying to get a subset of the DejaVu Sans fonts, as webfonts. I am using their “latest” version (2.37) from https://dejavu-fonts.github.io/Download.html.

    Bug #1: Using the LGC subset, I noticed that the svg’s internal ID and the one used in the generated css file do not match. For instance, in “DejaVu LGC Sans Bold.svg” the font id is “DejaVuLGCSans-Bold”, while in the css, it is “#DejaVu LGC Sans Bold”, which is using somehow the “font-family” svg font property.

    Bug #2: Again, using the LGC subset to start with, and selecting an “Include Latin characters” subsetting (no additional optimizations or hints), all seems fine and the sizes of the generated font formats are as expected (18-93kB). However, if I perform the same operation on the full font set, the EOT files are about 2MB in size. I tried a two step approach, first doing the subsetting and getting the TTF only (OK) and then doing the webfont conversion on those ones … the result was the same: the EOT file was Huge.

  17. Torben,

    Thank you very much for making the fontie daemon public.
    I’m trying to setup a local instance of fontie.
    I’m noob-ish so please excuse any lack of understanding.

    I have reconstructed your old webpage for fontie from the Wayback Machine’s archive: https://web.archive.org/web/20180601173811/https://fontie.pixelsvsbytes.com/webfont-generator

    I have all files and folder structure recreated based on this page:
    https://web.archive.org/web/*/https://fontie.pixelsvsbytes.com/*

    I have taken care of CORS policy issues with the XMLHttpRequest in the require.mis.js file (running a webpack devserv).

    I’m now at the point where I need to wire up the fontie daemon. This is where I am stuck I’m trying to figure out what JS events you assigned for the form values to be passed as well as the call to start fontie with the passed values.

    I think the Wayback Archive is missing some of the needed JS

    Thanks for such a great webfont generator and thanks in advance for any help you may provide.

Leave a Reply

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