# Fonts and Text: Family, Size, Weight and Spacing

A handful of text properties (font-family with fallbacks, font-size, font-weight, font-style, line-height, text-align, text-transform, letter-spacing and text-decoration) turn plain words into text people can read at a glance.

Novice · CSS · Updated November 1, 2026

## After this lesson you can

- Choose a font with font-family and a list of fallbacks that ends in a generic family
- Set text size, weight, style and line spacing with font-size, font-weight, font-style and a unitless line-height
- Align and decorate text with text-align, text-transform, letter-spacing and text-decoration

## Key takeaways

- font-family takes a list of fonts. The browser uses the first one it has, so end the list with a generic family such as `sans-serif`.
- Size text in rem. `1rem` is the reader's normal text size, so your page follows their own browser setting.
- font-weight sets how bold text is (400 is normal, 700 is bold), and `font-style: italic` slants it.
- A line-height with no unit, such as `1.5`, sets the space between lines as a multiple of the text's own size.
- text-align, text-transform, letter-spacing and text-decoration line text up, change its capitals, space it out, and underline or cross it out.

A good menu board can be read from the sidewalk: big, bold names, prices that stand out, and enough room between the lines that your eye doesn't slip. A bad one is a wall of tiny, cramped letters, and people walk on by. Web pages work the same way. Most of what's on any page is text, so you'll use the properties in this lesson on everything you build: a résumé page, a class report, a blog, the Sol Taco Truck menu.

## font-family: a list, best choice first

Ordering at the truck window, you might say: "a horchata, please; if you're out, an agua fresca; if not, any cold drink." You get your first choice if they have it, and something close if they don't.

`font-family` works the same way. A browser can only use a font that's on the reader's device (or one the page sends along, which is the next lesson), so you give it a list, best choice first. That list is called a **font stack**, and the fonts after the first are its **fallbacks**:

```css
body {
  font-family: "Trebuchet MS", Verdana, sans-serif;
}

h1 {
  font-family: Georgia, "Times New Roman", serif;
}
```

Put quotes around a font name that has spaces in it, such as `"Trebuchet MS"`. The last item in each list is a **generic family**, a kind of font that every browser has some version of, so the list always ends with a match:

| Generic family | What it looks like | Good for |
|---|---|---|
| `serif` | small strokes ("feet") at the ends of letters | a classic, bookish look |
| `sans-serif` | no feet: clean, plain letters | most body text on screens |
| `monospace` | every letter the same width | code, receipts, prices in columns |
| `system-ui` | the device's own interface font | pages that feel like an app |
| `cursive` | handwriting-like letters | a short, playful touch |

Generic family names never take quotes: `sans-serif`, not `"sans-serif"`. In quotes, the browser looks for a font actually named *sans-serif*.

**Try it.** In your `sol-taco-truck` page (or any page), give the `body` the first stack above. Then misspell the first font, as `"Trebuchet"`: nothing breaks, and the browser moves on to Verdana. To see which font it really used, select some text in the developer tools' Elements panel and scroll to the bottom of the **Computed** pane: **Rendered Fonts** names it. (In Firefox, it's the **Fonts** pane.)

## font-size, and the rem unit

`font-size` sets how big the letters are. The unit that suits text best is **rem**, read "rem". `1rem` is the reader's normal text size, which is 16 pixels in most browsers unless the reader has changed it:

```css
body {
  font-size: 1.125rem;
}

h1 {
  font-size: 2.5rem;
}
```

The body text is 1.125 times the normal size, which is 18 pixels for most readers, and the heading 2.5 times, 40 pixels. Here's why rem beats pixels for text: someone who has set their browser to bigger text gets bigger text on your page too, because everything is measured from *their* normal size. With `font-size: 16px`, the size is fixed, whatever the reader asked for. (*Units: px, rem, em, % and Viewport Units*, in the next chapter, covers every unit.)

## font-weight and font-style

`font-weight` sets how bold text is, with a number: 100 is thin, 900 is very heavy, and most fonts come in steps of 100 between them. Two have names: `400` is `normal`, and `700` is `bold`. `font-style: italic` slants the letters, and `font-style: normal` straightens them again.

