'Why is the default font weight 400?

So, when working with fonts :

  • the default (aka "Regular") font weight is 400
  • the "bold" font weight is 700
  • the "light" font weight is 300

But... why ? 400 what ? Is this a sort of unit ? Is there a historical reason behind that ?



Solution 1:[1]

Not "400 what", just 400. As per the CSS specification, first formalized in https://www.w3.org/TR/CSS1/#font-weight. there are nine levels of font weight, represented as unitless numbers, starting at 100 and ending at 900, in 100 increments.

In addition to this, the spec defines two mappings between numerical value and string value:

  • the numerical value 400 and the string value normal are the same thing, and
  • the numerical value 700 and string value bold are the same thing

(Note that while CSS4 will change this to allow for the numbers 1-1000 in increments of 1, it will still only officially recognise the string values normal and bold, still mapping to 400 and 700 respectively. See https://drafts.csswg.org/css-fonts-4/#font-weight-prop for more information)

The only formal rules around these weights is that if you're using a font family in CSS context, a font weight of 400/normal should get you whatever is that font family's Regular typeface, and a font weight of 700/bold should get you whatever is the font family's Bold typeface. Anything else is left entirely undefined, and all you know is that 100, 200, and 300 are probably lighter than 400, 500 and 600 are probably in between regular and bold, and 800 and 900 are probably heavier than 700.

All of those are qualified as "probably" because @font-face gets to completely invalidate everything about this. If you use @font-face, you overrule CSS's rules for what those numerical values mean entirely. For example: this rule will effect an ultra-thin font when you set font-weight to 900, because that's what we're telling the browser it must do:

@font-face {
  font-family: MyFont;
  font-weight: 900;
  src: url("./fonts/ultra-thin.woff2") format("WOFF2");
}

Also important to know is that these are the only two official number/string mappings. Officially there are no other mappings, and the table of numerical values in https://drafts.csswg.org/css-fonts-3/#font-weight-prop is there purely to illustrate which real CSS values map to which rough names people tend to use for them.

The most important part is that this only applies to CSS. It has nothing to do with actual font-stored values, or things you see in word processing software, etc.

Solution 2:[2]

On the reason for no units

Font weights are not given a unit because with increasing and decreasing font weights there is no specific, identifiable "thing" that you are "turning up and down." In contrast to font-size, increases/decreases in font weight on computers have not traditionally been achieved programmatically - each level of font thickness has been needed to be hand-created by the font designer as a completely different typeface.

This is because it's much harder to programmatically change font weight than it is to change, say, size. Bolding text doesn't just add thickness to the entire character. It adds contrast by selectively adding more thickness to certain parts of the letter than others. Notice on the font below how certain parts of the letter "a" grow very thick with a higher weight while other parts of the same letter don't grow nearly as much.

Kazimir Text typeface.

This is not easy do programmatically, it's mostly had to be done by hand to have it look good - typographers would create a few different versions of their font - usually three - developers would upload all three styles, and the CSS font-weight property would be set up to only change between those three, usually at 300, 400, and 700. This is assuming you wanted real bold / italics. Faux styling - faux bold, faux italics, etc - has been provided by browsers, but the results have generally not been great.

Where things are moving now is towards variable fonts, introduced in 2016. These are fonts that are specifically designed to give developers full control over style attributes such as font weight and italicization. Essentially, font creators create several different variations of their typeface with different levels of weight, and the computer then intelligently fills in the spaces in between so that developers now have potentially infinite degrees of font-weight to use for a given font.

Even with this change, though, it's hard to pin down a specific, scientifically measurable "thing" that makes text more or less heavy. So I doubt that we'll see any non-relative unit introduced for font-weight any time soon.

On the reason for multiples of 100 and default of 400

The system is based off of the Linotype system that was developed for the Univers font in 1957. The idea was that you would use three digits to specify font-weight, width, and italicization, in that order. So 099 would be very light, very wide, and very italicized. 905 would be very heavy, very compressed, with medium italicization. This is just an example, the actual available values were different. People had more use of the 'weight' part of the system than the other two digits, so the second two digits were used less and less until they became vestigial and people forgot that the numbering system was used for anything other than specifying weights. It would indeed make more sense to have a 1-9 scale for font weight at this point, but 100-900 has now become conventional.

My guess is that 400 is the default simply because it's right in the middle. I would think that they chose 400 over 500 because people more often desire to bolden their text than to lighten it so they chose the default value that left more room for that.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2