Type on the Web: Choosing Two Fonts and Making Them Behave
How to Choose Web Fonts and Make Them Behave on Load
Most designers have experienced that sinking feeling: you painstakingly pick a sans-serif/serif font pairing that looks great in desktop lettering software, create meticulous responsive typographic styles, and celebrate as you ship a beautifully readable design. Then, deep in a browser audit, you realize that for vital seconds—maybe on a crucial page load—visitors on slow connections are seeing blank space instead of key headlines and paragraphs. That's FOIT (Flash of Invisible Text), and it can break user flows and kill conversions. Worse, it’s the default behavior of most modern browsers when loading custom web fonts.
The problem is that FOIT happens when text content is ready to display but the custom web font hasn’t downloaded yet. Browsers keep that text hidden until the font is ready, which means users see nothing at all for seconds. The opposite effect, FOUT (Flash of Unstyled Text), happens when browsers render text in a system fallback font immediately, then swap to the web font later when it’s ready. Google Chrome, Firefox, Safari and other modern browsers actually do FOIT for around 3 seconds by default, then switch to FOUT if the custom font is still not available, to avoid an all-blank page.
That means any web font choice that doesn’t explicitly control FOIT/FOUT loading behavior could fail on some devices and connections, and leading performance tools now explicitly instruct designers and developers to avoid FOIT. Tools like Google’s Chrome Lighthouse audit recommend using the font-display: swap CSS property on the font face declaration, or parameters like &display=swap added directly to the font provider URL, to ensure text remains readable while the custom font is downloading. What these experts are saying is: blink, and you’ll miss the font. You must choose two fonts for your web type stack, but those may not be the only fonts that viewers ever see.
There’s no avoiding that custom web fonts introduce a trade-off between file size and performance. The larger and more complex the type, the heavier the download, especially at text-heavy resolutions. Extended families with many weights, styles and language glyphs bring the most performance pain. But you can mitigate FOIT and FOUT with performance-oriented font-display value choices that push browsers to render fallback text immediately.
Rendering fallback text as soon as possible, and only swapping it out later, gives users a readable web page on the critical path, which boosts conversions, leads, and the bottom line. font-display: swap is widely recommended as the fix—it allows text to be shown using a fallback system font (e.g., Helvetica, Arial, sans-serif) immediately, and if the custom font makes it to the page before the end of the swap phase, it replaces the fallback. If the web font fails to load within that window, the user reads the fallback text for the whole session.
That fallback text is the free performance insurance you get with the web’s built-in typefaces, and they shouldn’t be ignored. People accustomed to digital design might forget that a massive number of web visitors are using devices built in the mobile-first era, and may not have the computing power to download and render custom fonts quickly—or it may not matter because those devices run on tiny data plans that require every font byte to count.
Because of that, leading design systems like GitHub Primer rely on system font stacks as the backstop—their UI typefaces use native system font families as a critical fallback. Their design repo states that each font stack uses system fonts, which are “optimized for performance,” and the Primer guidance on typography makes it clear that not every brand font needs a blurry or blank “loading” state.
Designers have a duty of care to use these well-engineered system fonts to provide an experience that boots as fast as possible, while also giving users the benefits of web fonts in the right display contexts. That means your type stack isn’t really two fonts—it’s two custom fonts (if that’s your choice) and a handful of powerful fallback typefaces that make your customer experience stable.
Approach web typeface selection as specifying a complete loading and fallback stack. For example, you might choose a bold sans-serif like Overpass for headings, but if that fails to load in the swap period, deliver the text in a similar font like Helvetica. For body text, you might prefer a serif like Playfair Display, but if that doesn’t make it in the time allowed, render it in a fallback like Times. The best approach is to make your font choice system-optimized and well-up-front, but not all-or-nothing.
Setting the font-display property to swap is the everywhere switch for web fonts on bigger sites. For heading designs in particular, FOIT was common and costly, because critical page elements were loading without content. It’s disappearing gradually, but skull-tough sites still use font-display: block for critical text, which hails a reversion to invisible text until the custom font loads, then does a late swap. That’s an edge case for high-drama pages but it’s the last remaining goalpost in the FOIT/FOUT race.
As a designer, you don’t need to have this data in your head, but you do need to understand it enough to know that designers and developers work together to specify concrete text loading and fallback settings for the entire UI typing family. Designers control the visible switching between custom and system fonts, and developers write the browser-side code that makes it happen.
To design a font stack that rolls out exactly as expected, specify font-display: swap for the entire site markup, then pinpoint heading styles that need to switch directly to font-display: block. Finally, choose your two branded type families, and ensure that each one has a fallback font that gives customers the info they need while the custom font loads.
This isn’t free—lexical and typographic designers still have an important job to do, even if their customers are reading a system font for the first few seconds. But the days of an all-or-nothing “font stack” are over. Smart mobile development uses the browser’s built-in system font access to avoid FOIT, and specify FOUT that customers never notice and happy developers prize on their audit scorecards. The right balance of customer experience and brand expression is simply a performance-based choice.