Search code examples
cssfonts

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

  • 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

    And it's important to note 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.

    (Also note that while CSS4 will the way the numbers work such that you can use 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)

    So 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 will probably get you whatever is that font family's Regular typeface, and a font weight of 700/bold will probably 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");
    }
    

    The most important part is that how CSS uses font weight numbers only applies to CSS. It has literally nothing to do with font weights that are stored in the actual font file(s), or as you might see in word processing software, etc.