R3.13.1FOIT versus FOUTdesign

Invisible text and swap-flash are two ends of one tradeoff

Aliases: FOIT · FOUT · font-display · flash of invisible text · flash of unstyled text

What it is

While a custom font is still on the wire, the browser has two legal pictures of existing text: paint the glyphs transparent and reveal them when the face arrives; or paint immediately in a fallback face and swap when the face arrives. The first is FOIT (flash of invisible text); the second is FOUT (flash of unstyled text). font-display values block / swap / optional only pick a point on that axis and add a timeout. There is no third default path in which text is instantly readable and never changes glyph — unless the font is already cached.

This is the pair of costs during the wait — blank versus flash — not which flash form a loading strategy selects, and not reflow from fallback-versus-webfont metric mismatch.

Why it happens

Text nodes still have to paint before the face is ready. The engine either withholds the foreground (visibility zero; boxes may still take space) or paints a fallback. block lengthens the FOIT window and shrinks the chance of a swap, but for that stretch the words are invisible: reading and hit targets are empty. swap FOUTs immediately — readable — then weight, width, and glyph shapes change, which yanks the eye to "the type just jumped". optional gives a very short block and then stays on the fallback forever: "may never be the brand face" in exchange for "almost no flash". The ends exclude each other: shorten invisibility and the swap gets louder; forbid swapping and the invisible window must grow, or the brand face must be abandoned.

A timeout does not create a third state; it jumps between the ends. On a slow network, block's cap still falls through to swap or fallback, so the user gets a blank and then a swap — both costs stacked on one load. Cache hits collapse both ends to "no wait"; a cached session cannot prove the strategy does not flash.

Where it stops holding

System UI fonts and user-installed faces have no wait; the tradeoff does not arise. Icon fonts fail by leaving characters behind — do not describe that with FOIT/FOUT. A variable font that ships many weights in one file reduces tearing ("this weight still FOIT while body already FOUT") but the first packet is still on the axis. preload shortens the wait; it does not delete the axis — it only makes the chosen point land on "already cached" more often. Print and PDF need embedded fonts; there is no runtime flash. For long copy already being read, a mid-article swap hurts more than a first-paint FOIT; body and headings may pick different points.

Applying it

  • Decide which end this text cannot afford: navigation and buttons prefer readable (toward swap / optional); brand headings may take a short block, with a timeout cap.
  • Pick the point explicitly on font-display; do not rely on the engine default. Do not demand "visible at first byte" and "never swap glyphs" without a cache hit.
  • preload critical faces so most sessions skip the wait; still accept against a cold cache.
  • How to check: cold-cache on a slow network, frame by frame: is the wait blank or fallback, and at which second does a swap occur? Compare a cache hit. Overlay the two recordings and confirm the chosen point matches the end the product can live with — not both ends stacked.

Related

  • Same group: R3.13.2 Faux-bold and faux-italic change how text can be read · R3.13.3 Failed icon fonts leave meaningless characters
  • Nearby: R3.06 Font Loading
  • Search terms: FOIT · FOUT · font-display · flash of invisible text

Cards in the same group

Quick Actions

Share

Share this page

ios_share

https://hci.top/en/handbook/R3.13.1