@font-face and Web Fonts: Self-Hosting, WOFF2 and font-display
The best way to add custom fonts today is to self-host a WOFF2 file and declare it with @font-face. That means one font file (often a variable font), one short CSS rule, a sensible font-display value, and optionally a preload. Typekit-style script tags, the four-format “bulletproof” syntax and EOT files are all history.
This guide updates the old comparison of @font-face, font services and Google Fonts. The three options still exist, but the trade-offs changed. If you are choosing typefaces rather than wiring them up, start with our @font-face design guide and Typographic Contrast and Flow.
What changed since the bulletproof syntax
The old advice existed because every browser wanted a different format: EOT for old Internet Explorer, TTF or OTF elsewhere, SVG fonts for early iOS. WOFF2 replaced all of that. It is a compressed container that every current browser supports, so one src line is enough.
| Then | Now |
|---|---|
| EOT, TTF, SVG and WOFF files per font | A single WOFF2 file |
| One file per weight and style | One variable font covering a weight range |
| Invisible text until the font arrived | font-display controls what users see while loading |
| Font generators and sliced formats | Subsetting and unicode-range |
| JavaScript loaders from a font service | A CSS file or self-hosted files |
1. Self-hosting with @font-face
Self-hosting gives you full control over performance, caching and privacy, and nothing breaks if a third-party server goes down. This is the default choice for most sites.
@font-face {
font-family: "Inter";
src: url("/fonts/inter-var.woff2") format("woff2");
font-weight: 100 900;
font-style: normal;
font-display: swap;
}
:root {
--font-body: "Inter", system-ui, sans-serif;
}
body {
font-family: var(--font-body);
}
Three details matter here. The format("woff2") hint lets a browser skip files it cannot use. The font-weight: 100 900 range tells the browser this one file is a variable font, so font-weight: 300 or font-weight: 650 all work without extra downloads. And the fallback stack ends in a generic family, because that is what users see first.
Where to get legal font files
- Open-source families. Most Google Fonts families use the SIL Open Font License, which allows self-hosting. You can download them from Google Fonts or install packages from Fontsource.
- Commercial foundries. Buy a web license from the foundry and check its page-view or domain limits. A desktop license does not cover web use.
- Your own conversions. Only convert a font to WOFF2 if its license allows modification and embedding. Always read the license first.
Show the result before it is perfect: font-display
The font-display descriptor sets how text behaves while the file is loading. MDN describes three periods: a block period where text is invisible, a swap period where a fallback shows and gets replaced, and a failure period.
| Value | Behavior | Use it for |
|---|---|---|
swap |
Tiny block period, then fallback text, swapped whenever the font arrives | Body text and brand fonts that must always appear |
fallback |
Tiny block period, short swap window, then stays on the fallback | A compromise that limits late layout jumps |
optional |
Tiny block period, no swap; uses the font only if it is ready almost at once | Decorative fonts, or when you preload and want zero shift |
block |
Longer invisible text | Icon fonts only, rarely anything else |
2. Stop the layout jump with fallback metrics
With swap, text first appears in the fallback and then jumps when the web font loads, because the two fonts have different widths and line heights. You can shrink that jump by defining an adjusted local fallback with size-adjust and the metric overrides.
@font-face {
font-family: "Inter Fallback";
src: local("Arial");
size-adjust: 107%;
ascent-override: 90%;
descent-override: 22%;
line-gap-override: 0%;
}
:root {
--font-body: "Inter", "Inter Fallback", system-ui, sans-serif;
}
The percentages above are example values, not universal ones. Measure your own pair of fonts or use a tool such as Fontaine or Next.js’s built-in font handling, which calculate them for you. MDN lists size-adjust as widely available.