```css
.price {
  font-weight: 700;
}

.tagline {
  font-style: italic;
}
```

Every price turns bold, and the tagline under the truck's name leans to the right. A font comes with only some weights. Ask for one it doesn't have, and the browser uses the nearest one it has, or draws a fake bold or italic, which never looks quite as good as the real thing. The next lesson shows how to load the weights you need.

## line-height: room between the lines

Notebook paper comes wide-ruled and college-ruled: the same words, but on wide-ruled paper the lines sit farther apart. `line-height` is how far apart your lines of text sit. Give it a number with no unit, and it's a multiple of the text's own size:

```css
body {
  font-size: 1.125rem;
  line-height: 1.5;
}

h1 {
  line-height: 1.1;
}
```

For 18-pixel body text, `1.5` gives lines 27 pixels apart, a comfortable rhythm: body text reads well at about 1.4 to 1.6. Big headings look better tighter, around 1.1 to 1.2.

Why no unit? A number scales with each element's own size. Write `line-height: 24px` on the body instead, and every element inside it gets 24-pixel lines, including a 40-pixel heading, whose lines would then crash into each other if it wrapped onto two. With `1.5`, the heading gets lines 1.5 times *its* size.

**Try it.** Paste a long paragraph into your page (two or three menu descriptions in a row will do). Set its `line-height` to `1`, then `1.5`, then `2.5`, saving after each. Which reads best, and which makes the lines feel like they're floating apart?

## text-align, text-transform and letter-spacing

The truck's section headings are painted in capital letters, spaced out a little and centered. Three properties do that:

```css
h2 {
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
```

- **`text-align`** lines text up: `left` (the usual for English), `right`, `center`, or `justify`, which stretches each line to both edges.
- **`text-transform: uppercase`** shows text in capitals. The HTML still says *Tacos*: only the look changes, so if the design changes later, you change one line of CSS instead of retyping every heading. There's also `lowercase`, `capitalize` (a capital at the start of each word) and `none`.
- **`letter-spacing`** adds room between letters. `0.1em` is a tenth of the text's own size (an **em** is the size of the element's own font), so the spacing grows with the text. Capitals look better with a little extra room; lowercase body text is best left alone.

## text-decoration: underlines and cross-outs

`text-decoration` draws a line under, over or through text. The value you'll use most is `line-through`, for a price that has dropped:

```css
.old-price {
  text-decoration: line-through;
}

.menu-link {
  text-decoration: none;
}
```

```html
<p>Chicken tinga burrito <span class="old-price">$10.00</span> <span class="price">$8.50</span></p>
```

The old price is crossed out beside the new one, the way a sale sign shows it. `underline` adds an underline, and `none` takes one away, which is how sites remove the underline from links in a menu bar.

Take care with that last one. In a paragraph of text, the underline is how readers spot a link, and some people can't tell the link's color from the text around it. Keep links in your paragraphs underlined, and remove the underline only where it's clear from the design that something is a link, such as a menu bar of buttons.

## Check yourself

2 questions to try on the lesson page.

## So what

Text is most of every page you'll build. A font stack with a fallback, sizes in rem, a unitless line-height and a few finishing properties make the difference between a page people read and a page they leave.

## Key terms

- [Font family](https://www.ask-codey.com/glossary/font-family)
- [Font fallback](https://www.ask-codey.com/glossary/font-fallback)
- [Font size](https://www.ask-codey.com/glossary/font-size)
- [Font weight](https://www.ask-codey.com/glossary/font-weight)
- [Line height](https://www.ask-codey.com/glossary/line-height)
- [Text transform](https://www.ask-codey.com/glossary/text-transform)

## Cheat sheets

- [Fonts and Text: Family, Size, Weight and Spacing](https://www.ask-codey.com/cheat-sheets/css-fonts-and-text-cheat-sheet)

## Related

- [Web Fonts: Using Any Font You Like](https://www.ask-codey.com/lessons/css-web-fonts)
- [Color: Names, Hex, rgb() and hsl()](https://www.ask-codey.com/lessons/css-color-values)

Source: https://www.ask-codey.com/lessons/css-fonts-and-text
