Beautiful women doing geeky stuff

CSS Fonts

Related Posts

07/09/2013 Categories: CSS Web Design

Notes from "CSS.Fonts" Eric A.Meyer

Probably not everybody knows that Times is not a font it's a font family - a combination of many variants called font faces (TimesRegular, TimesBold, TimesItalic, TimesBoldItalic,etc)


Generic Font Families
Serif fonts
These fonts are proportional (all characters in the font have different widths due to their various sizes) and have serifs - decorations.
Sans-serif fonts
These fonts are proportional and do not have serifs. 
Monospace fonts
Are not proportional (each character uses up the same amount of horizontal space as all the others). These fonts may or may not have serifs.
Cursive fonts
Look like a human handwriting or lettering. Decoration bigger than those in serif fonts.
Fantasy fonts
All the rest.


  • In your html you can use only generic Font Families:

body {font-family: serif;}

h1, h2, h3, h4 {font-family: sans-serif;}

code, pre, tt, kbd {font-family: monospace;}

p.signature {font-family: cursive;}

  • Or you can specify a font family:

h1 {font-family: Times;}

If user agent can find Times it will use it, if not, it will use a default font.
If user agent don’t find Times here h1 {font-family: Times, serif;} it will use font from the same generic family.


Best practices: use single or double quote if font name contains a symbol or consist of two words with space in between.


If you define style inline use different types of quotes:
<p style="font-family: 'New Century Schoolbook', Times, serif;">...</p>


