In a CSS @font-face rule, how do the font-display values block, swap, fallback and optional differ in terms of the block period and the swap period?
answer
- two windows, then give up
- block period paints nothing
- swap period accepts a late arrival
- one value has no swap window
- clock starts at the request, not navigation
basics
~20 sEach value sets two windows. block gives a short blocking window then swaps whenever the font lands; swap blocks for almost nothing and swaps at any time; fallback blocks briefly and swaps only within a short window; optional blocks briefly and never swaps on that load.
solid answer
~50 sThe timeline for a face has two periods that start when the browser first tries to use it. During the **block period** text is laid out but painted invisibly; during the **swap period** the fallback is painted and the web font is still accepted if it arrives. After both, the fallback is kept for the rest of the load. `block` uses a short block period — around three seconds in practice — and an unlimited swap period. `swap` uses a near-zero block period, about a tenth of a second, and an unlimited swap period. `fallback` uses the same near-zero block period but only a short swap period, so a font that arrives very late is ignored for that load. `optional` uses the near-zero block period and no swap period at all: the font is used only if it is effectively ready, otherwise the file is just cached for next time. `auto` leaves it to the browser and behaves like `block` today.
code
css · 13 lines@font-face {
font-family: "Brand";
src: url("/fonts/brand-400.woff2") format("woff2");
font-weight: 400;
font-display: swap;
}
@font-face {
font-family: "Brand";
src: url("/fonts/brand-700.woff2") format("woff2");
font-weight: 700;
font-display: swap;
}go deeper
Know the four named values and that each one decides how long text stays invisible and how late an arriving font is still allowed to change the page.
Be ready to draw the block-period-then-swap-period timeline, state which value gives an unlimited swap window, and explain that optional has none at all.
Demonstrate that you know the clock starts at the font request, so a display value cannot rescue a font discovered late, and that cached fonts hide all of this in local testing.
Frame the four values as a policy question about acceptable first-visit experience, and be able to defend a per-role default across a component library rather than a single blanket setting.
## The two periods The font-display timeline is defined per font face and starts at the moment the browser first *attempts to use* that face — which is when it issues the request, not when the navigation started. That detail matters: a font discovered late in the load starts its clock late, so its windows run past the point where the user is already reading. From that instant the face passes through up to three states: - **Block period.** The face is not available. Text using it is laid out but painted with an invisible fallback — the space is reserved, no glyphs are drawn. This is the flash of invisible text. - **Swap period.** The face is still not available. Text is painted with a real fallback family, and if the web font arrives during this window the browser repaints with it. - **Failure period.** Both windows have elapsed. The browser keeps the fallback for the rest of the page load and treats the face as unavailable, even if the file eventually finishes downloading. ## What each value sets | value | block period | swap period | practical result | |---|---|---|---| | `auto` | browser's choice | browser's choice | today's browsers behave like `block` | | `block` | short (~3s) | infinite | invisible text first, font always wins eventually | | `swap` | extremely small (~100ms) | infinite | fallback first, font always wins eventually | | `fallback` | extremely small | short (~3s) | fallback first, very late font ignored this load | | `optional` | extremely small | zero | fallback for the whole load unless the font is basically ready | The exact durations are not fixed by the specification — it calls them "short" and "extremely small" and leaves browsers to pick. The values above are what mainstream engines use in practice, and the *shape* of the behaviour is what an interviewer is checking, not the millisecond count. ## Reading the table as three decisions Ask two questions and you can derive any value. First: *may the reader wait in the dark?* If yes you want a real block period, which only `block` (and `auto` by proxy) gives. Second: *how late is too late to change the page?* `swap` says never too late; `fallback` says a few seconds; `optional` says immediately too late. ```css @font-face { font-family: "Brand"; src: url("/fonts/brand.woff2") format("woff2"); font-display: fallback; /* brief FOIT window, then a limited chance to swap */ } ``` ## Why optional is qualitatively different `optional` is the only value that can result in the font being downloaded and then *not used*. Its zero swap period means the browser decides once, very early, and sticks with the decision. The download still completes and enters the HTTP cache, so the second navigation typically renders in the web font immediately with no swap at all. That is the trade it offers: a first visit that may look generic, in exchange for never restyling a page mid-read. ## Things people get wrong The periods do not run from navigation start, so "three seconds" is not three seconds of page load — it is three seconds after the request began. A cached font usually resolves within the block period on repeat visits, which is why the descriptor's effect is nearly invisible in local development where every asset is warm. And the descriptor is per face: mixing `swap` on the regular weight with the default `auto` on the bold weight produces a page where body copy paints instantly and headings stay blank, which reads as a rendering bug. ## A quick sanity check If you want to *see* the behaviour, throttle the network hard and disable the cache before reloading. Without both, the font arrives inside the block period every time and all five values look identical.
- When exactly does the font-display timeline start counting?When the browser first attempts to use the face — effectively when it issues the font request. It is not measured from navigation start. So a font whose request begins two seconds in still gets its full block and swap windows from that point, which is why late discovery and the display policy are separate problems.
- What is the difference between fallback and optional in the outcome a user sees?Both paint the fallback almost immediately. With `fallback` a font arriving within roughly a three-second window still swaps in, so a moderately slow connection eventually gets the brand face. With `optional` there is no swap window at all: unless the font is effectively ready at that first decision, the load renders entirely in the fallback.
- Why do all the values look the same when you test locally?Because a locally served or cached font resolves inside the block period, so the browser never enters the swap or failure states. To observe real differences you need heavy network throttling with the cache disabled — otherwise every value produces the same instant render.
saying these in an interview costs you the question
- Says the periods are measured from navigation start
- Thinks fallback and optional behave identically
- Claims block hides text until the font arrives, forever
- Believes the durations are fixed by the specification
- Assumes one font-display covers every weight of the family