Himanshu SharmaCOBOX Technologies
Let’s talk

CSS · Lesson 8 of 29

Fonts and text

Set font families with safe fallbacks, load web fonts, and control size, weight, line height, alignment, decoration and letter spacing for readable text.

13 minColour and textUpdated 16 October 2026

By the end of this lessonChoose and load fonts, then style headings and paragraphs so they are comfortable to read on any screen.

Text is most of the web

Most of what people do on a website is read. Good typography is not decoration: it decides whether visitors stay or leave. This lesson covers the properties you will use on every project.

font-family and fallbacks

css
body {
  font-family: "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

font-family takes a list. The browser uses the first font that is available and moves down the list if it is not. Names with spaces go in quotes. Always finish with a generic family:

Generic family Looks like
serif Letters with small feet, like many printed books
sans-serif Clean letters without feet, common on screens
monospace Every character the same width, for code
system-ui The operating system's own interface font

font-family: system-ui, sans-serif; is a popular modern choice: it needs no download and looks native on Windows, macOS, Android and iOS.

Web fonts

To use a font your visitors do not have installed, the browser has to download it. The simplest way is a hosted service such as Google Fonts, which gives you a <link> to paste into your head. You can also host the files yourself with @font-face:

css
@font-face {
  font-family: "Inter";
  src: url("/fonts/inter-var.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
}

body { font-family: "Inter", system-ui, sans-serif; }
  • WOFF2 is the modern, compressed font format; it is all you need for current browsers.
  • font-display: swap shows the text immediately in the fallback font, then swaps to the web font when it arrives. Without it, some browsers hide the text for a moment, which feels broken on slow connections.
  • Every weight and style is usually a separate file. Load only the ones you actually use; three or four files are plenty for most sites. A variable font (like the one above) packs a whole range of weights into one file.

Check the licence before using a font. Fonts from Google Fonts are free to use; many commercial fonts need a web licence.

Size, weight and style

html
<style>
  body { font-family: system-ui, sans-serif; }
  h2 { font-size: 2rem; font-weight: 700; line-height: 1.2; }
  .lead { font-size: 1.25rem; font-weight: 300; }
  p { font-size: 1.0625rem; line-height: 1.6; max-width: 65ch; }
  .note { font-style: italic; color: #555; }
</style>
<h2>Planning a weekend trek</h2>
<p class="lead">Everything you need for a safe two-day trek in the Western Ghats.</p>
<p>Start early, carry more water than you think you need, and tell someone your route before you leave. Most trails are easiest after the monsoon, from October to February.</p>
<p class="note">Check the forest department's rules for permits before you go.</p>
  • font-size: body text between 1rem and 1.125rem (16 to 18 pixels by default) is comfortable on most screens.
  • font-weight: numbers from 100 (thin) to 900 (black). 400 is normal and 700 is bold. If the font has no file for a weight, the browser fakes it or uses the nearest one.
  • font-style: italic or normal.
  • line-height: around 1.5 to 1.7 for paragraphs, tighter (1.1 to 1.3) for big headings. Write it without a unit.

Line length and alignment

Long lines are tiring: your eyes lose their place when jumping back to the start of the next line. Aim for roughly 60 to 75 characters per line, which max-width: 65ch gives you.

text-align takes left (the default for English), right, center or justify. Centre short headings and buttons if you like, but keep paragraphs left-aligned: centred paragraphs are hard to read, and justify creates uneven gaps between words on narrow screens.

Decoration, case and spacing

css
a { text-decoration: underline; text-underline-offset: 3px; }
.label { text-transform: uppercase; letter-spacing: 0.08em; font-size: 0.8rem; }
.deleted { text-decoration: line-through; }
  • text-decoration draws underlines and lines through text. Keep links underlined in body text: colour alone is not enough for colour-blind readers.
  • text-transform: uppercase changes how text is displayed without changing the HTML, so screen readers still read the original words. Write the text in normal case and let CSS do the capitals. (For changing the actual text, the Case Converter tool does it.)
  • letter-spacing: small uppercase labels look better with a little extra space; normal lowercase text rarely needs any.

The font shorthand

font sets several properties at once, in a fixed order: style, weight, size/line-height, family.

css
p { font: italic 400 1.125rem/1.6 Georgia, serif; }

It also resets any part you leave out to its default, so many developers prefer the separate properties for clarity.

Common mistakes

  • No generic fallback at the end of font-family.
  • Loading ten font files for weights and styles the design never uses.
  • Tiny, light grey text that looks stylish but is hard to read.
  • Full-width paragraphs on large screens; add max-width.
  • Typing headings in capitals in the HTML instead of using text-transform.

Exercise

Style a blog post: body text in system-ui with a sans-serif fallback at 1.0625rem and line height 1.65; headings in Georgia with a serif fallback, weight 700 and line height 1.2; paragraphs at most 65ch wide; and a small uppercase label above the title with extra letter spacing. Check the reading time of your test paragraph with the Word Counter.

Show one possible answer
css
body {
  font-family: system-ui, sans-serif;
  font-size: 1.0625rem;
  line-height: 1.65;
}

h1, h2 {
  font-family: Georgia, serif;
  font-weight: 700;
  line-height: 1.2;
}

article p { max-width: 65ch; }

.category {
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: 0.8rem;
}

Key points

  • font-family takes a list of fonts and must end with a generic family such as sans-serif or serif.
  • system-ui uses the device's own interface font, which is fast and looks native.
  • Web fonts load with @font-face or a stylesheet link; font-display swap shows fallback text while the font downloads.
  • Body text reads best at around 1rem to 1.125rem, line-height 1.5 to 1.7 and 60 to 75 characters per line.
  • Use numeric font-weight (400 normal, 700 bold) and only load the weights you use.

Check yourself

1. Why should a font-family list end with a generic family such as sans-serif?
2. What does font-display: swap do?
3. Which font-weight value means bold?
4. Which line-height is most comfortable for body text?

Free tools for this lesson