Fonts set the voice of your website. A rounded, playful font feels friendly, a classic serif feels traditional and trustworthy, and a monospace font says "code". CSS lets you choose fonts, sizes and weights, and even load custom fonts from the web.
Fonts also affect speed and readability. Every custom font is a file the visitor has to download, and a font that looks great in a heading can be tiring to read in a long paragraph. In this lesson you'll learn how to pick fonts that look good, load quickly and fall back gracefully.
font-family and font stacks
body { font-family: "Inter", "Helvetica Neue", Arial, sans-serif; }This list is called a font stack. The browser uses the first font it has available and falls back to the next one if it doesn't. Always end the stack with a generic family:
| Generic | Looks like |
|---|---|
serif | Times-style, with small "feet" on the letters |
sans-serif | Clean, without feet (used by most websites) |
monospace | Every letter the same width (used for code) |
system-ui | The device's own interface font |
cursive, fantasy | Decorative (use sparingly) |
Font names that contain spaces need quotes, such as "Times New Roman".
Font size, weight and style
font-sizesets the size of the text, for example16px,1.25remorclamp(…). See CSS Units.font-weightsets the thickness:400is normal and700is bold. Values from100to900work if the font includes those weights.font-styleisnormaloritalic.
Most browsers use 16px as the default text size. Body text smaller than that becomes hard to read on phones, so treat 16px as a minimum for paragraphs.
The font shorthand
font: italic 700 1.25rem/1.4 Georgia, serif;The order is style, weight, size/line-height, then family. Size and family are required. Like other shorthands, it resets any part you leave out to its default.
Using web fonts
Google Fonts is the easiest way to use custom fonts: choose a font, copy the <link> tag into the <head> of your HTML, then use the font's name in font-family. To host font files yourself, use @font-face with a .woff2 file, which is the most compact font format.
Only load the weights you actually use. Each extra weight is another download, and a page that waits for fonts can show invisible text for a moment. This site uses Figtree for text and JetBrains Mono for code.
CSS Fonts Syntax
Font properties
h1 {
font-family: Georgia, serif;
font-size: 2.5rem;
font-weight: 700;
font-style: normal;
}CSS Fonts Summary
font-familytakes a stack of fonts; always end with a generic family.- Quote font names that contain spaces.
- Use
font-size,font-weightandfont-styleto control size, thickness and italics. - The
fontshorthand needs at least a size and a family. - Load web fonts with Google Fonts or
@font-face, and only the weights you need.
CSS Fonts Examples
Each example runs in the page. Edit the code and press Run to see what changes.
Generic families side by side
<p class="serif">Serif: The quick brown fox</p>
<p class="sans">Sans-serif: The quick brown fox</p>
<p class="mono">Monospace: The quick brown fox</p>
<p class="ui">System UI: The quick brown fox</p>p { font-size: 20px; margin: 6px 0; }
.serif { font-family: Georgia, "Times New Roman", serif; }
.sans { font-family: Arial, Helvetica, sans-serif; }
.mono { font-family: "Courier New", monospace; }
.ui { font-family: system-ui, sans-serif; }Line-by-line explanation
- Lines 3 to 6Each font stack lists specific fonts, then a generic family as the safe fallback.
Using a Google Font
The @import loads the font from Google. On a real site, use the <link> tag Google gives you in your HTML head instead, because it's faster.
<h1>Cosmic Pancakes</h1>
<p>Fluffy, golden and slightly out of this world.</p>@import url("https://fonts.googleapis.com/css2?family=Fredoka:wght@400;700&display=swap");
h1 {
font-family: "Fredoka", sans-serif;
font-weight: 700;
font-size: 2.6rem;
color: #7c3aed;
}
p {
font: 400 1.1rem/1.6 "Fredoka", sans-serif;
}Line-by-line explanation
- Line 1Load the "Fredoka" font in weights 400 and 700.
- Line 4Use it, with
sans-serifas backup while it loads. - Line 11The shorthand: weight 400, size 1.1rem, line-height 1.6, then the family.
Common CSS Fonts Mistakes
No generic fallback
body { font-family: "Fancy Font"; }body { font-family: "Fancy Font", sans-serif; }If the font fails to load, the browser falls back to its default, which is often Times New Roman.
Faking bold with a weight the font doesn't have
/* only weight 400 was loaded from Google Fonts */
h1 { font-family: "Fredoka"; font-weight: 800; }/* load the weights you use: ...family=Fredoka:wght@400;700... */
h1 { font-family: "Fredoka"; font-weight: 700; }Browsers fake missing weights by smearing the letters, which looks blurry. Load the weights you need.
CSS Fonts in Real Projects
Fonts and performance
Every font file is a download. Professional sites load only the weights they use, use the modern .woff2 format, and add font-display: swap (the &display=swap in Google's URL) so text appears immediately in a fallback font instead of staying invisible.
CSS Fonts Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Give the heading a serif font stack and make it bold.
h2 {
: Georgia, ;
font-weight: ;
}
Which generic family should code use?
Why do font names like "Open Sans" need quotes?
The heading should use a bold Courier monospace stack and be 28px. The font shorthand is in the wrong order. Fix it.
<h1 class="code-title">console.log("hi")</h1>.code-title {
font: "Courier New", monospace 28px bold;
}- It's bold
- Size is 28px
- Uses a monospace stack
CSS Fonts Quiz
3 questions to check what you learned.
What is
font-weight: 700the same as?- bold
- normal
- light
- italic
In a font stack, which font does the browser use?
- The last one
- The first one it has available
- A random one
- All of them blended
Which two values are required in the
fontshorthand?- weight and style
- family and line-height
- style and size
- size and family
CSS Fonts Challenge
Pair two fonts
Create a classic font pairing:
h1usesGeorgia, serifat2.4rem, weight700pusesArial, sans-serifat1.1rem.smallusesfont-style: italic
<h1>The Daily Post</h1>
<p>Local news, grown fresh every morning.</p>
<p class="small">Est. 2026</p>- h1 uses Georgia serif
- h1 is 2.4rem (38.4px)
- h1 is bold
- p uses a sans-serif stack
- p is 1.1rem (17.6px)
- .small is italic