CSS: Fonts & Typography

Control how text looks, from font choice to web font loading.

font-family and Font Stacks

font-family sets which font to use. Because a font may not be installed on every device, you provide a font stack, a comma-separated list of fallbacks ending with a generic family.

font-family

A font stack lists your preferred font first, followed by fallbacks. The browser uses the first font it can find. The last value is always a generic family name as a final safety net.

  • serif: fonts with small strokes at the end of characters (Times New Roman)
  • sans-serif: fonts without serifs (Arial, Helvetica)
  • monospace: every character is the same width (Courier, Consolas)
  • cursive / fantasy: decorative fonts; rarely used for body text
  • Font names with spaces must be quoted: 'Times New Roman'

Font Stacks

Three font families, each with fallbacks ending in a generic family.

font-size and font-weight

font-size sets how large the text is. font-weight sets how thick or thin the characters are, from hairline to heavy.

font-size / font-weight

font-size accepts any CSS length unit. rem is preferred for accessibility. font-weight accepts numeric values (100–900) or keywords like bold and normal.

  • font-size: 1rem: relative to root font size; scales with user preferences
  • font-weight: 400: normal weight
  • font-weight: 700: bold (same as the bold keyword)
  • font-weight: 100–900: nine numeric steps; available steps depend on the font
  • Not all fonts include every weight, missing weights fall back to the nearest available

font-size and font-weight

Different sizes and weights side by side.

font-style (italic, oblique)

font-style controls whether text is displayed in a normal, italic, or oblique form.

font-style

italic uses a specifically designed italic version of the font. oblique simply slants the normal font when no true italic version exists.

  • normal: default upright text
  • italic: uses the font's built-in italic design if available
  • oblique: artificially slants the normal font when italic is unavailable
  • Most fonts have a true italic variant, prefer italic over oblique
  • Use font-style: normal to cancel inherited italic (e.g. inside a tag)

font-style

Normal, italic, and oblique on the same font.

Web Fonts (@font-face)

@font-face lets you load a custom font file from your server so every visitor sees the same typeface, regardless of what fonts they have installed.

@font-face

@font-face registers a font under a name you choose, then you use that name in font-family just like any other font.

  • font-family: the name you give the font to reference it in CSS
  • src: url(): path to the font file on your server
  • format(): hint to the browser: 'woff2', 'woff', 'truetype'
  • woff2: best format; smallest file size; supported by all modern browsers
  • Always provide woff2 first, it is the most efficient web font format

@font-face

Register a custom font then reference it by the name you gave it.

Google Fonts and Font Services

Instead of hosting font files yourself, services like Google Fonts host them for you. You link to them in your HTML and they are ready to use in CSS.

Google Fonts

Google Fonts is the most popular free web font service. Add a <link> tag to your HTML and the font is immediately available as a font-family value.

  • Visit fonts.google.com, pick a font, copy the provided tag
  • rel='preconnect': add preconnect hints to speed up font loading
  • Specify only the weights you need, loading unused weights wastes bandwidth
  • Other services: Adobe Fonts, Bunny Fonts (privacy-friendly Google Fonts alternative)

Google Fonts

Three link tags, two preconnect hints and the font stylesheet.

Using Google Fonts in CSS

Reference the font by the exact name shown on Google Fonts.

font-display for Performance

When a web font takes time to download, the browser must decide what to show in the meantime. font-display inside @font-face controls this behaviour.

font-display

font-display prevents invisible text during font loading. swap is the most common choice, it shows a system fallback immediately and replaces it once the web font arrives.

  • swap: show fallback immediately, swap to web font when ready (recommended)
  • block: briefly hide text, then show web font (risks invisible text)
  • fallback: very short block period, then swap; if font loads late, keep fallback
  • optional: browser decides; often skips web font on slow connections
  • Google Fonts adds display=swap automatically when you use the query parameter

font-display: swap

swap prevents invisible text by showing a fallback while the font loads.

Variable Fonts

A variable font is a single font file that contains a continuous range of weights, widths, and other axes, instead of requiring a separate file for each weight. weights, widths, and other axes, instead of requiring a separate file for each weight.

Variable Fonts

Variable fonts use font-variation-settings to access any point on their supported axes. A single file replaces an entire family of separate weight files.

  • font-variation-settings: low-level control: font-variation-settings: 'wght' 650
  • font-weight: automatically maps to the variable font's weight axis
  • One file covers all weights, reduces total download size for multi-weight designs
  • Common axes: wght (weight), wdth (width), ital (italic), slnt (slant)
  • Check variable font support at v-fonts.com

Variable Fonts

One font file, any weight from 100 to 900.

System Font Stacks

A system font stack uses fonts already installed on the user's operating system, A system font stack uses fonts already installed on the user's operating system, no download required. Pages load instantly and text feels native to each platform.

System Font Stack

System fonts load instantly because they are already on the device. Each OS uses its own default UI font, the stack picks the right one for each platform.

  • -apple-system: San Francisco on macOS and iOS
  • BlinkMacSystemFont: San Francisco in Chrome on macOS
  • Segoe UI: Windows system font
  • Roboto: Android system font
  • system-ui: modern CSS keyword that picks the OS default automatically

System Font Stack

system-ui is the modern shorthand; the full stack covers all platforms.

Fallback Fonts

A fallback font is the font the browser uses when the primary choice is unavailable, A fallback font is the font the browser uses when the primary choice is unavailable, either not installed or still loading. Every font stack should end with a generic family as the final fallback.

Fallback Fonts

Fallbacks ensure text is always readable. When choosing fallbacks, pick fonts that are similar in size and shape to your primary font to minimise layout shift when the web font loads.

  • Always end every font stack with a generic family: serif, sans-serif, or monospace
  • Choose fallbacks with similar x-height and letter-spacing to your web font
  • Layout shift: when the fallback and web font differ in size, content reflows on swap
  • Layout shift: when the fallback and web font differ in size, content reflows on swap
  • size-adjust: CSS property to scale a fallback font to match the web font's metrics
  • Minimise layout shift by testing the swap visually in DevTools

Fallback Fonts

Web font → similar system font → generic family as the safety net.

Knowledge Check

1. What is the purpose of a font stack in CSS?

2. Which font-weight value renders text as bold?

3. What does @font-face do?

4. Which font-display value shows a fallback font immediately, then swaps to the web font when loaded?

5. What makes variable fonts different from regular web fonts?