How to find the exact weight, width, and slant ranges a variable font ships
- Step 1Upload the candidate font — Drop the TTF, OTF, WOFF, or WOFF2 you are evaluating for the design system. Compressed formats are decompressed in-browser, so you read the exact production file.
- Step 2Read the axis ranges — Each axis row shows tag, name, and min/default/max. Note which registered axes exist (wght/wdth/slnt/ital/opsz) and any custom ones. An axis that is absent is a capability the font does not have.
- Step 3Check wdth and slnt specifically — If your system needs condensed or oblique tokens, confirm a wdth or slnt axis exists and what range it covers. wdth is a percentage (100 = normal); slnt is degrees (negative = forward lean).
- Step 4Compare against your token plan — Map each intended token to a value inside the reported range. Anything below min or above max will clamp at render time — adjust the token to the nearest in-range value the font actually supports.
- Step 5Note the named instances — The instances list shows the discrete styles the foundry shipped. Aligning your weight tokens to named-instance values keeps you on points the designer intentionally tuned.
- Step 6Export the ranges as JSON — Download `<fontname>.axes.json` and keep it with your token source. It is the authoritative record of what the font supports, ready to diff when the foundry ships an update.
Reading each axis for design tokens
How to interpret each registered axis's reported range when defining tokens. Custom axes are font-specific and have no shorthand.
| Axis | Range units | Token meaning | Out-of-range behaviour |
|---|---|---|---|
| wght | 100-900 scale | Weight tokens (Light, Regular, Bold) | Clamps to nearest of min/max |
| wdth | percentage (100 = normal) | Width / condensed-expanded tokens | Clamps to nearest of min/max |
| slnt | degrees (negative = forward) | Oblique angle token | Clamps to nearest of min/max |
| ital | 0 or 1 | Italic toggle token | Clamps; typically only 0/1 are meaningful |
| opsz | point-size scale | Optical-size token by context | Clamps; or use font-optical-sizing: auto |
| custom (e.g. GRAD) | foundry-defined | Specialised token (grade, mono, etc.) | Clamps; explicit settings only |
Capability check before committing a token
Quick decisions you can make directly from the report. 'Axis absent' means the report has no row for that tag.
| Question | Look at | If absent / out of range |
|---|---|---|
| Can I have a 200-weight caption? | wght min | If min is 300, your lightest token is 300 |
| Can I ship a Condensed variant? | wdth axis present? | No wdth axis = no condensed; pick a different font |
| Can I do an oblique style? | slnt axis present? | No slnt = use a true italic file or synthetic oblique |
| Should weights auto-size by context? | opsz axis present? | No opsz = optical sizing not available |
| Does Black actually exist as a style? | named instances | Reachable on the continuum even if not a named instance |
Cookbook
Turning the reported ranges into safe design tokens. Use the values your specific file reports, not the examples below.
Clamp a weight token to the real range
ExampleYour spec wanted 200-800. The report says wght 300-700. Redefine the extreme tokens to the real bounds so nothing silently clamps.
report: wght min 300, max 700 --font-weight-light: 300; /* was 200 -> would clamp */ --font-weight-regular: 400; --font-weight-bold: 700; /* was 800 -> would clamp */
Decide whether condensed tokens are even possible
ExampleA width token only makes sense if the font ships a wdth axis. Check before designing the variant.
report: axes = [ wght 300-700 ] (no wdth) Decision: drop the planned --width-condensed token; this font has no width axis. Either pick a font with wdth, or use a separate condensed family.
Build oblique from the slnt range
ExampleIf slnt exists, your oblique token uses degrees within the reported range. Negative leans forward.
report: slnt min -10, default 0, max 0 --style-oblique: "slnt" -10; /* max forward lean this file allows */ /* equivalently font-style: oblique -10deg */
Anchor weight tokens to named instances
ExampleNamed instances are the weights the foundry tuned. Aligning tokens to them keeps your scale on intentional design points.
named instances: Light(300) Regular(400) Medium(500) Bold(700) --fw-light: 300; --fw-regular: 400; --fw-medium: 500; --fw-bold: 700; /* 600 is reachable but not a named instance -> omit unless needed */
Lock the design space into version control
ExampleExport the JSON and commit it. When the font is updated, re-run and diff to catch range or instance changes that would break tokens.
tokens/font-axes.json (from this tool) wght: 300..700, wdth: (none), opsz: 14..72 instances: Light, Regular, Medium, Bold CI: fail if any token weight falls outside wght min..max
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.
Token value below the axis minimum
Gotcha — clamps to minA 200 weight token on a font whose wght min is 300 renders at 300 — no error, just a silently heavier caption. Always set token extremes to the reported min/max, never beyond.
No width axis present
Capability absentIf the report shows no wdth row, the font cannot do condensed or expanded widths; font-stretch will have no effect. Pick a font that ships a wdth axis, or use a separate condensed family. The mapper makes the absence obvious.
No slant or italic axis
Capability absentWithout a slnt or ital axis, oblique/italic tokens won't work via variation settings. The browser may synthesise a fake oblique, but it will not match a designed italic. Confirm the axis exists before promising an italic token.
Width range looks like 62.5-100, not 0-100
Expected — percentage unitswdth is a percentage where 100 is normal. A range of 62.5-100 means the font condenses to 62.5% but does not expand past normal. Use those numbers directly in font-stretch (as a percent) or in font-variation-settings (as a number).
Static font uploaded
Error — no variable axesA static font has fixed weight and width with no ranges to read; the tool throws "This font has no variable axes (no fvar table or empty axis list)." For static fonts, use the Font Metrics Analyzer to read its fixed metrics instead.
Named instances don't cover every weight you want
Continuum still worksVariable fonts are continuous, so a weight like 550 is valid even if there is no named instance at 550. Named instances are just the foundry's chosen presets. Use any in-range value; the named list is guidance, not a limit.
Axis present but default sits at one extreme
Read carefullyIf wght default equals its min (e.g. default 400, min 400, max 900) the font ranges upward only. Your 'lighter than default' token is impossible. The default/min/max triple tells you which direction the axis can move.
A fractional range like opsz 14-144 with default 14
Expected — Fixed 16.16Optical-size ranges are reported exactly from Fixed 16.16. A default at the small end means the font renders for small text unless you raise opsz or enable font-optical-sizing: auto. Map your context tokens within the reported range.
Custom axis you didn't plan for
Listed — opportunityFonts like Recursive or Roboto Flex ship custom axes (CASL, MONO, GRAD, parametric XOPQ/YOPQ). The report lists them with ranges. They have no CSS shorthand, so any token must use font-variation-settings with the explicit tag.
Frequently asked questions
How do I find a variable font's weight range?
Drop the file here and read the wght axis row: its min and max are the lightest and heaviest weights the file can render. Anything outside that range clamps to the boundary in the browser.
Does the font have a width (condensed) axis?
Check for a wdth row in the report. If it is absent, the font has no width axis and font-stretch will do nothing. If present, the min/max (as percentages, 100 = normal) tell you how far it condenses or expands.
What units are width and slant in?
wdth is a percentage where 100 is normal width; a value like 75 is condensed. slnt is degrees, where negative leans forward. The report shows the raw numbers, which match what font-stretch and font-style oblique expect.
Why do my extreme tokens render the same as the defaults?
They are probably outside the axis range and being clamped. A 200 weight token on a font whose wght min is 300 renders at 300. Set your extreme tokens to the reported min/max so they stay in range.
Are named instances the only weights I can use?
No. Variable fonts are continuous — any value within the reported range is valid, named or not. Named instances are the foundry's chosen presets and are good anchors for tokens, but you are not limited to them.
Why is a width value a decimal like 87.5?
fvar stores values in Fixed 16.16 fixed-point, decoded by dividing by 65536, so fractional widths appear exactly. Use 87.5 verbatim rather than rounding, to land on the intended design point.
Can I use this to compare two candidate fonts?
Yes. Map each font and compare the reported ranges and named instances. The one whose ranges cover your token plan without clamping is the better fit. Export both JSON reports to diff them.
Does it work on a static font?
No. Static fonts have no axes; the tool reports that there are no variable axes. For a static font's fixed metrics, use the Font Metrics Analyzer instead.
Will this change the font file?
No, it is read-only. To produce a static file at a chosen weight, use the Variable Font Freezer. This tool only reports what ranges exist.
Is my font uploaded?
No. The fvar table is parsed in your browser from the file's bytes. Nothing is uploaded, so you can safely evaluate fonts that are still under licence review.
What if the font has axes I don't recognise?
Custom (uppercase-tag) axes are foundry-defined — grade, monospace, casual, parametric, etc. The report lists their ranges. They have no CSS shorthand, so you reach them only via font-variation-settings with the explicit tag. To turn the ranges into deployable rules, use the Font Face Generator or CSS Variable Generator.
How large a font can I evaluate?
5 MB on Free, 50 MB on Pro, 1 GB on Developer per job. Reading axis ranges only touches the fvar and name tables, so it is fast even for large families.
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.