Beginner · CSS basics · topic 18 of 64 · 25 min
Typography: fonts and readable text
Explanation
Choosing a font
font-family takes a list called a font stack. The browser uses the first font it has and falls back to the next. The last item should be a generic family: sans-serif, serif or monospace.
body {
font-family: system-ui, "Segoe UI", Roboto, "Noto Sans", sans-serif;
font-size: 1rem;
line-height: 1.5;
color: #1f2937;
}
h1, h2 { line-height: 1.2; }Web fonts
A web font is a font file the browser downloads, such as one from Google Fonts or a file you host yourself with @font-face. They give a brand its look, but each weight is another download, so use only the two or three weights you need.
@font-face {
font-family: "Inter";
src: url("/fonts/inter-variable.woff2") format("woff2");
font-weight: 100 900;
font-display: swap; /* show fallback text at once, swap when loaded */
}
body { font-family: "Inter", system-ui, sans-serif; }font-display: swap shows text immediately in a fallback font and switches when the web font arrives, so users on slow mobile data never stare at a blank page.
Indian scripts
If your page has Hindi, Tamil, Bengali or other scripts, choose fonts that support them, such as the Noto family (Noto Sans Devanagari, Noto Sans Tamil). Mark the language with lang, for example <p lang="hi">, so browsers and screen readers handle it correctly.
Size, weight, spacing
| Property | Example | Tip |
|---|---|---|
| font-size | 1rem, 1.25rem, 2rem | Body text at least 1rem (16px) on phones |
| font-weight | 400 normal, 600 semibold, 700 bold | Use weight for hierarchy, not only size |
| line-height | 1.5 | Unitless numbers scale with the font size |
| letter-spacing | 0.02em | Small changes only; good for all-caps labels |
| text-align | left, center | Centre short headings, keep long text left-aligned |
| text-transform | uppercase | Keeps the HTML in normal case for screen readers |
Line length
Very long lines tire the eye. A comfortable line holds about 45 to 75 characters. The ch unit is the width of the "0" character, so max-width: 65ch keeps paragraphs readable on wide screens.
Watch the lesson
Typography: fonts and readable text · 1/6
Typography is how your text looks, and most of a web page is text.
Prefer a video by a teacher? Find free videos on “css typography fonts line height web fonts tutorial” on YouTube ↗
In real life: A bilingual government notice
A district office publishes notices in English and Hindi. The developer uses Noto Sans and Noto Sans Devanagari with font-display: swap, wraps the Hindi part in lang="hi", sets body text to 1.125rem with line-height 1.6, and limits paragraphs to 65ch. Elderly citizens can read it comfortably on a phone, and the text grows when they enlarge their phone font size.
Practice (0/2 done)
Give the body a font stack that starts with system-ui and ends with sans-serif, a line-height of 1.5, and make paragraphs no wider than 65ch (max-width).
Write a function lineLengthOk(text, maxChars) that returns true when every line of text (lines are separated by "\n") has at most maxChars characters, and false otherwise.
Quick quiz
Read more (free)
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.