Also available in: Español · Português · Français · العربية
font-display: what swap, block, fallback and optional really do
Pick a value and a download time, and see the exact moments text is invisible, falls back, or switches to your font.
What font-display controls
A web font takes time to arrive, and the browser has to draw the text before it does. font-display is the descriptor you put inside an @font-face rule to say what should happen in the meantime: hold the text back until the font is ready, show it immediately in a fallback and swap later, or give up on the font entirely if it takes too long. The five values are auto, block, swap, fallback and optional, and auto is the initial value.
Underneath, the specification describes a download timer running through three periods. During the block period, an element using the font must render with an invisible fallback face. During the swap period, it renders with an ordinary fallback. When the failure period begins, an unfinished download is marked as failed and normal font fallback applies for good. Each font-display value is simply a choice of how long the first two periods last.
The invisible part is more interesting than its reputation suggests. The specification does not say the text is missing — it says the browser creates an anonymous font face with the same metrics as the real one but with every glyph invisible. The space is already reserved at the right size, so when the font lands nothing reflows. The flash of invisible text is a flash of blank space that is exactly the right shape.
How to use it
- Pick a value and a download time. The time is in milliseconds from when the browser starts the timer. The sample buttons cover a font that is downloaded and then discarded, one that shows all three renderings in turn, one that holds the text back, and one that is never swapped in at all.
- Read the timeline. Each row is a stretch of time and what a reader sees during it — blank space, a fallback face, or your font. The outcome line underneath says plainly whether the font is ever shown.
- Change the periods. The three duration fields are editable on purpose, because the specification recommends those figures rather than requiring them. Set the block period to zero — the specification's own example of something a browser might let a reader do — and watch the invisible phase disappear.
Every number in the usual table is a recommendation
Search for font-display and you will find the same table everywhere, with 3s and 100ms in it as though they were fixed. They are not, and the specification is unusually careful about saying so. block gives a short block period, with 3s recommended in most cases. swap gives an extremely small block period, with 100ms or less recommended in most cases. fallback combines the two. Those are the only two numbers in the whole descriptor, and both are hedged in the same words.
Then there is a note covering all five values at once: browsers may use slightly different durations, or more sophisticated behaviours that cannot be expressed in the syntax at all. And it goes further, saying browsers may let a reader override what the author chose — with the example given being forcing every font to have a zero-second block period. So the numbers are advisory twice over: the browser need not follow them, and the reader may overrule them.
That is why this page lets you edit them rather than printing them as constants. Setting the block period to zero removes the invisible phase entirely and text appears immediately in a fallback; lengthening the swap period rescues a font that the recommended figure would have thrown away. Neither of those is a hypothetical — both are behaviours the specification explicitly permits.
auto is the honest extreme of this. Its entire definition is that the font display policy is user-agent-defined. The specification adds only that many browsers default to something similar to block, which is an observation about the world rather than a rule. If you write auto, or write nothing at all, you have not chosen a behaviour.
optional has no periods at all
Every copied table gives optional a block period and a swap period. The specification gives it neither. It defines the value by outcome: if the font can be loaded immediately, meaning it is available for the first paint of the text, the font is used; otherwise the font is treated as if its block period and swap period had both already expired.
What follows is a pair of hard rules rather than durations. An optional font must never cause the layout of the page to jump as it loads in, and once the text has been painted with a fallback it must not be rendered with the optional font for the rest of the page's lifetime. Not later in the session, not on the next paint — the font is out. That is why the optional scenario on this page shows a single unchanging row: no phase change means no jump, which is the whole point of the value.
The browser is also given unusual latitude here. It may abort the download once it decides the font will not be used, may download it with very low priority, and if it believes that would serve the reader better, may avoid even starting the download and go straight to a fallback. In practice that usually means a font declared optional is fetched on the first visit, ignored, and used from cache on the second.
The practical reading is that optional is not a stricter fallback. It is a different promise: this font is a nice-to-have, never delay or disturb the reader for it. Choosing it means accepting that some visitors will simply never see your typeface.
What this will not tell you
It simulates the rules; it does not measure your site. The download time is the number you typed, not one observed over a real network, and nothing here fetches a font. To find out how long yours actually takes, use your browser's network panel — and remember that the timer starts when the browser first attempts to use the face, which is not when the stylesheet loads.
Because the durations are recommendations, the timeline is what a browser following them would do rather than what yours will. A browser using different figures, applying a more sophisticated policy the syntax cannot express, or honouring a reader's override will behave differently while remaining entirely conformant. That is a fact about the descriptor rather than a limitation of this page, which is why the durations are editable.
Two things sit outside the model. The specification permits a browser to slightly delay rendering an element using an optional font, to give a possibly-slow local cache time to answer, and it does not say by how much — so the window this page uses for immediately is a stand-in rather than a quoted figure. And font loading interacts with preloading, the CSS Font Loading API and the priority a browser assigns to the request, none of which is simulated here.
Finally, this is about one font face. A page with several faces in one family runs several of these timers at once, and what a reader sees is the combination — including the case where a fallback is swapped out for one weight but not another.
Why is it free?
Working out a timeline from a few numbers runs in your browser. There is no server in the loop, so there is nothing to bill for and no account to create.
Nothing is uploaded and no font is fetched. Reload the page and it has forgotten what you typed.