3. Variable fonts and subsetting
A variable font packs a whole range of weights, widths or other axes into one file. Instead of four static files for regular, medium, bold and black, you ship one. Use the registered axes through normal properties such as font-weight and font-stretch, and custom axes through font-variation-settings.
Subsetting removes glyphs you do not need. An English site rarely needs Cyrillic or Vietnamese. Split the font by script and let unicode-range do the rest: per MDN, the browser downloads a face only if the page uses a character in its range.
@font-face {
font-family: "Inter";
src: url("/fonts/inter-latin.woff2") format("woff2");
font-weight: 100 900;
font-display: swap;
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+20AC, U+2122;
}
@font-face {
font-family: "Inter";
src: url("/fonts/inter-cyrillic.woff2") format("woff2");
font-weight: 100 900;
font-display: swap;
unicode-range: U+0400-045F, U+0490-0491;
}
Google Fonts already serves its CSS this way, which is why one request can return several @font-face rules. Self-hosting means you copy that split yourself, or use a package that already includes it.
4. Preload the one font that matters
Browsers discover fonts late: they must download the CSS, build the page, and only then learn which fonts it needs. A preload hint starts the download earlier.
<link rel="preload" href="/fonts/inter-latin.woff2" as="font" type="font/woff2" crossorigin>
Keep the crossorigin attribute even for same-origin files, because fonts are always fetched in CORS mode and the preload is wasted without it. Preload only the one or two files used above the fold. web.dev recommends pairing a preload with font-display: optional as the most effective way to avoid layout shifts.
5. Font services: Adobe Fonts, Google Fonts and others
Hosted services still make sense when you want a large catalog, automatic licensing or a design team that picks fonts without touching code.
- Google Fonts is free and its families are open-source. You paste a
<link>or@import, and Google serves the right files. The catalog is far bigger than it was in 2011 and includes many variable fonts, so the old complaint of too few weights no longer applies. - Adobe Fonts, the service that grew out of Typekit, is included with Creative Cloud plans and delivers fonts through a CSS link to a kit you configure.
- Foundry hosting from commercial type vendors gives you their newest releases with their own usage-based pricing.
- Services that disappeared. Fontdeck, which the original article recommended, closed in 2016 after announcing the shutdown the year before. A third-party host is a dependency that can vanish.
The trade-offs are the same as before: an extra connection to another origin, less control over caching, and a privacy question, since your visitors’ browsers contact the provider. If you use Google Fonts but want local control, download the files and self-host them under their open licenses.
Which approach to choose
| Situation | Choose |
|---|---|
| Marketing site or app where speed and privacy matter | Self-hosted WOFF2 with font-display and a preload |
| Prototype or client site with a free font | Google Fonts link, then self-host before launch |
| Team already using Creative Cloud | Adobe Fonts kit |
| A licensed commercial typeface | Foundry-supplied WOFF2, self-hosted if the license allows |
A short checklist
- Use WOFF2 only; drop EOT, TTF, SVG and WOFF fallbacks.
- Prefer one variable font over many static files.
- Set
font-displayon every@font-facerule. - Define an adjusted local fallback to reduce layout shift.
- Subset by script with
unicode-range. - Preload only the above-the-fold font, with
crossorigin. - Confirm the license permits web embedding.
Font loading is one part of page speed; for the rest see How to Speed Up Your Slow WordPress Website. Once your pipeline works, browse the fonts in 30 Free Fonts For Creative Projects, or try type effects with CSS Animated Text Effects.
I was using @font-face, but I switched to Google Fonts. Since version 2 it has much more fonts to choose from and the performance is much better.
Also with @font-face, I had some browser issues that were not solved at the moment I needed to use the font. I think Google Fonts is safer regarding browser compatibility, am I right?
I also think Google fonts is the way to go, they do have a nice selection of typefaces right now. Very few fonts have more than 2-3 weights but that’s basically the norm with free fonts. It’s also a nice ice-breaker for type designers that want to submit their first fonts somewhere.
As long as you don’t necessarily need some very specific commercial typefaces, Google fonts kicks ass.
I’m also Google Web font user. But as poster said it has limited offer of fonts library. Especially my country uses Russian like Cyrillic. I found only one font named “PT Sans Narrow”, that has all our language characters.
I agree with what several people have already said, Google Web Fonts seems to be the way to go for free, reliable font service. Their selection has been growing and while you only get a few weights for each font, it is free.
Give Fonts.com Web Fonts ( webfonts.fonts.com ) a look for more than 12,000 Web fonts including the big name typefaces such as Helvetica, Frutiger, Univers and many others. @Gerelt there are 410 Cyrillic fonts currently available in the service. Free option as well.
I thought you should be aware that there are a few other web font services out there, including Webtype, WebInk and our service Fonts.com.
We are proud of the fact that we now have over 12,000 commercial fonts available for use on the web. These include name-brand fonts such as Helvetica®, Frutiger®, Gill Sans®, Univers® and many more. One benefit of the service not mentioned is that when we enhance a font and make improvements to how it displays on-screen, it is then automatically made available to subscribers. Additionally, something not mentioned is that there is a self-host option available for those larger sites who prefer to control all their site assets.
I use google web fonts for all of my custom blog themes and I love it. I’m also excited to see them adding new fonts pretty regularly, and I’m very impressed with the revamped website.
I think it’s important to point out that @font-face was in the CSS2 spec also, but was removed from CSS2.1. It’s also supported by IE6, although you need another font format, but at least it’s supported.
Fully support @font-face
If you work on a site that has 10’s of thousands of page views a day Typekit is NOT the way to go. For them to track font usage they don’t cache the font so it has to pull the font on every page load.
TypeKit is great for smaller sites that don’t generate tons of traffic.
Cufon used to be great, but let’s face it, it’s not a match for real browser-rendered fonts with @fontface. Besides, the loading time of a page containing Cufon is dramatically slower than it is with @fontface. Time to step forward and be grateful for what delight it used to be, but fall in love with new and better technology :)
Until we have better anti-aliasing on Windows, Cufon is the only way for me. It’s hard to justify using a non-standard font because it looks better when in fact it looks terrible.
Cufon actually looks good regardless of your browser and OS, because it doesn’t rely on browser anti-aliasing to smooth out the pixels.
Spot on Chris. Exactly what I have found. I will give up a little performance for something that looks fantastic in all browsers. The goal is to have a happy medium, but the designer in me cannot let the windows fonts pass.
I would agree with your statemen however you can use the text-shadow property to good effect. By utilising this proerty as the same coour code as your font it can smooth it out providing its 1px.
Thats the method i have adopted and used for quiet some time. The only downside was the lack of support it once had which now is pretty much widely supported.
Thanks a ton! I was just wandering around for the very information. Your article just fed me with the sufficient knowledge about custom @font-face fonts. Thanks again :)
Doesn’t anyone else get horrible aliasing under Windows based browsers (yes, even on Chrome and Firefox)? Even more-so when using Google’s hosted fonts?
we miss your judgement on Cufon – – –
Cufon is font/image replacement. It doesn’t consider @font-face solution.
I use Typekit, they provide a great service however, i think that @font-face would be the better choice if you do not want to subscribe.
really nice article and brilliant work and this will help us .
I have found that sometimes the cufon alternative is better
At our company we use Cufon. The only downside about using it is that the end user can’t mark the text because it’s pictures. Anyway I think that you no matter what should be carfull using speciel fonts for text. I recemend to use it in headers and so and not for reading text that people might want to mark. :-)
Ok, but the cufón is heavy, one font 1 or 2 MB. This service is easier then cufón.
The stability is key point; I will not consider Font Service Providers
I have found that using cufon is the only bullet proof solution to having fonts render identical no matter the browser or OS. But it is very heavy.
@font-face or any of the options above are great if you can get past the crappy rendering that PC’s give you. Historically, depending on the font itself, I have not been happy with how my custom font choices look on a windows machine. But I am biased.
I personally have some problems with embedded fonts while they undergo a CSS Animation. Seems that CSS still needs more refinement, so that their different parts can work together, not just separately.
I’ve had trouble using the @font-face method. However, it is less code heavy from Cufon. These browsers are going to have to get some consistency in rendering the CSS3 @font-face properties. Anyway, thanks a lot for sharing.
I am a beginner in web designing. And I am not well in it. I can not design font face in wordpress. Here I have got a great solution.
It’s available and auto on Blogger. Just for WP.
i love using font-face, not fan of cuFon and so on…
Nice post! I’ve mostly been using font squirrel, although I think I’ll give Google Web Fonts a try now.
First and foremost, I think you need a help of a psychiatrist
Is there a way to deliver to a specific browser?
I have problems with font-face in FF4 on PC, all the other browsers are fine…
So, is there a way to serve FF4 with for example Cufon, or a general font?
Hi,
I recently embedded a font using @font-face and the Mac rendered the font differently to a PC. It displayed it thicker and bolder.
Has anyone else had this issue, whilst using @font-face? In the end I had to resort to using Cufon instead.
I think cufon isn’t a great solution, if you want to get your website future-proof. The future of web standards (embedding fonts) really lies in @font-face, instead of finding a way to hack around it…
After several trials with @font-face I still rely on cufon because it is backward compatible, and it is graphically much more beautiful than @font-face. The only problem is cufon forward compatibility… They update oftenly but you should followup carefully…
CUFON is great for large scale headline fonts, but its just not feasible for smaller font sizes, since it changes the text to PNG on the fly. I like @font best, but tend to use online font services more so I dont have to worry about breaking EULA on the fonts we use here.
With Google Webfonts, there are many more options than there used to be. Google just updated the Google Webfont interface, and added many, many new fonts. Many don’t have multiple weights, but most body copy fonts have regular, bold, and italic.
I still use Google Webfonts as my first stop for selecting fonts. If I can’t find any there, I will use FontSquirrel fonts. I hate all those paid webfont subscriptions, and try to avoid them. There are enough decent free webfonts. Why pay a subscription when clients don’t like extra charges?
Google sounds like the best option…to have to install the fonts on your own server for every website seems like it could be time consuming. I’m sure, as CSS continues to evolve, we’ll see more solutions to this web design challenge.
Hi there!
This solved a big issue on my site.
I was using cufon and transform (skew) effect, but its not working in IE8 and IE9. I searched a lot for another solution, and this helped me!!!!!! :)
BTW, is there any solution to using cufon and transform effect together [e.g. I am using: skew(0deg, -10deg)] ??
Please reply back if any solution is there.
Thanks a ton!!!!!!!!
I’ve always been weiting for something like google web fonts. Your single con is obselete: Google got already 238 fonts online, and it’s growing fast and constantly.
We used font squirrel quite a bit until we realized we had some inconsistencies with the way IE fonts were created, example they would have padding on the top of them.
Interesting summary. I’ve never used Google fonts, I’ll have to check it out
Is the following code wrong..??
@font-face {
font-family: “myfont”;
src: url(“../myfont.ttf”);
*src: url(“../myfont.eot”);
src: url(“../myfont.eot”)\9;
}
where “*” is the working for IE7 and “/9” for IE8. I haven’t worked for IE9 but the above code is working on all browser in my case.
Autson is an outstanding name in the field of web design, web development, and experts in Internet marketing. We are providing innovative and creative web development and designing solutions which ensure your strong online business presence as well as gave you a way to expand your business.
Cufon was good at one point, now I just keep it simple :)
A nice tip to use fonts with every browser for webdesigners (diseñadores web en méxico), thanx to the team of wdw…
Thanks for this very comprehensive post. I’ve used cufon in the past to install fonts, which was javascript based, but I was aware of @font-face and also Google Web Fonts, which are both great tools.
Font Squirrel is amazing for font-face. A great selections of copyright free fonts. You can download kits with all fonts formats (svg, otf, etc) and a css file. It’s dead easy. You can even create your own kit if you know of to create fonts.
https://www.fontsquirrel.com/
I love it
I ‘ve just studied CSS3.I like your tips.thank for font face css guide.
The major papers reported today about exploding obesity rates. Especially for children in Australia and the US. There was no suggestion anywhere of a solution to the problem, except for surgery. Is there a solution?
We quite like the Cufon font, but are looking more towards the “Apple” font as it’s clearer and easier to read for our visitors! Thanks for the article though!
Nice article. I have to have a better look in to which fonts I want to use on my web designs in the future and this article gave me some good ideas. Thanks
This does look like a great theme.hloer
I will be trying this on my next project.
I’ve been looking for something for information on font face kits and typography. I found this one about general typogaphy, but its more gear towards standard web safe fonts