Understanding CSS font-weight: Numeric vs Keyword Values and Browser Matching

This article explains the differences between numeric (100‑900) and keyword (normal, bold, bolder, lighter) font-weight values, shows how browsers match unavailable weights using the CSS font‑matching algorithm, and provides practical examples and recommendations for developers.

Aotu Lab
Aotu Lab
Aotu Lab
Understanding CSS font-weight: Numeric vs Keyword Values and Browser Matching

Problem Statement

CSS font-weight can be expressed as numeric values (100‑900) or as keywords ( normal, bold, bolder, lighter). This summary explains the exact differences and gives practical guidance on which form to use.

Understanding font-weight

According to the W3C Fonts specification, the property accepts the numeric range 100‑900 and the four keywords. The keywords normal and bold are defined to be equivalent to the numeric values 400 and 700.

Numeric values and their descriptive names

100 – Thin

200 – Extra Light (Ultra Light)

300 – Light

400 – Regular (Normal, Book, Roman)

500 – Medium

600 – Semi Bold (Demi Bold)

700 – Bold

800 – Extra Bold (Ultra Bold)

900 – Black (Heavy)

Some font families use slightly different mappings; for example Adobe Typekit treats “Heavy” as 800, and Photoshop/Sketch label “Ultra Light” as 100 and “Thin” as 200.

Most fonts provide only 4‑6 distinct weights, but 400 (normal) and 700 (bold) are guaranteed to exist in common families such as Arial, Helvetica, and Georgia.

Relative keywords bolder and lighter

These keywords compute a weight relative to the inherited weight of the parent element. The resulting weight is defined by the following table:

| Inherited value | bolder → weight | lighter → weight |
|-----------------|------------------|-----------------|
| 100             | 400              | 100             |
| 200             | 400              | 100             |
| 300             | 400              | 100             |
| 400             | 700              | 100             |
| 500             | 700              | 100             |
| 600             | 900              | 400             |
| 700             | 900              | 400             |
| 800             | 900              | 700             |
| 900             | 900              | 700             |

Font‑matching algorithm

If the requested numeric weight is not available in the font, browsers select the nearest available weight using the following rules:

If the desired weight is less than 400, the browser checks lower weights in descending order first; if none are found, it checks higher weights in ascending order.

If the desired weight is greater than 500, the browser checks higher weights in ascending order first; if none are found, it checks lower weights in descending order.

If the desired weight is exactly 400, the browser prefers 500 first; if unavailable, it follows the “less than 400” rule.

If the desired weight is exactly 500, the browser prefers 400 first; if unavailable, it follows the “greater than 500” rule.

Practical examples

Official W3C example

The W3C specification diagram shows which weights are present (black) and which are missing (gray). Applying the algorithm yields the indirect matches shown below:

| Direct weight | Filled‑in weights |
|--------------|-------------------|
| 400          | 300, 200, 100, 500 |
| 700          | 600 |
| 900          | 800 |

For font-weight: 300; the font lacks a direct 300 weight. Because 300 < 400, the algorithm first looks downward (no match) then upward and selects 400.

Real‑world test – Google Fonts “Droid Sans”

Droid Sans provides only two weights: 400 and 700. The algorithm predicts the following mapping:

| Direct weight | Filled‑in weights |
|--------------|-------------------|
| 400          | 300, 200, 100, 500 |
| 700          | 600, 800, 900 |

Empirical testing with a simple HTML page confirms that values 100‑300‑500 render as the 400 weight, while 600‑800‑900 render as the 700 weight.

Conclusion

Most fonts contain only a few available weights; when a requested weight is missing, the browser selects the nearest weight using the font‑matching algorithm.

In practice, developers mainly use the normal (400) and bold (700) weights; both numeric and keyword forms are equivalent.

It is recommended to use numeric values instead of the relative keywords bolder and lighter, because numeric values make inheritance calculations explicit and clearer.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Web DevelopmentTypographyfont-weightfont matching
Aotu Lab
Written by

Aotu Lab

Aotu Lab, founded in October 2015, is a front-end engineering team serving multi-platform products. The articles in this public account are intended to share and discuss technology, reflecting only the personal views of Aotu Lab members and not the official stance of JD.com Technology.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.