How to generate font-weight presets for inter's variable woff2
- Step 1Get Inter's variable WOFF2 and self-host it — Download the variable build (`Inter.var.woff2` / `InterVariable.woff2`) from the Inter project and place it under your own domain, e.g. `/fonts/inter.var.woff2`. If you currently pull Inter from Google Fonts, convert that to a self-hosted block with [google-fonts-css-generator](/font-tools/google-fonts-css-generator) first, then generate weight presets here.
- Step 2Keep the family name as Inter — The default family `Inter` is already correct for stock Inter. The value only needs to match what your component CSS references — it does not have to equal Inter's internal name-table family. Leave it as `Inter` unless you're aliasing.
- Step 3Point the Font URL at your hosted file — Set the URL to your real path (default `/fonts/inter.var.woff2`). The exact string is written verbatim into both `src` entries; the tool never fetches it, so paste the deployed path, not a localhost one.
- Step 4Generate the nine Inter presets — The builder emits a header comment plus Thin 100 → Black 900. For stock Inter every value is in range, so no preset is wasted. There are no other knobs — the ladder, the `wght` axis, `font-style: normal`, and `font-display: swap` are all fixed.
- Step 5Replace your old multi-file Inter @font-face set — Delete the per-weight `@font-face` rules that pointed at `Inter-Thin.woff2`, `Inter-Regular.woff2`, etc., and paste the generated block in their place. The variable file now backs every weight from one download.
- Step 6Verify the weights render distinctly — Render a paragraph at `font-weight: 100; 400; 700; 900` and confirm visible steps. If 100 and 200 look identical, you're likely on a range-trimmed Inter subset whose axis no longer starts at 100 — see the edge cases below.
Inter's wght axis vs the builder's ladder
Stock InterVariable exposes wght 100–900, so every generated preset maps to a real axis point. This is why Inter is the cleanest match for the fixed ladder.
| Preset | wght emitted | In stock Inter's range (100–900)? |
|---|---|---|
| Thin | 100 | Yes — axis minimum |
| Extra Light | 200 | Yes |
| Light | 300 | Yes |
| Regular | 400 | Yes — Inter's default |
| Medium | 500 | Yes |
| Semi Bold | 600 | Yes |
| Bold | 700 | Yes |
| Extra Bold | 800 | Yes |
| Black | 900 | Yes — axis maximum |
Self-hosted Inter: variable presets vs static multi-file
Why the generated preset block beats shipping nine static Inter weights, and the one case where static still wins.
| Approach | Files downloaded | Trade-off |
|---|---|---|
| Variable + 9 presets (this tool) | 1 (inter.var.woff2, cached once) | Slightly larger single file; every weight free after first load |
| 9 static WOFF2 weights | up to 9 separate fetches | Each weight cached independently, but more requests and total bytes if you use 3+ weights |
| Google Fonts CDN | served by Google | No self-host work, but visitor IP leaks to Google (GDPR concern) and extra DNS/connection |
Fields and their Inter defaults
The two-field form, pre-populated for Inter.
| Field | Default | Keep or change? |
|---|---|---|
| Family name | Inter | Keep for stock Inter |
| Font URL | /fonts/inter.var.woff2 | Change to your real hosted path |
| Output filename | inter-weight-presets.css | Derived from family — auto |
Cookbook
Inter-specific CSS the builder produces and how to slot it into a typical self-hosted setup.
Inter Regular and Bold from the generated block
ExampleTwo of the nine blocks. Note both point at the same /fonts/inter.var.woff2.
@font-face {
font-family: "Inter";
src: url("/fonts/inter.var.woff2") format("woff2-variations"),
url("/fonts/inter.var.woff2") format("woff2");
font-weight: 400;
font-style: normal;
font-display: swap;
font-variation-settings: "wght" 400;
}
@font-face {
font-family: "Inter";
src: url("/fonts/inter.var.woff2") format("woff2-variations"),
url("/fonts/inter.var.woff2") format("woff2");
font-weight: 700;
font-style: normal;
font-display: swap;
font-variation-settings: "wght" 700;
}Body text with Inter as the base family
ExampleAfter pasting the presets, your base styles are plain font-weight.
:root { --font-sans: "Inter", system-ui, sans-serif; }
body { font-family: var(--font-sans); font-weight: 400; }
strong { font-weight: 600; }
h1, h2 { font-weight: 800; }Migrating off the nine static Inter files
ExampleReplace a stack of single-weight @font-face rules with the one generated variable block.
/* BEFORE: 9 rules, 9 files */
@font-face { font-family:"Inter"; font-weight:400;
src:url(/fonts/Inter-Regular.woff2) format("woff2"); }
/* ...eight more... */
/* AFTER: generated variable presets, 1 file */
/* paste inter-weight-presets.css here */Preload Inter for first paint
ExampleThe builder doesn't emit preload; add it manually in head.
<link rel="preload" href="/fonts/inter.var.woff2"
as="font" type="font/woff2" crossorigin>Adding Inter's display-friendly 350 (optical preference)
ExampleSome designers prefer a hair under 400 for large Inter text. That value isn't in the ladder — add it directly.
.hero-sub {
font-family: "Inter";
font-variation-settings: "wght" 350;
}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.
You're using a range-trimmed Inter subset
Extremes clampIf you've run Inter through an axis-range trim (e.g. wght cut to 300–700 to shrink the file), the builder still emits 100–900 because it never reads the file. The browser then clamps wght 100/200 to your 300 minimum and wght 800/900 to your 700 maximum — Thin, Extra Light, Extra Bold and Black all collapse onto your range ends. Either keep the full-range Inter or hand-edit the generated CSS to only the weights you shipped.
You used Inter's static italic build by mistake
No variationIf your URL points at a static Inter-Italic.woff2 instead of the variable file, every preset's font-variation-settings is ignored and you get one fixed weight in italic. The CSS parses fine. Confirm the file is the variable build (it carries an fvar table) before generating.
InterVariable vs Inter.var filename mismatch
404The Inter project has shipped the variable file under different names over the years (Inter.var.woff2, InterVariable.woff2). The default URL is /fonts/inter.var.woff2; if your deployed file is named differently, update the Font URL field to the exact filename or the font 404s and you fall back to system-ui.
Google Fonts Inter instead of self-hosted
Wrong tool pathIf you load Inter from fonts.googleapis.com, you don't control the @font-face and pasting these presets pointing at a Google URL is fragile. Convert to self-hosted first with google-fonts-css-generator, host the WOFF2, then generate presets against your own path.
You want Inter's slnt (italic) axis exposed
Not generatedInterVariable also has a slant/italic axis. This builder only writes the wght axis with font-style: normal. To expose Inter italic, duplicate the generated set with font-style: italic and add the appropriate "slnt"/"ital" value to font-variation-settings by hand.
Aliasing Inter to a different CSS family name
200 OKIf your design system references the font as --brand-sans or "AppFont", set the Family name field to that name — the presets bind to whatever you type, not to Inter's internal name. The variable file doesn't care what CSS family points at it.
Mixing the presets with a non-Inter fallback stack
200 OK — fallback only on loadBecause every block is font-display: swap, your fallback stack (system-ui, sans-serif) shows for the brief moment before Inter loads, then swaps. Keep a metrics-compatible fallback to minimise the layout shift on swap; Inter pairs well with system-ui.
Expecting the tool to download Inter for you
CSS onlyThis builder doesn't fetch, bundle, or host Inter — it only writes CSS referencing a URL you provide. Download Inter from its own project and self-host it; the tool just generates the @font-face glue.
Frequently asked questions
Why is Inter a perfect match for this builder?
Inter's wght axis is exactly 100–900, the same span the builder hardcodes. So all nine emitted presets (Thin through Black) land on real axis points with nothing clamped. Fonts whose weight axis is narrower would have presets collapse onto the range ends; stock Inter doesn't.
Does the tool include Inter, or do I supply it?
You supply it. The builder only generates CSS that references a URL you give it (default /fonts/inter.var.woff2). Download InterVariable from the Inter project, self-host it, and point the Font URL at your deployed path.
Should I switch from nine static Inter files to the variable presets?
If you use three or more Inter weights, yes — one cached variable file usually beats multiple static fetches in total bytes and request count, and every weight becomes available for free. If you use only Regular and Bold, two static files can occasionally be smaller; measure both.
Will the presets work with Google-Fonts-hosted Inter?
Not reliably. Google serves its own @font-face and the gstatic URLs aren't stable to hardcode. Self-host instead: convert with google-fonts-css-generator, host the WOFF2, then generate presets against your own URL.
Can I get Inter italic presets here?
No. The builder only writes wght with font-style: normal. InterVariable has a slant axis, so duplicate the generated blocks yourself with font-style: italic and the matching font-variation-settings slant value.
What if my Inter is range-trimmed to 300–700?
The builder still emits 100–900 (it doesn't read your file). The browser clamps out-of-range values, so Thin/Extra Light render at 300 and Extra Bold/Black at 700. Either ship full-range Inter or delete the out-of-range blocks from the generated CSS.
What family name should I use?
For stock Inter, keep Inter. The value only needs to match what your component CSS references — it can be an alias like "BrandSans" if your design tokens use that. It does not have to equal Inter's internal name-table family.
Do I still need a preload tag for Inter?
For above-the-fold text, yes — add <link rel="preload" as="font" type="font/woff2" crossorigin> for the variable file. The builder writes only @font-face, not preload, so the preload is a separate manual line in your head.
Is the generated CSS the same every time for Inter?
Yes — the output is deterministic. With family Inter and the default URL you always get the same nine blocks plus header comment. Only your two inputs change the strings; the ladder, axis, style, and display are fixed.
Does self-hosting Inter this way help GDPR compliance?
Yes. Self-hosting means visitor IPs never reach Google's font CDN, removing one third-party data flow. The variable file lives on your own domain; this builder just gives you the @font-face glue to serve every weight from it.
Is there a file-size limit?
No — this is a generative tool with no upload. The 5 MB free / 50 MB pro font upload caps apply to tools that parse a binary; this one only manipulates two strings.
Why list /fonts/inter.var.woff2 twice in each src?
The two entries differ only by format hint — format("woff2-variations") first so variation-aware browsers recognise Inter's axes, then plain format("woff2") as a fallback hint. Same Inter file, same URL: the browser fetches the first entry it understands and stops, so it's one cached download, not two requests.
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.