Understanding Font Weights: 100 to 900 Explained
Embed This Widget
Add the script tag and a data attribute to embed this widget.
Embed via iframe for maximum compatibility.
<iframe src="https://fontfyi.com/iframe/entity//" width="420" height="400" frameborder="0" style="border:0;border-radius:10px;max-width:100%" loading="lazy"></iframe>
Paste this URL in WordPress, Medium, or any oEmbed-compatible platform.
https://fontfyi.com/entity//
Add a dynamic SVG badge to your README or docs.
[](https://fontfyi.com/entity//)
Use the native HTML custom element.
Understanding Font Weights: 100 to 900 Explained
Font weight is one of the most expressive typographic tools available in CSS. The spectrum from 100 (ultra-thin) to 900 (ultra-black) creates a visual hierarchy that guides the eye, communicates importance, and establishes brand character.
Yet font weights are widely misunderstood. Developers frequently set font-weight: bold without knowing what weight value that resolves to, load weights that don't actually exist in a given font, or unknowingly rely on the browser's weight synthesis, which produces noticeably inferior results.
This guide covers the full weight system: what the values mean, how named keywords map, how variable fonts change the game, what happens when a weight is missing, and how to load multiple weights efficiently.
The 100-900 Weight Scale
CSS defines font weight on a numeric scale from 1 to 1000, though in practice the values are expressed in multiples of 100 from 100 to 900. These values map to the weight names used in traditional typography and in font file naming conventions.
.weight-100 { font-weight: 100; } /* Thin / Hairline */
.weight-200 { font-weight: 200; } /* Extra Light / Ultra Light */
.weight-300 { font-weight: 300; } /* Light */
.weight-400 { font-weight: 400; } /* Regular / Normal */
.weight-500 { font-weight: 500; } /* Medium */
.weight-600 { font-weight: 600; } /* Semi Bold / Demi Bold */
.weight-700 { font-weight: 700; } /* Bold */
.weight-800 { font-weight: 800; } /* Extra Bold / Ultra Bold */
.weight-900 { font-weight: 900; } /* Black / Heavy */
Each step in the scale is a 100-unit increment. With static fonts, you are limited to these specific values — and only the values for which you have loaded a font file. With variable fonts, any numeric value between 1 and 1000 is valid.
Practical Weight Usage in UI Design
Most interfaces use three to four distinct weights:
:root {
--weight-light: 300; /* Decorative, large display text */
--weight-regular: 400; /* Body copy, default */
--weight-medium: 500; /* UI labels, slightly emphasized text */
--weight-semibold: 600; /* Sub-headings, strong emphasis */
--weight-bold: 700; /* Headings, strong CTAs */
}
body { font-weight: var(--weight-regular); }
.label { font-weight: var(--weight-medium); }
h3, h4 { font-weight: var(--weight-semibold); }
h1, h2 { font-weight: var(--weight-bold); }
Using too many weights creates visual noise and increases download size. Loading three or four is usually enough for a complete visual hierarchy.
Named Weights: Thin, Light, Regular, Bold, Black
In addition to numeric values, CSS provides two keyword values: normal and bold.
/* Keyword equivalents */
.normal { font-weight: normal; } /* Equivalent to 400 */
.bold { font-weight: bold; } /* Equivalent to 700 */
The keywords lighter and bolder are relative to the inherited weight and follow a lookup table:
/* bolder and lighter follow this table:
Inherited: 100-300 → bolder = 400
Inherited: 400-500 → bolder = 700
Inherited: 600-900 → bolder = 900
Inherited: 100-500 → lighter = 100
Inherited: 600-700 → lighter = 400
Inherited: 800-900 → lighter = 700
*/
.parent { font-weight: 400; }
.child { font-weight: bolder; } /* Becomes 700 */
.grandchild { font-weight: bolder; } /* Becomes 900 */
Font Family Naming Conventions
Font families use various naming conventions for their weight variants. These don't always map predictably to CSS values. Here is the common mapping:
| File/Style Name | CSS Value |
|---|---|
| Thin, Hairline | 100 |
| Extra Light, Ultra Light | 200 |
| Light | 300 |
| Regular, Roman, Normal, Book | 400 |
| Medium | 500 |
| Semi Bold, Demi Bold | 600 |
| Bold | 700 |
| Extra Bold, Ultra Bold | 800 |
| Black, Heavy, Ultra Black | 900 |
Some families have additional named weights not covered by CSS: "Compressed", "Ultra Compressed", or brand-specific names like "Display". These may map to non-standard numeric weights or to custom variable font axes.
Which Weights Google Fonts Offers
Not all fonts on Google Fonts offer all nine weights. Some highlights:
Inter: 100, 200, 300, 400, 500, 600, 700, 800, 900 (variable font, full range) Roboto: 100, 300, 400, 500, 700, 900 Open Sans: 300, 400, 500, 600, 700, 800 Lato: 100, 300, 400, 700, 900 Montserrat: 100, 200, 300, 400, 500, 600, 700, 800, 900
Always check which weights a font actually offers before designing around a weight. Loading a weight that doesn't exist triggers weight synthesis, which is covered below.
Font Weight in Variable Fonts
Variable fonts fundamentally change how font weight works. Instead of discrete files for specific weights, a single variable font file contains the entire weight spectrum defined by the type designer.
/* Variable font with full weight range */
@font-face {
font-family: 'Inter';
src: url('/fonts/Inter-Variable.woff2') format('woff2');
font-weight: 100 900; /* Range — covers any value in between */
font-display: swap;
}
/* Now any numeric weight value is valid */
.hero-thin { font-weight: 100; }
.body-text { font-weight: 400; }
.ui-medium { font-weight: 500; }
.half-step { font-weight: 450; } /* Not possible with static fonts */
.almost-bold { font-weight: 650; } /* Not possible with static fonts */
.heading { font-weight: 700; }
.extra-heavy { font-weight: 850; } /* Not possible with static fonts */
The ability to specify non-multiple-of-100 weight values is one of the most useful capabilities of variable fonts in practice. It enables:
Dark mode weight adjustment: Dark backgrounds make text appear optically heavier. Reducing weight from 400 to 370 on dark backgrounds maintains the same perceived weight:
@media (prefers-color-scheme: dark) {
body { font-weight: 370; } /* Slightly lighter than 400 */
strong { font-weight: 580; } /* Slightly lighter than 600 */
}
Optical weight matching: Large text at the same font-weight value looks heavier than small text. Reducing weight slightly for display sizes matches the visual weight to the designer's intent:
h1 {
font-size: 4rem;
font-weight: 680; /* Feels like 700 but optically correct at large size */
}
h3 {
font-size: 1.5rem;
font-weight: 700; /* Standard bold at normal heading size */
}
Smooth hover animations: Animating weight on hover creates a satisfying interactive effect without layout shift (since variable font weight changes don't change metrics significantly in most cases):
.nav-link {
font-weight: 400;
transition: font-weight 200ms ease;
}
.nav-link:hover {
font-weight: 600;
}
Weight Synthesis: What Happens When a Weight Is Missing
When you request a font-weight that the font family doesn't have a file for, the browser synthesizes it. This is automatic and silent — there's no error.
How Synthesis Works
Bold synthesis: When you request font-weight: 700 but only 400 is loaded, the browser applies an algorithmic darkening/thickening of the 400 strokes. The result is almost always visually inferior to a properly designed bold face — it applies a uniform stroke widening that doesn't account for the optical adjustments a type designer makes when drawing a bold weight.
Thin/light synthesis: When you request font-weight: 300 but only 400 is loaded, the browser applies an algorithmic thinning. The results are similarly imperfect.
/* This triggers synthesis if only the regular (400) weight is loaded */
strong {
font-weight: bold; /* 700 — will be synthesized if 700 isn't loaded */
}
/* To prevent synthesis, load the weight you need */
@font-face {
font-family: 'Open Sans';
src: url('/fonts/OpenSans-Bold.woff2') format('woff2');
font-weight: 700; /* Load the real bold */
font-display: swap;
}
Detecting Synthesis Problems
You can see synthesis in action by comparing text rendered in a synthesized weight versus a proper weight. The most visible difference is usually: - Synthesized bold: uniform stroke widening, sometimes blurry, poor spacing - Real bold: carefully adjusted strokes, maintained spacing, intentional design
Open browser DevTools and look at the "Fonts" section of the Elements panel. Chrome DevTools shows you exactly which font file is being used for each element, and whether synthesis is being applied.
Disabling Synthesis
You can prevent the browser from synthesizing weights using font-synthesis:
/* Disable all synthesis */
body {
font-synthesis: none;
}
/* Disable only weight synthesis (allow style synthesis) */
body {
font-synthesis: style;
}
/* Disable only italic synthesis (allow weight synthesis) */
body {
font-synthesis: weight;
}
Setting font-synthesis: none means that if a requested weight isn't available, the browser renders the nearest available weight instead of synthesizing. This can result in text that's lighter or heavier than intended, but it prevents the quality degradation of synthesis.
The right approach is to load the weights you need rather than rely on synthesis at all.
Best Practices for Loading Multiple Weights
1. Load Only What You Need
Every weight variant is a separate file download (for static fonts) or increases the size of the variable font file. Audit your design and load only the weights you actually use.
/* Audit your design — do you actually need all these? */
@font-face { font-weight: 100; src: url('thin.woff2'); } /* Thin headlines? */
@font-face { font-weight: 200; src: url('el.woff2'); } /* Rarely needed */
@font-face { font-weight: 300; src: url('light.woff2'); } /* Subheadings? */
@font-face { font-weight: 400; src: url('regular.woff2'); } /* Body — YES */
@font-face { font-weight: 500; src: url('medium.woff2'); } /* UI labels? */
@font-face { font-weight: 600; src: url('semibold.woff2'); } /* Strong labels? */
@font-face { font-weight: 700; src: url('bold.woff2'); } /* Headings — YES */
@font-face { font-weight: 800; src: url('extrabold.woff2'); } /* Rarely needed */
@font-face { font-weight: 900; src: url('black.woff2'); } /* Display only */
For most body-copy-focused sites, you need exactly two weights: 400 and 700. For UI-heavy applications, add 500 or 600.
2. Prefer Variable Fonts for Multiple Weights
If you need three or more weights, a variable font is almost always more efficient:
/* Static: 4 files, 4 HTTP requests, ~68 KB total */
@font-face { font-weight: 300; src: url('light.woff2'); }
@font-face { font-weight: 400; src: url('regular.woff2'); }
@font-face { font-weight: 600; src: url('semibold.woff2'); }
@font-face { font-weight: 700; src: url('bold.woff2'); }
/* Variable: 1 file, 1 HTTP request, ~45 KB, full range */
@font-face {
font-weight: 100 900;
src: url('variable.woff2') format('woff2');
}
3. Define Weight Variables Once
:root {
--weight-body: 400;
--weight-ui: 500;
--weight-emphasis: 600;
--weight-heading: 700;
--weight-display: 800;
}
body { font-weight: var(--weight-body); }
.label { font-weight: var(--weight-ui); }
strong, b { font-weight: var(--weight-emphasis); }
h3, h4, h5 { font-weight: var(--weight-heading); }
h1, h2 { font-weight: var(--weight-display); }
This makes weight auditing simple: look at your :root variables to see every weight in use, and ensure each maps to a loaded font face.
4. Preload the Most Critical Weight
For your primary body font, preload the regular (400) weight to eliminate render-blocking:
<!-- Preload the most critical weight — regular body text -->
<link
rel="preload"
href="/fonts/inter-400.woff2"
as="font"
type="font/woff2"
crossorigin
>
Non-critical weights (bold for headings, etc.) can load on demand without preloading.
5. Use font-display: swap
Always include font-display: swap so users see text in the fallback font immediately rather than waiting for the web font:
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-400.woff2') format('woff2');
font-weight: 400;
font-display: swap;
}
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-700.woff2') format('woff2');
font-weight: 700;
font-display: swap;
}
The weight scale is one of the most powerful tools in your typographic toolkit. Used well — with deliberate choices about which weights to load, careful matching of weights to their intended use, and an understanding of how variable fonts expand the possibilities — it creates a clear, legible visual hierarchy with minimal overhead.
タイポグラフィ用語
ツールを試す
言及されたフォント
Christian RobertsonがGoogleのMaterial Designエコシステムのために設計したこのネオグロテスクなサンセリフ体は、ウェブとAndroidで最も広く使われている書体です。機械的な精密さと自然な読み取りのリズムを両立させたデュアルネイチャーのデザインにより、UIラベルから長文テキストまで幅広く活躍します。バリアブルフォントは幅と太さの軸に加え、キリル文字・ギリシャ文字・拡張ラテン文字もサポートしています。
Rasmus Anderssonが長年かけてコンピュータスクリーン向けに磨き上げたこのネオグロテスクは、デジタルディスプレイの小サイズでの高い可読性を実現するため、字間・Xハイト・ストロークコントラストを最適化しています。光学サイズ軸(opsz)によりキャプションと見出しでデザインが自動調整され、太さ軸はThinからBlackまで全範囲をカバー。ダッシュボード・ドキュメントサイト・開発者ツールでのデファクトスタンダードとなっています。
ブエノスアイレスのモンセラット地区の幾何学的な看板や商店街に着想を得て、Julieta Ulanovskiが20世紀初頭の都市的なレタリングの精神を表現すべく生み出したこの書体は、クリーンな円形フォルムと力強い幾何学的プロポーションが、見出し・ブランディング・ランディングページに最適な力強い存在感を生み出します。バリアブルウェイト軸は幅広いレンジをカバーし、キリル文字とベトナム語も収録しています。