Most of what’s on a web page is text, so how that text looks goes a long way toward whether a site feels polished or amateur. Good typography is mostly invisible — nobody notices it, they just find the page easy to read. Bad typography you feel right away: cramped lines, a harsh font, text that’s too small or too washed out.
The good news is that getting text to look right in CSS takes surprisingly little. A handful of properties cover most of what you’ll need. This article walks through them, then shows how to bring in custom fonts.
Choosing a font: font-family
The font-family property sets which typeface to use. You can list several, separated by commas, and the browser picks the first one that’s available:
body {
font-family: "Helvetica Neue", Arial, sans-serif;
}
That list is called a font stack, and each comma means “try this one; if it’s not there, move on to the next.” The browser reads left to right until it lands on a font the user actually has. The last item should always be a generic family as the final fallback:
sans-serif— clean fonts with no little “feet” on the letters (like Arial). Common for screens.serif— fonts with small decorative strokes (like Times). Often used for long-form reading.monospace— fonts where every character is the same width (like Courier). Used for code.
Always end your font stack with one of these generics. That way, even if every named font is missing, the browser still falls back to something sensible from the right category.
Font size and weight
Two properties cover the most basic adjustments. font-size sets how big the text is:
p {
font-size: 16px;
}
You’ll come across a few units for this. px (pixels) is simple and fixed. You’ll also see rem a lot — a unit measured relative to the page’s base font size. 1rem equals the root font size (16px by default), so 1.5rem is 1.5× that. People reach for rem because it scales nicely and respects the user’s own font-size setting, which is better for accessibility.
font-weight controls how bold the text is:
h1 {
font-weight: 700; /* bold */
}
p {
font-weight: 400; /* normal */
}
Weights run from 100 (thin) to 900 (heavy) in steps of 100. 400 is normal and 700 is bold, and you can also just write the keywords normal and bold. Not every font ships every weight, so stick to the ones your chosen font actually provides.
Line height: the secret to readable text
Here’s a property that punches way above its weight for beginners: line-height. It controls the vertical space between lines of text. Without enough of it, paragraphs feel cramped and quickly become tiring to read:
p {
line-height: 1.6;
}
A unitless value like 1.6 means “1.6 times the font size” — a comfortable, go-to choice for body text. Tight line height (around 1) suits big headings, but for paragraphs you usually want something in the 1.5–1.7 range. This one property does a surprising amount to make text feel easy and pleasant to read.
Generous line height makes text far more readable
If your paragraphs feel dense and hard to read, line-height is almost always the fix. Bumping body text up to around 1.6 gives the eyes room to travel from one line to the next and makes a page feel instantly more comfortable. It’s about the highest-impact, lowest-effort typography tweak there is. Use a unitless number (like 1.6) rather than a fixed pixel value, so it scales properly with the font size.
Aligning and spacing text
A few more properties fine-tune how text sits on the page. text-align handles horizontal alignment:
h1 {
text-align: center;
}
Your options are left (the default), right, center, and justify (stretches lines to reach both edges — use it sparingly, since it can open up awkward gaps between words).
Other handy text properties:
.label {
text-transform: uppercase; /* MAKES TEXT UPPERCASE */
letter-spacing: 1px; /* space between letters */
text-decoration: underline; /* or none, to remove link underlines */
}
text-transformchanges capitalization (uppercase,lowercase,capitalize) without touching your HTML.letter-spacingadds or removes space between letters — a touch of it can make headings feel more refined.text-decorationadds or removes underlines, most often astext-decoration: noneto strip the default underline off links.
Using custom web fonts
The fonts we’ve used so far are “system fonts” — ones already installed on the user’s device. But you’re not stuck with those. Web fonts let you use almost any typeface by having the browser download it on the fly. The easiest place to start is a free service like Google Fonts.
You drop a <link> to the font into your HTML’s <head> (the font service hands you this exact line to copy):
<link href="https://fonts.googleapis.com/css2?family=Inter&display=swap" rel="stylesheet" />
Then you reference the font by name in your CSS, with a fallback as always:
body {
font-family: "Inter", sans-serif;
}
Now your whole site uses Inter, downloaded automatically for every visitor. This is how sites pull off a distinctive, consistent look.
Don't load too many fonts
Every web font is a file the browser has to download, and that adds to your page’s load time. Two font families — say, one for headings and one for body text — is plenty for most sites. Loading five different fonts and a dozen weights just slows the page down and rarely looks any better. Keep it lean: pick one or two good fonts, and only the weights you actually use.
A solid typographic baseline
Pulling it all together, here’s a sensible set of text styles to start almost any project with:
body {
font-family: "Inter", Arial, sans-serif;
font-size: 16px;
line-height: 1.6;
color: #1a1a1a;
}
h1 {
font-size: 2rem;
font-weight: 700;
line-height: 1.2;
}
That gives you readable body text with comfortable spacing and a clear, bold heading. From this baseline you can tweak to taste — but starting from good defaults means your text reads well from the very first line.
Wrapping up
You can now make text look intentional and read comfortably:
font-familysets the typeface via a font stack (comma-separated list ending in a generic likesans-serif).font-sizesets the size (pxis fixed;remscales with the base size and is better for accessibility).font-weightsets boldness (100–900;400normal,700bold).line-height(around1.6for body text) is the key to readable paragraphs.text-align,text-transform,letter-spacing, andtext-decorationfine-tune alignment and styling.- Web fonts (e.g. Google Fonts via a
<link>) let you use custom typefaces — but keep the number of fonts small for performance.
With color, the box model, and now typography under your belt, you can style individual elements really well. The next two articles tackle the big one: layout — arranging those elements across the page. We’ll start with Flexbox, the modern tool for laying things out in rows and columns without the headache.