How to preview every step of a variable font's wght axis in one view
- Step 1Upload your variable font — Drop a TTF, OTF, WOFF, or WOFF2 file. The viewer decompresses WOFF/WOFF2 to an sfnt buffer and parses the `fvar` table. One file at a time — this tool is single-file (`multiFile: false`).
- Step 2Confirm it has a weight axis — The viewer looks for an axis tagged `wght` in `fvar`. If your font has axes but no `wght` (e.g. only `opsz` or `slnt`), the viewer falls back to a single 'Static' row at `font-weight: 400` — see the edge cases below.
- Step 3Set a sample string (optional) — The **Sample text** textarea defaults to `The quick brown fox`. Replace it with your headline, brand name, or a numeric string to judge weights against the text you actually set. Whitespace-only input falls back to the default.
- Step 4Run the viewer — The tool renders one `.prog-row` per step: named instances if `fvar` defines any, otherwise 100-unit wght steps. Each row shows a monospace label (instance name plus its `font-variation-settings`, or `wght N`) above the sample at 36px.
- Step 5Read the labels to pick a weight — Each row's label is the copy-ready truth: for named instances it is the full coordinate string like `"wght" 700, "wdth" 100`; for axis steps it is `"wght" 500`. Note the one that reads best for your context.
- Step 6Save or copy the HTML — Download the `<stem>.progression.html` file (the font is embedded, so it works standalone) or copy the `font-variation-settings` value from the row label straight into your stylesheet.
How the viewer decides what to render
The step list is built entirely from the font's fvar table. There is no manual step-count control — the three cases below are the only outcomes.
| Font shape | What the viewer does | Row label format | Per-row CSS applied |
|---|---|---|---|
wght axis with named instances | One row per named instance, in fvar order | Instance name · full coordinate string (e.g. Bold · "wght" 700) | font-variation-settings: <all axis coords> |
wght axis, no named instances | Steps from ceil(min/100)*100 to max in +100 increments | wght 100, wght 200, … wght N | font-variation-settings: "wght" N |
| Axes present but no `wght` axis | Single fallback row | Static | font-weight: 400 |
No fvar table (static font) | Single fallback row | Static | font-weight: 400 |
Accepted inputs, limits, and output
All formats are normalised to an sfnt buffer before fvar parsing. Limits are the free-tier font limits.
| Property | Value | Notes |
|---|---|---|
| Input formats | TTF, OTF, WOFF, WOFF2 | WOFF inflated via pako; WOFF2 decompressed via wawoff2 |
| Files per run | 1 | Single-file tool — no batch, no second file |
| Free file size limit | 5 MB (5,000,000 bytes) | Larger files are rejected by the free-tier guard |
| Sample text default | The quick brown fox | Trimmed; whitespace-only reverts to default |
| Output | HTML (text/html) | Filename <stem>.progression.html, font embedded as base64 @font-face |
| Render size | 36px per row | Fixed; the preview is for weight comparison, not size tuning |
Cookbook
Five real situations and exactly what the viewer renders for each. The point is to set expectations: the row count and labels come straight from the font, never from a setting you forgot to change.
A 5-axis font that only declares wght instances
ExampleMany superfamilies expose named instances only along weight even when other axes exist. The viewer lists each named instance and prints the entire coordinate string, so you see what the other axes are pinned to.
Named instances rendered (label · settings):
Thin · "wght" 100, "wdth" 100
Light · "wght" 300, "wdth" 100
Regular · "wght" 400, "wdth" 100
Medium · "wght" 500, "wdth" 100
Bold · "wght" 700, "wdth" 100
Black · "wght" 900, "wdth" 100
Copy any settings string into CSS:
h1 { font-variation-settings: "wght" 700, "wdth" 100; }A wght-only font with no named instances (min 200, max 800)
ExampleWhen no instances are defined the viewer steps the axis. Note the start: it is ceil(200/100)*100 = 200, then +100 each row, stopping at the max.
Steps rendered: 7 wght 200 wght 300 wght 400 wght 500 wght 600 wght 700 wght 800 Each row applies: font-variation-settings: "wght" N;
A font whose axis min is not a multiple of 100 (min 1, max 1000)
ExampleInter-style fonts often declare min 1. The viewer rounds the start up: ceil(1/100)*100 = 100. The axis floor of 1 is never rendered as its own row.
Steps rendered: 10 wght 100 wght 200 … wght 1000 Note: the true axis minimum (1) is not shown — the first step is the first multiple of 100 at or above it.
Previewing against your real headline instead of the pangram
ExampleSwap the sample text for the words you actually set so you judge weight on your own letterforms and numerals.
Sample text: Acme Q3 2026 Revenue — 42% Every weight row now renders that exact string at 36px, so you can see which weight keeps the numerals legible and the percent sign from going spindly at light weights.
Self-contained HTML you can drop into a design doc
ExampleThe output embeds the font, so the file renders the full progression with no network access and no external font dependency.
<style>
@font-face {
font-family: "Progression_MyFont";
src: url("data:font/...base64...");
font-display: block;
font-weight: 1 1000;
}
.prog-text { font-family: "Progression_MyFont"; font-size: 36px; }
</style>
<div class="prog-row">…one row per weight…</div>Edge cases and what actually happens
Every row below was probed against the live API. Some documented requirements (alphabetical axis order, numerical tuple order) are not actually enforced in practice — useful to know if you've been blaming the wrong thing for a 400.
No file uploaded
Error: Upload a font file.The handler throws Upload a font file. immediately when no file is present. Drop a font first.
Font has axes but no wght axis
Falls back to one Static rowIf fvar exists but contains no axis tagged wght (e.g. an optical-size-only or slant-only font), the viewer does not step those other axes. It renders a single row labelled Static at font-weight: 400. To preview a different axis, this tool is not the right one — its logic is wght-specific.
Axis min is below 100 (e.g. 1 or 50)
First step rounded up to 100The step loop starts at Math.ceil(min/100)*100, so a min of 1 or 50 yields a first row of wght 100. The genuine axis floor is never rendered as its own row — by design, to keep steps on round hundreds.
Axis max is not a multiple of 100 (e.g. 850)
Top step omittedThe loop condition is w <= max with +100 steps, so a max of 850 produces rows up to wght 800 and stops; 850 itself is not rendered because 900 would exceed the max. The very top of the axis can be missed by up to 99 units.
Static font with no fvar table
Single Static rowA plain static font has no fvar, so the viewer renders exactly one row labelled Static at font-weight: 400 — regardless of the font's actual declared weight. To compare separate static weight files, this single-file viewer can't do it; use a comparison tool with two files.
Sample text left blank or all spaces
Reverts to defaultThe sample is .trim()-ed; if the result is empty the viewer uses The quick brown fox. You won't get blank rows from an empty textarea.
Uploading a WOFF or WOFF2 web font
Decompressed then parsedWOFF is inflated table-by-table via pako and WOFF2 is decompressed via wawoff2 into an sfnt buffer before fvar is read, so the exact web file you ship can be previewed — not just the desktop TTF.
Named instance pins wght to a fractional value
Label weight rounded, settings exactThe numeric weight shown in code is Math.round(w), but the applied font-variation-settings string uses the instance's exact stored coordinate, so the rendered glyphs match the font's intent even when the displayed number is rounded.
File larger than 5 MB on the free tier
Rejected by free-tier guardThe free font file limit is 5,000,000 bytes. Large desktop variable fonts can exceed this; convert to WOFF2 or subset first, then preview the smaller file.
Two named instances share the same wght (e.g. Bold and Bold Italic)
Both rendered as separate rowsInstances are enumerated from fvar directly, so a family with Bold and Bold Italic instances shows both rows; the settings string differentiates them by their other axis coordinates (e.g. slnt).
Frequently asked questions
Does this freeze the font to a single weight?
No. The viewer only renders a preview — it never modifies or re-exports the font. To instantiate a static file at one weight, use the variable font freezer.
How does it decide how many rows to show?
Entirely from the font's fvar table. Named instances → one row each. A wght axis with no instances → 100-unit steps from ceil(min/100)*100 to the max. No wght axis or no fvar → one Static row. There is no step-count setting.
Why doesn't it show my font's exact axis minimum, like wght 1?
The step loop starts at the first multiple of 100 at or above the minimum, so a min of 1 renders wght 100 first. The literal floor is intentionally skipped to keep steps on round numbers.
Will it preview the width or optical-size axis?
No. The stepping logic is specific to the wght axis. If a font has other axes but no wght, you get a single Static row. To inspect all axes and their ranges, see the variable font freezer.
What formats can I upload?
TTF, OTF, WOFF, and WOFF2. WOFF and WOFF2 are decompressed to an sfnt buffer before the fvar table is read, so you can preview the exact web file you intend to ship.
Is the output online-only?
No — the HTML embeds the font as a base64 @font-face with font-weight: 1 1000, so the saved file renders the full progression with no network connection.
Can I change the preview size from 36px?
Not in this tool — rows are fixed at 36px because the goal is weight comparison, not size tuning. For responsive sizing, see the clamp font size generator or typography scale builder.
What sample text is rendered by default?
The quick brown fox. You can replace it in the Sample text textarea; whitespace-only input reverts to that default.
Can I compare two different font files side by side?
No — this is a single-file tool. It shows one font's weights. For a static-vs-static comparison you'd need a different, two-file tool.
Does the copy-ready label include all axes or just weight?
For named instances it includes every axis coordinate the instance defines (e.g. "wght" 700, "wdth" 75). For axis steps it is just "wght" N.
What's the file size limit?
5 MB (5,000,000 bytes) on the free tier. If your variable font is larger, convert it to WOFF2 or subset it first, then preview the smaller file.
Does it tell me which named instances exist?
Yes — every named instance defined in fvar becomes its own labelled row, so the rendered list is the authoritative set of instances the font ships.
Privacy first
Every JAD Font tool runs entirely in your browser using opentype.js and the wawoff2 WASM Brotli encoder. Your fonts never leave your device — verified by zero outbound network requests during processing.