How to Fine-Tune Your Font Weights in CSS?

Learn about how different font weights are used and mapped in CSS

Most of the fonts that we use, come with different font weights. The ones you might have come across frequently are bold and normal (or regular). In this article, we will explore different font weights available in CSS and learn what those weights imply visually.

Font Weight Declaration in CSS

In CSS, we have the following weight values that we can declare for a font (given, of course, that the font family actually has those weight variants / faces otherwise the font weight is substituted):

CSS Value Description
100 Thin
200 Extra-light (Ultra Light)
300 Light
400 Normal (Regular)
500 Medium
600 Semibold (Demibold)
700 Bold
800 Extra Bold (Ultra Bold)
900 Black (Heavy)
normal Normal (equivalent of numeric font-weight value 400 in CSS)
bold Bold (equivalent of numeric font-weight value 700 in CSS)
bolder One font weight darker than the parent element
lighter One font weight lighter than the parent element
  • You may see different descriptions for these font weights in different places, that is because there is no accepted, universal meaning to these weight names / values. The general idea is that you understand that their primary role is to distinguish faces of differing darkness within a single font family.
  • If you wish to have finer control over the exact weight values used for a given element you should avoid using relative font weights (i.e. lighter and bolder) and use numeric values instead.
  • In typography, each weight is a separate typeface designed by typographer. For most fonts commonly used on web pages, only a few of font weights are available (most often just 400 and 700, or maybe just 400).

What Happens If a Font Weight Is Missing?

Quite often there are only a few weights available for a particular font family. When a weight is specified for which no face exists, a face with a nearby weight is used based on the following rules:

Font Weight Substitute Selection Algorithm
100 - 300 Weights below the specified weight are checked in descending order followed by weights above the specified weight in ascending order until a match is found.
400 500 is checked first; if not found then weights below 400 are checked in descending order (i.e. 300 - 100) followed by weights above 500 in ascending order (i.e. 600 - 900) until a match is found.
500 400 is checked first; if not found then weights below 400 are checked in descending order (i.e. 300 - 100) followed by weights above 500 in ascending order (i.e. 600 - 900) until a match is found.
600 - 900 Weights above the specified weight are checked in ascending order followed by weights below the specified weight in descending order until a match is found.

Faux Bold:

If a font family does not contain a specified font weight, some CSS3-compatible browsers may synthesize the appearance of text for the purpose of style matching (i.e. they will try to create the weight themselves). This should be avoided, as this may create an unexpected look across different browsers which might not be the look we expect. To explicitly avoid this behavior the font-synthesis property can be used in CSS3. This property controls whether the browser is allowed to synthesize bold (or oblique) font faces when a font family lacks bold (or italic) faces. The following code illustrates the use of this property:

/* prevent browser from synthesizing bold and italic */
font-synthesis: none;

Please check browser compatibility / support before relying on the font-synthesis property.


A few things answered that you may be wondering:

Why Are There Only 9 Numeric Values for the font-weight Property?

The scale of 9 weights has been selected to cover all traditional typographic weights.

Why Can't We Use String Values to Define CSS Font Weight?

The numeric values are neutral and can be used independently of the naming scheme of a font.

Why Do the CSS Font Weight Numeric Values Start From 100 and Not From 1?

The font scale of 100 through 900 was introduced by TrueType font format, where 400 is regular (roman or plain). The same scale is also used in CSS and OpenType font format.

Hope you found this post useful. It was published (and was last revised ). Please show your love and support by sharing this post.