How to see every axis inside any variable font
- Step 1Drop your variable font onto the tool — Upload a TTF, OTF, WOFF, or WOFF2. WOFF2 is Brotli-decompressed and WOFF is zlib-inflated in the browser before parsing — you do not need to convert to TTF first. Static (non-variable) fonts will be rejected at the next step.
- Step 2Let the fvar parser run client-side — The tool locates the `fvar` table in the sfnt directory and reads it directly. No data is sent anywhere; the parse happens in your tab. If there is no `fvar` table or it lists zero axes, you get a clear error instead of a blank result.
- Step 3Read the axis table — Each axis row shows its 4-character `tag`, a human `name` (pulled from the font's Windows-English name records, falling back to the tag), and `min` / `default` / `max`. Registered tags are lowercase (`wght`, `wdth`, `slnt`, `ital`, `opsz`); custom tags are uppercase (`GRAD`, `YOPQ`).
- Step 4Scan the named instances — Below the axes, every named instance is listed with its `name` and a `coordinates` map of tag-to-value. This is the design-space point the foundry blessed as a discrete style — e.g. `Bold = { wght: 700 }`. Instances without a name record fall back to `Instance N`.
- Step 5Copy the font-variation-settings snippets — The output includes a `css_examples` array — one comment-labelled `font-variation-settings` line per named instance. Paste the one you want into a CSS rule alongside `font-family`. There is one snippet per named instance, so a font with no named instances produces an empty list (the axes are still listed).
- Step 6Save or hand off the JSON — Download the report as `<fontname>.axes.json`. It contains `axis_count`, the full `axes` array, `instance_count`, the `instances` array, and `css_examples`. Keep it next to the font in your repo as the canonical record of what the file supports.
What the JSON report contains
Every field the mapper returns, parsed live from the fvar table. The report is read-only — it describes the font, it does not modify it.
| Field | Type | What it holds |
|---|---|---|
axis_count | number | How many variation axes the fvar table declares |
axes[].tag | string | 4-character axis tag, e.g. wght, opsz, or a custom GRAD |
axes[].name | string | Human axis name from the font's Windows-English name table; falls back to the tag if no matching record exists |
axes[].min / default / max | number | Axis range endpoints, decoded from Fixed 16.16 (can be fractional) |
axes[].flags | number | Raw fvar axis flags value (e.g. hidden-axis bit) as stored in the file |
instance_count | number | How many named instances the font ships |
instances[].name | string | Subfamily name of the instance; falls back to Instance N when no name record matches |
instances[].coordinates | object | Map of axis tag to that instance's value across all axes |
css_examples | string[] | One font-variation-settings block per named instance, comment-labelled with the instance name |
Registered axes you will commonly see
The five OpenType-registered axes use lowercase tags; any 4-letter uppercase tag is a custom (foundry-defined) axis. The mapper reports whatever the file declares — these are just the common ones.
| Tag | Axis name | Typical range | Maps to CSS |
|---|---|---|---|
wght | Weight | 100-900 (often) | font-weight / font-variation-settings: "wght" N |
wdth | Width | 62.5-100-200 (varies) | font-stretch / "wdth" N (percentage) |
slnt | Slant | -10 to 0 (degrees) | font-style: oblique Ndeg / "slnt" N |
ital | Italic | 0 to 1 | font-style: italic / "ital" 1 |
opsz | Optical size | 8-144 (varies) | font-optical-sizing / "opsz" N |
GRAD, YOPQ, XTRA... | Custom / parametric | foundry-defined | font-variation-settings: "TAG" N only |
Cookbook
Common ways to turn the mapped axes into working CSS. Values shown are illustrative — use the exact min/default/max the tool reports for your specific file.
Bind a named instance straight into a rule
ExampleThe css_examples array gives you the instance's settings verbatim. Drop it onto a class that also sets font-family. This pins the font to one design-space point rather than relying on the default.
/* From css_examples, instance "SemiBold" */
.lead {
font-family: "My Variable";
font-variation-settings: "wght" 600;
}Use the reported axis range to drive a fluid weight
ExampleOnce you know wght runs 100-900, you can animate or interpolate within that range. Never push a value past the reported max — out-of-range values are clamped by the browser, so they silently render at the boundary, not where you intended.
/* axes report: wght min 100, max 900 */
.title {
font-family: "My Variable";
font-variation-settings: "wght" 820; /* inside 100-900 */
transition: font-variation-settings .2s;
}
.title:hover { font-variation-settings: "wght" 900; }Combine multiple axes from one instance's coordinates
ExampleAn instance's coordinates map lists every axis, so a 'Condensed Bold' instance carries both wght and wdth. Copy all of them together — setting only wght would leave width at its default.
/* instance "Condensed Bold" coordinates: { wght: 700, wdth: 75 } */
.compact-heading {
font-family: "My Variable";
font-variation-settings: "wght" 700, "wdth" 75;
}Drive optical size from the reported opsz range
ExampleIf the report lists an opsz axis, you can let the browser auto-pick with font-optical-sizing: auto, or pin it. The mapper tells you the valid range so your manual value stays in bounds.
/* axes report: opsz min 14, max 72 */
body { font-optical-sizing: auto; } /* browser interpolates opsz by size */
.fine-print {
font-variation-settings: "opsz" 14; /* pin to the small-text design */
}Document a font's design space in your repo
ExampleSave the JSON next to the font as a contract. When a designer ships a new build, re-run the mapper and diff the axes — a vanished axis or a shrunk range is an instant red flag before it reaches production.
# committed alongside the font MyVariable.var.axes.json axis_count: 2 axes: wght (100..900), opsz (14..72) instance_count: 9 instances: Thin ... Black
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.
Upload a static (non-variable) font
Error — no variable axesIf the file has no fvar table, or an fvar table with zero axes, the tool throws "This font has no variable axes (no fvar table or empty axis list)." Static fonts are not mappable here. To inspect a static font's tables and metadata instead, use the Font Metadata Extractor.
Upload a TrueType Collection (.ttc)
Error — unsupported formatThe mapper accepts a single face: TTF, OTF, WOFF, or WOFF2. A .ttc collection trips the format guard and you get "Unsupported font format: ttc." Extract the individual face you want first, then map it. Use the Font Format Identifier to confirm exactly what container you have.
Axis names show as bare tags like wght or GRAD
Expected — name fallbackThe human axis name is read only from Windows-English name records (platform 3, encoding 1, language 0x409). A font that stores axis names only on the Macintosh platform, or in another language, will show the 4-character tag instead of a friendly label. The tag is canonical, so this never changes the CSS you write.
Named instances appear as Instance 1, Instance 2...
Expected — name fallbackJust like axes, instance names come from Windows-English name records. When an instance's subfamily name ID has no matching record, it falls back to Instance N. The coordinates map is still fully populated, so the css_examples snippets are still correct — only the human label is generic.
Axis default is a fractional number like 387.5
Expected — Fixed 16.16fvar stores axis values as Fixed 16.16 fixed-point, which the tool decodes by dividing the raw integer by 65536. That means non-integer defaults, minimums, and maximums (common on parametric axes) are reported exactly rather than rounded. Use the value verbatim in font-variation-settings.
The css_examples list is empty
Expected — no named instancescss_examples contains one block per named instance. A variable font that declares axes but ships zero named instances produces an empty css_examples array. The axes table is still fully populated — build your own font-variation-settings from the reported min/default/max.
Font exceeds your tier's per-job size limit
Error — over limitPer-job upload caps are 5 MB on Free, 50 MB on Pro, and 1 GB on Developer. Most variable fonts are well under 5 MB compressed, but a large CJK variable family can exceed the Free cap. The tool reports the exact limit it blocked on; upgrade the tier for larger files.
A hidden axis appears in the report
Listed — flaggedSome fonts mark an axis as hidden (a flag bit in fvar) so it does not show in design tools. The mapper still lists it and exposes the raw flags value, because a hidden axis is still settable via font-variation-settings. Reading flags lets you tell an intentionally hidden axis from a normal one.
You expected to download a modified font
Read-only by designThis tool never writes a font — it only reports the design space. To bake one instance into a static file, use the Variable Font Freezer. To turn axis values into deployable @font-face CSS, use the Font Face Generator or CSS Variable Generator.
Frequently asked questions
Does my font get uploaded to a server?
No. The fvar parser runs entirely in your browser. The font binary is read with the FileReader/ArrayBuffer API and parsed in your tab — it is never sent to a server, which makes the tool safe for unreleased or licensed fonts.
What file formats can I drop in?
TTF, OTF, WOFF, and WOFF2. WOFF2 is Brotli-decompressed and WOFF is zlib-inflated in the browser before parsing, so you do not need to convert to TTF first. TrueType Collections (.ttc) are not supported.
Why does it say my font has no variable axes?
The font either has no fvar table (it is a static font) or its fvar table declares zero axes. Only variable fonts have a design space to map. Confirm the format with the Font Format Identifier if you are unsure whether you have a variable build.
What do the min, default, and max numbers mean?
They are the endpoints and resting point of each axis's range. default is what you get if you set no font-variation-settings; min and max are the limits you can interpolate between. Values outside that range are clamped by the browser.
Why are some axis names just four letters?
The friendly axis name is read from the font's Windows-English name records. If a font stores that name only on another platform or language, the tool falls back to the 4-character tag. The tag is the canonical identifier you use in CSS anyway.
What is a named instance versus an axis?
An axis is a continuous dimension (e.g. weight 100-900). A named instance is a specific point in that space the foundry exposed as a discrete style (e.g. "Bold" = wght 700). The tool lists both, and generates a CSS snippet per named instance.
Can I edit the axes or trim the ranges here?
No — this tool is read-only. To trim unused ranges you would use a desktop tool like fonttools' instancer; to bake a single instance into a static font, use the Variable Font Freezer.
Why is a default value a decimal like 412.5?
fvar values are stored in Fixed 16.16 fixed-point. The tool divides the raw value by 65536, which faithfully recovers fractional values. Parametric axes in particular often use non-integer defaults — use the reported value exactly.
The css_examples array is empty — is that a bug?
No. css_examples has one entry per named instance. If the font declares axes but no named instances, there is nothing to template, so the array is empty. Build your own font-variation-settings from the reported axis ranges.
How big a font can I map?
Up to 5 MB on the Free tier, 50 MB on Pro, and 1 GB on Developer per job. The mapper only reads the fvar and name tables, so even large families parse quickly within those caps.
What is the flags field on each axis?
It is the raw fvar axis flags value from the file. The defined bit marks an axis as hidden from UI. The tool surfaces the number so you can detect hidden axes, which are still fully settable via font-variation-settings.
What do I do after mapping the axes?
Take the ranges and instance coordinates into your CSS. For ready-made @font-face blocks use the Font Face Generator; for design-token-style CSS custom properties use the CSS Variable Generator; to ship a single weight as a static file use the Variable Font Freezer.
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.