
The History of Web Typography: From Web-Safe Fonts to Variable Fonts
- Sajjad
- Typography
- 01 Oct, 2026
If you built a website in 2005 and wanted a headline in your client's brand typeface, your options were a JPEG of the text, a Flash movie that replaced it, or a font stack of Verdana and Arial and an apology. Today you can load a single variable font file, set its weight to 640 and its width to 87%, animate its optical size, and have it render in every major browser. That shift took about twenty-five years, and many of the conventions you still use, from fallback stacks to font-display, are scars from the problems each era had to solve.
This article walks through the history of typography on the web in roughly chronological eras: plain text and the first browsers, web-safe fonts, image and Flash replacement, the arrival of @font-face and WOFF, font services and Google Fonts, the performance era, and variable fonts. For each, you'll see what was possible, why it worked that way, and which ideas survive in modern CSS.
A Timeline at a Glance
| Period | Milestone |
|---|---|
| 1991–1994 | The web is text in whatever font the browser chooses |
| 1995 | Netscape adds the font element with a face attribute |
| 1996 | CSS Level 1 introduces font-family with generic families; Microsoft launches Core Fonts for the Web |
| 1997 | Internet Explorer 4 supports embedded fonts in the EOT format |
| 1998 | CSS2 specifies @font-face, but cross-browser support doesn't follow |
| 2004–2009 | Image replacement, sIFR (Flash), and Cufón (JavaScript) work around the limits |
| 2008–2010 | Safari, Firefox, and Chrome ship @font-face with TTF and OTF files |
| 2009 | Typekit launches; WOFF is proposed |
| 2010 | Google Font API launches with a small set of open fonts |
| 2012 | WOFF 1.0 becomes a W3C Recommendation |
| 2016 | OpenType 1.8 introduces variable fonts |
| 2018 | WOFF2 becomes a W3C Recommendation; variable fonts ship in major browsers |
| 2019–2020s | font-display, preloading, metric overrides, and self-hosting become standard practice |
The sections below fill in the story.
The Early Web: Text Without Typography
The first browsers rendered pages in a font selected by the browser, and later by the user. HTML described structure, such as headings, paragraphs, and lists, and left presentation to the client. That was deliberate. Tim Berners-Lee's early web was a document-sharing system for researchers, and readers controlled how documents looked.
Designers wanted control, and browser vendors gave it to them in the bluntest way possible. In 1995, Netscape Navigator 2 popularized the font element, and its face attribute let you name a font:
<font face="Verdana, Arial" size="2" color="#333333">Welcome to our site</font>
This mixed presentation into every paragraph, multiplying markup and making redesigns painful. It also only worked if the reader happened to have the font installed. But the comma-separated list of fallbacks introduced an idea that is still central to CSS today: name your preferred font, then name the alternatives.
CSS and the Web-Safe Fonts Era
CSS Level 1, published as a W3C Recommendation in December 1996, moved typography into stylesheets with font-family, font-size, font-weight, line-height, and the generic families serif, sans-serif, monospace, cursive, and fantasy.
body {
font-family: Georgia, "Times New Roman", Times, serif;
}
The same year, Microsoft launched the Core Fonts for the Web initiative, distributing a set of fonts for free and bundling them with Windows and Internet Explorer. The set included Arial, Courier New, Georgia, Times New Roman, Trebuchet MS, Verdana, Comic Sans MS, Impact, Andale Mono, and Webdings. Georgia and Verdana, both designed by Matthew Carter with hinting by Tom Rickner, were made specifically for low-resolution screens, with generous x-heights, open spacing, and shapes that held up at small pixel sizes.
These became the web-safe fonts, the fonts you could reasonably assume were installed on most Windows and Mac machines. Microsoft ended the free download program in 2002, but the fonts remained installed on hundreds of millions of computers, and for most of the 2000s they defined how the web looked. Many sites set body text in Verdana at 11px, which was readable only because Verdana was designed for exactly that.
The habits from this era still matter:
- Fallback stacks are still how you protect against a font failing to load.
- Generic family keywords are still the final fallback in every stack.
- Screen-specific design, the idea that fonts should be made for pixels, lives on in modern UI typefaces and in the system fonts used by a system font stack.
Embedded Fonts That Didn't Catch On
Downloadable fonts were attempted surprisingly early. In 1997, Internet Explorer 4 supported embedding fonts in Embedded OpenType (EOT), a format with compression and domain-locking intended to satisfy foundries. Netscape 4 backed a competing technology, TrueDoc. Neither format worked in the other browser, tooling was awkward, and foundries were wary of distributing font software over the web.
CSS2, published in 1998, defined the @font-face rule for downloadable fonts. It was removed again in CSS 2.1 because of poor implementation, and it took about a decade to come back in a usable form.
Image Replacement, sIFR, and Cufón
With no reliable way to use real fonts, designers worked around the browser.
- Images of text. Headlines and navigation were exported as GIFs or JPEGs. They looked right, but they were heavy, couldn't be translated, selected, or resized, and were invisible to search engines and screen readers without careful alt text.
- CSS image replacement. Techniques like the Fahrner Image Replacement and later the Phark method hid real HTML text, often with a large negative
text-indent, and showed a background image instead, keeping text in the markup for search and accessibility. - sIFR (Scalable Inman Flash Replacement). Around 2004 to 2005, sIFR used JavaScript to replace headings with tiny Flash movies that rendered the text in an embedded font. It was clever and widely used, but it depended on the Flash plugin, flickered on load, and was slow.
- Cufón and Typeface.js. Around 2008 and 2009, these libraries converted fonts to vector paths in JavaScript and drew them with canvas or VML. They were faster than Flash, but the text wasn't selectable in the normal way, and the approach raised licensing concerns because it effectively redistributed font outlines.
Each technique made the same point: designers needed real fonts, and the web had to find a way to deliver them that browsers, foundries, and users could all accept. One lasting lesson from this era is formalized in WCAG 1.4.5, which asks you to use real text rather than images of text wherever possible.
@font-face Returns and WOFF Arrives
Between 2008 and 2010, browsers shipped @font-face with support for raw TrueType and OpenType files: Safari 3.1 first, then Firefox 3.5, then Chrome. Internet Explorer still required EOT. For a few years, cross-browser font loading required the famous "bulletproof" syntax, popularized by Paul Irish, that listed several formats:
@font-face {
font-family: "MyFont";
src: url("myfont.eot");
src: url("myfont.eot?#iefix") format("embedded-opentype"),
url("myfont.woff") format("woff"),
url("myfont.ttf") format("truetype"),
url("myfont.svg#myfont") format("svg");
}
The SVG font format was there for early iOS Safari. Converters like the Font Squirrel generator produced all of these formats from a single file.
Raw TTF and OTF files had a problem: they were exactly the same files people installed on desktops, so serving them made unlicensed copying trivial. In 2009, Jonathan Kew, Tal Leming, and Erik van Blokland proposed WOFF (Web Open Font Format), a wrapper that compressed font data and included space for licensing metadata. It wasn't DRM, but it marked web fonts as distinct from desktop fonts, which reassured foundries enough to start offering web licenses. WOFF became a W3C Recommendation in 2012, and WOFF2, using Brotli compression for significantly smaller files, followed in 2018. Today the bulletproof syntax has collapsed to a single line, as covered in WOFF2 vs. WOFF vs. TTF:
@font-face {
font-family: "MyFont";
src: url("/fonts/myfont.woff2") format("woff2");
font-display: swap;
}
Font Services and Google Fonts
Even with @font-face working, licensing and hosting were obstacles. Font services solved both.
- Typekit launched in 2009 as a subscription service that hosted fonts from multiple foundries and delivered them with a JavaScript snippet. Adobe acquired it in 2011, and it later became Adobe Fonts.
- Fonts.com, Fontdeck, Webtype, and other services offered similar models.
- The Google Font API launched in 2010 with a small collection of open-source fonts. Google Fonts grew into a library of well over a thousand open-licensed families, served for free from Google's CDN.
Google Fonts changed the default look of the web. Open Sans, Roboto, Lato, Montserrat, and Source Sans became as ubiquitous in the 2010s as Verdana and Georgia had been in the 2000s. It also normalized open licensing: most of its fonts use the SIL Open Font License, which allows commercial use, modification, and self-hosting.
The Performance Era
As fonts became common, their cost became visible. Pages loaded multiple families and weights, often hundreds of kilobytes, and browsers handled loading inconsistently. Some hid text until fonts arrived, the flash of invisible text (FOIT), while others showed fallback text and then swapped, the flash of unstyled text (FOUT).
The 2010s produced a toolkit to control this:
- The Font Loading API,
document.fonts, let JavaScript detect when fonts loaded. font-display, broadly supported by around 2019, gave CSS control over the block and swap periods with values likeswapandoptional.- Preloading with
rel="preload"let browsers discover critical fonts earlier. - Subsetting and
unicode-rangereduced file sizes by shipping only needed characters. - Metric overrides like
size-adjustandascent-overridearrived in the early 2020s to match fallback fonts to web fonts and reduce layout shift, which Google's Core Web Vitals had made a measurable concern. - Self-hosting became more common, partly because browsers began partitioning their HTTP caches by site around 2020, removing the shared-cache benefit of third-party font CDNs, and partly because of European privacy rulings about loading fonts from third parties.
Frameworks now bundle much of this. next/font self-hosts fonts and generates metric-matched fallbacks at build time, and the WordPress Font Library downloads fonts into the site. The full story of loading behavior is in FOUT vs. FOIT.
Variable Fonts
In 2016, Adobe, Apple, Google, and Microsoft jointly announced OpenType Font Variations as part of OpenType 1.8. A variable font contains one or more design axes, such as weight, width, slant, or optical size, and can produce any position along them from a single file.
Browsers shipped support around 2018, and CSS exposed it through existing properties and the low-level font-variation-settings:
@font-face {
font-family: "Body";
src: url("/fonts/body-var.woff2") format("woff2");
font-weight: 100 900;
font-stretch: 75% 125%;
}
h1 {
font-weight: 640;
font-stretch: 87%;
font-optical-sizing: auto;
}
The idea itself is older than the web font era. Apple's TrueType GX in the early 1990s and Adobe's Multiple Master fonts offered interpolated designs, but neither achieved broad adoption. What made variable fonts succeed in the late 2010s was that every major platform vendor agreed on one format, browsers implemented it quickly, and WOFF2 compression made the files practical.
Variable fonts finally gave the web something print never had: typography that can respond continuously to screen size, user preferences, and interaction. Learn the details in what variable fonts are and why you should use them.
What the History Teaches
Looking back, a few patterns repeat:
- Users and browsers have always had a say. From the first browsers to modern zoom, user font overrides, and WCAG 1.4.12 text spacing, web typography has to tolerate changes it doesn't control.
- Fallbacks never went away. The comma-separated list in the 1995
fontelement is the same idea as today's metric-adjusted fallback stacks. - Licensing shaped technology. EOT, WOFF, and font services all existed partly to satisfy foundries.
- Workarounds become standards. Image replacement led to the demand for
@font-face; FOUT hacks led tofont-display; responsive type hacks led toclamp()and variable fonts.
Web Typography History FAQ
The core set came from Microsoft's Core Fonts for the Web project in 1996, including Arial, Courier New, Georgia, Times New Roman, Trebuchet MS, Verdana, Comic Sans MS, Impact, Andale Mono, and Webdings. They were widely installed on Windows and Mac, so designers could rely on them.
Around 2010. Safari, Firefox, and Chrome added font-face support for TrueType and OpenType files between 2008 and 2010, and Internet Explorer had supported EOT since version 4. Cross-browser syntax required several formats until WOFF became universal.
sIFR, or Scalable Inman Flash Replacement, was a mid-2000s technique that used JavaScript to replace HTML headings with small Flash movies rendering text in a custom font. It kept the real text in the HTML but depended on the Flash plugin and was eventually replaced by native web fonts.
WOFF wrapped and compressed font data and allowed licensing metadata, which made web fonts smaller and clearly distinct from installable desktop fonts. That reassured foundries enough to license fonts for the web, and it became the standard format.
OpenType Font Variations were announced in 2016 as part of OpenType 1.8 by Adobe, Apple, Google, and Microsoft. Major browsers shipped support around 2018, and variable fonts are now common across font libraries.
Yes, mainly as fallbacks. Fonts like Arial and Georgia still appear in fallback stacks and in metric override rules that make fallback text match web fonts. System font stacks are the modern descendant of the web-safe idea.
Conclusion
Web typography went from no control at all, through a narrow set of web-safe fonts and a decade of image, Flash, and JavaScript workarounds, to universal @font-face support, WOFF2 compression, open font libraries, and variable fonts that adapt continuously. Each step solved a problem the previous era couldn't: availability, licensing, file size, rendering behavior, and finally flexibility.
Knowing the history makes modern practice easier to understand. Fallback stacks, font-display, metric overrides, self-hosting, and variable axes all exist because of specific problems designers and browser makers fought through. The tools are better than ever, and the principles that carried through every era still apply: respect the reader's control, plan for failure, and use real text.
Here are some useful references for going deeper on the history of web typography:
- W3C: WOFF File Format 2.0 — the specification for the modern web font format.
- W3C: Cascading Style Sheets, level 1 — the 1996 specification that introduced font-family and generic families.
- MDN Web Docs: @font-face — today's syntax and browser behavior for downloadable fonts.
- Microsoft Typography: OpenType Font Variations overview — the technical foundation of variable fonts.
- web.dev: Introduction to variable fonts on the web — how variable fonts work in modern browsers.


