폰트 웨이트 이해하기: 100부터 900까지 설명
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-height, 획 대비를 최적화했습니다. 광학 크기 축(opsz)은 캡션과 헤드라인에 맞춰 디자인을 자동으로 조정하며, 웨이트 축은 얇은 것부터 가장 굵은 것까지 전체 범위를 아우릅니다. 전 세계 대시보드, 문서 사이트, 개발자 도구에서 사실상의 표준 선택지가 되었습니다.
부에노스아이레스 몬세라트 지역의 기하학적 표지판과 상점 전면에서 영감을 받아, Julieta Ulanovsky는 20세기 초 도시 레터링의 정신을 담아내기 위해 이 서체를 만들었습니다. 깔끔한 원형 형태와 강한 기하학적 비례는 헤드라인, 브랜딩, 랜딩 페이지에 이상적인 단호한 존재감을 부여합니다. 가변 웨이트 축은 넓은 범위를 아우르며, 키릴 문자와 베트남어 문자도 포함됩니다.