@font-face {
font-family: "SwitzeraADF";
src: url("SwitzeraADF-Regular.otf");

  • Only those faces needed to render a document will be loaded
  • !font faces can only be loaded from the same origin as the style sheet so you can't directly use font from someone’s else site
  • In case of font-face, font-family is not a property anymore but a descriptor.
  • If you want to be sure the user agent use correct font, add format() - user agents skip pulling files in formats that they don’t support - better speed and performance.

@font-face {
font-family: "SwitzeraADF";
src: url("SwitzeraADF-Regular.otf") format("opentype");


Font format values:

embedded-opentype Format: EOT (Embedded OpenType)
opentype Format: OTF (OpenType)
svg FOrmat: SVG (Scalable Vector Graphics)
truetype Format: TTF (TrueType)
woff Format: WOFF (Web Open Font Format)


  • You can also add name of the font to the src if font is stored on users machine.

@font-face {
font-family: "SwitzeraADF";
src: url("SwitzeraADF-Regular.otf") format("opentype"),
local("SwitzeraADF-Regular "):

  • Most efficient way to work in all browsers: “Bulletproof @font-face Syntax” developed by Paul Irish and refined by the FontSpring:

@font-face {
font-family: "SwitzeraADF";
src: url("SwitzeraADF-Regular.eot");
src: url("SwitzeraADF-Regular.eot?#iefix") format("embedded-opentype"),
url("SwitzeraADF-Regular.woff") format("woff"),
url("SwitzeraADF-Regular.ttf") format("truetype"),
url("SwitzeraADF-Regular.svg#switzera_adf_regular") format("svg");


EOT: IE6 to IE9
WOFF: most modern browsers
TIFF: iOS and Android
SVG: old iOS


font-style normal
font-weight normal
font-stretch normal (varying degrees of character widths: condensed - expanded)
font-variant normal (wide range of potential variant faces: small-caps)
font-feature-settings normal (direct access to low-level OpenType features: enabling ligatures)
unicode-range U+0-10FFFF Defines the characters for which a given face may be used (Ranges must always ascend unicode-range: U+04??, U+0500-052F, U+2DE0-2DFF ...;)


normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit


  • The CSS specification says that each number corresponds to a weight at least as heavy as the number that precedes it.
  • If you have less than 9 weights in a font family, numbers from 100 to 900 are assigned to existing weights.
  • If you use {font-weight: bolder;}, then the user agent checks what font-weight value was inherited from the parent element and (unless its 900) he adds one number higher. 
  • You can also use {font-weight: lighter;}.

You can assign different weights in your @font-face using font-weight descriptor
@font-face {
font-family: "SwitzeraADF";
font-weight: 700;
src: url("f/SwitzeraADF-Bold.otf") format("opentype");
@font-face {
font-family: "SwitzeraADF";
font-weight: 300;
src: url("f/SwitzeraADF-Light.otf") format("opentype");


xx-small | x-small | small | medium | large | x-large | xx-large | smaller | larger
| <length> | <percentage> | inherit


  • Relation between the font-size property and what you see rendered deicded by a font's designer and it's set as an em square (em box) within the font itself.
  • There are seven absolute-size values which instead of being defined precisely are relative to each other: xx-small, x-small, small, medium, large, x-large, and xx-large.
  • The relative-size values are not limited by the absolute-size range - a font’s size can be pushed beyond the sizes for xx-small and xx-large (impossible with font-weight).
  • Instead of px use % or em (1em = 100%).
  • Font-size is inherited as the computed values not percentages (eg. element is 12px, modified by the value 135% to arrive at 16.2px - 16,2px is inherited.)
  • As with the relative-size keywords, percentages are effectively cumulative - if you have 3 elements nested in each other and you apply ol {font-size:20%;} each element will be 20% bigger than the previous!


Rounding for Display

  • Different browser and OS can give different results - always test.
  • e.g. Mono font: inherited font-size: medium in some browsers displayed as 16px in others as 13px
  • Cross browser solution:

p {font-size: medium;} /* the default value */
span {font-family: monospace, serif; font-size: 1em;}
<p>This is a 'p' with a <span>'span'</span> inside.</p>

  • Extra serif in the font-family triggers a switch that makes all browsers treat font-size: 1em as being 100% of the paragraph’s computed font-size, not a medium-derived value.
  • The font-size can be set using any length value. This are equivalents: {font-size: 36pt;}
p.two {font-size: 3pc;}
p.three {font-size: 0.5in;}
p.four {font-size: 1.27cm;}
p.five {font-size: 12.7mm;}

  • Font-size in px is the easiest but in some browsers and devices it doesn't resize so it’s not recommended.


Aspect Value

  • Aspect value is a number that results from dividing the x-height by the font-size (higher aspect value - more legibility) - solution is font-size-adjust .
  • Font-size-adjust keep legibility when user agent uses other font than yours rather than keeping the same font-size - if you don't know the aspect value use {font-size-adjust: auto;} (watch out cause default is {font-size-adjust: none;})



  • enables you to choose between normal, italic, and oblique.

italic | oblique | normal | inherit

  • Difference between italic (cursive, Kursive) text and oblique (Slanted, Incline): 

italic is not only lean but appearance of the letters is changed (especially with serif fonts) while oblique is a leaned version of a normal text.

  • BUT many fonts as well as many browsers don't make difference between italic and oblique.


Font Stretching

  • Font faces variants concerning narrowness of text

normal | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded | inherit 

  • BUT works only if the font family has defined wider and narrower faces (many don’t)!
  • The font-stretch descriptor can take all of the values of the font-stretch property except for inherit just like with font-style and font-weight.


Font Kerning 

  • decides about spacing between characters (different space between AD than AW), works only if font contain kerning data

auto | normal | none | inherit

  • {font-kerning:auto;} - user agent does whatever it think is best
  • {font-kerning:none;} - any information about spacing in the font is skipped
  • If you have letter-spacing and font-kerning, kerinig is done first and only then letter-spacing is applied



Values (CSS2.1): normal | small-caps
Values (Level 3): normal | none | [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> || stylistic(<featurevalue-name>) || historical-forms || styleset(<feature-value-name>#) ||
character-variant(<feature-value-name>#) || swash(<feature-value-name>) || ornaments(<feature-value-name>) || annotation(<feature-value-name>) || [ small-caps | all-small-caps | petite-caps | all-petite-caps | unicase |
titling-caps ] || <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> || ordinal || slashed-zero || <east-asianvariant-values> || <east-asian-width-values> || ruby ] | inherit


  • not much support for enabling font variants (and not every font support each variant!)
  • The font-variant descriptor allows you to put multiple values (i.e.)@font-face {font-variant: stacked-fractions titling-caps slashed-zero;} - important -what you type in font-face descriptor will overide whatever you put later i.e. in the p style!!



  • allows you to decide which OpenType font features will be used
  • Everything from font-feature-settings is covered in the font-variant descriptor which gives you a little extra comparing with the former, so use font-variant.

normal | <feature-tag-value># | inherit

  • You can put multiple features i.e. font-feature-settings: "liga" on, "smcp" on, "zero" on;
  • The exact format of a <feature-tag-value> value is:

<string> [ <integer> | on | off ]?

values are 0 (off) and 1 (on) - if there is no number 1 is assumed so this are equivalents:
font-feature-settings: "liga";
font-feature-settings: "liga" 1;
font-feature-settings: "liga" on;

  • All feature tags must be four ASCII characters long.
  • In the font-feature-settings descriptor you specified what you want to use in a space separated list.



  • allows you to decide how much synthesis you will or will not permit in the rendering of a page (it happens when font family is missing face for things like bold and user agent tries to synthesize face from what is available)

none | [weight || style] | inherit

  • {font-synthesis: none;} makes sure the user agent doesn't do any synthesis


Font property
[[ <font-style> || [ normal | small-caps ] || <font-weight> ]? <font-size> [ / <line-height> ]? <font-family>] | caption | icon | menu | message-box | small-caption | status-bar | inherit

  • !important font-size and font-family must always be present in a font declaration and must be listed in this order as the last two values, all the rest is optional
  • You can also add line-height as a value (even though it s a text and not font property) but put font-size always before line-height and separate them with /
  • If you use font as a shorthand property you can get some weird behavior.



  • used to take the font size, family, weight, style, and variant of elements of the operating system, and apply them to an element to make it blend in the OS of the user 


  • caption is used for captioned controls, such as buttons 
  • icon is used to label icons 
  • menu is used in menus (drop-down menus and menu lists)
  • message-box is used in dialog boxes
  • small-caption is used for labeling small controls
  • status-bar is used in window status bars

e.g. If you want your button to have the same font as buttons in OS use button {font: caption;}



Font Matching (matching of font families, weights, and variants)