DevPath · Learn to code ESPTEN

Typography, color and effects

Typography: giving the text a voice

The detail that separates "amateur" from "pro"

Put two websites side by side. The one that looks real rarely wins by having more stuff: it wins on typography, color, and a touch of effects. It's what you notice without being able to name it. And here you have an edge: every change shows up instantly.

90% of the web is text, so that's where we start. Choosing the right typeface and its rhythm is what makes a design feel professional, and CSS controls the font with a handful of very expressive properties.

font-family and font stacks

font-family indicates which font to use. You never give just one: you offer a fallback list (font stack), like a plan B, C, and D. The browser tries from left to right until it finds one that is installed, and ends with a generic family (serif, sans-serif, monospace).

body {
  font-family: "Inter", "Helvetica Neue", Arial, sans-serif;
}
code {
  font-family: "Fira Code", Consolas, monospace;
}

Names with spaces go in quotes. The final generic is your safety net: there will always be something readable.

Size, weight and style

h1 {
  font-size: 2.5rem;    /* size (rem = relative to the root) */
  font-weight: 700;     /* thickness: 400 normal, 700 bold */
  font-style: italic;   /* normal | italic */
}

Vertical and horizontal rhythm

p {
  line-height: 1.6;        /* leading: 1.4–1.7 reads best */
  letter-spacing: 0.02em;  /* spacing between letters */
  text-align: justify;     /* left | right | center | justify */
}

A unitless line-height (1.6) is proportional to the font size: this is the recommended approach, because it adapts to each element.

⚠️ Classic trap: forgetting line-height. Text with cramped lines is tiring to read even with a gorgeous font. Give it room: 1.5–1.7 on long paragraphs and you'll feel the difference.

Web fonts (general idea)

System fonts are limited. To use a custom font you download it with @font-face or from a service like Google Fonts:

/* Option 1: declare it yourself with @font-face */
@font-face {
  font-family: "MyFont";
  src: url("/fonts/myfont.woff2") format("woff2");
}

/* Option 2: import from Google Fonts */
@import url("https://fonts.googleapis.com/css2?family=Inter&display=swap");

Once loaded, you use it like any other in font-family. At a high level: the font is just another resource the browser downloads before painting the text.

⚠️ Classic trap: throwing in five typefaces "because they look cool." Two well-chosen ones (one for headings, one for body text) carry more weight than a font circus. Less is more.

Examples

A font stack with good leading

body {
  font-family: "Inter", Helvetica, Arial, sans-serif;
  line-height: 1.6;
  font-size: 1rem;
}
Put this into practice

DevPath is a hands-on course: you read the theory here; in the app you put it into practice with exercises that really run, offline.

Start free in the app →
Color in depth: hex, rgb and hsl →