Typography is one of the most important aspects of web design. CSS provides powerful properties to control fonts, making your text readable, accessible, and beautiful. Understanding font properties lets you create visual hierarchy, set the right tone, and enhance the overall user experience of your website.
font-family
The font-family property specifies which font to use for text. You can specify multiple fonts as a "fallback stack"—if the first font isn't available, the browser tries the next one.
Font Family Syntax
/* Single font */
.element {
font-family: Arial;
}
/* Font stack (fallback fonts) */
.element {
font-family: Arial, Helvetica, sans-serif;
}
/* Font names with spaces need quotes */
.element {
font-family: "Times New Roman", Times, serif;
font-family: "Segoe UI", Tahoma, sans-serif;
}
/* Generic font families (always put last) */
.element {
font-family: serif; /* Browser's default serif font */
font-family: sans-serif; /* Browser's default sans-serif font */
font-family: monospace; /* Browser's default monospace font */
font-family: cursive; /* Browser's default cursive font */
font-family: fantasy; /* Browser's default fantasy font */
}Font Categories
1. Serif Fonts
Have small decorative strokes (serifs) at the ends of letters. Traditional, formal, and good for print.
2. Sans-serif Fonts
Clean, modern fonts without decorative strokes. Great for screens and digital reading.
3. Monospace Fonts
Each character takes up the same width. Perfect for code and technical content.
4. Cursive Fonts
Mimic handwriting with flowing, connected letters. Use sparingly for decorative purposes.
5. Fantasy Fonts
Decorative, ornamental fonts. Best for headlines and special effects.
Web-Safe Font Stacks
These font combinations are available on most operating systems:
/* Sans-serif stacks */
.element {
/* Modern, clean */
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
"Helvetica Neue", Arial, sans-serif;
/* Classic sans-serif */
font-family: Arial, Helvetica, sans-serif;
/* Clean and modern */
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
}
/* Serif stacks */
.element {
/* Elegant serif */
font-family: Georgia, "Times New Roman", Times, serif;
/* Classic serif */
font-family: "Palatino Linotype", Palatino, "Book Antiqua", serif;
}
/* Monospace stacks */
.element {
/* Code-friendly */
font-family: "Courier New", Courier, monospace;
/* Modern monospace */
font-family: Consolas, Monaco, "Lucida Console", monospace;
}Font Family Examples
💡 Pro Tip:
Always end your font stack with a generic font family (serif, sans-serif, monospace) as a final fallback. This ensures your text will display in a font of the correct type even if none of your specific fonts are available.
font-size
The font-size property controls the size of text. It accepts various units including pixels, ems, rems, and percentages.
Font Size Units
/* Absolute units */
.element {
font-size: 16px; /* Pixels - fixed size */
font-size: 12pt; /* Points (print) */
}
/* Relative units */
.element {
font-size: 1em; /* Relative to parent font size */
font-size: 1.5em; /* 1.5 times parent font size */
font-size: 1rem; /* Relative to root (html) font size */
font-size: 2rem; /* 2 times root font size */
}
/* Percentage */
.element {
font-size: 100%; /* Same as parent */
font-size: 150%; /* 1.5 times parent */
}
/* Keyword values */
.element {
font-size: small;
font-size: medium; /* Browser default (usually 16px) */
font-size: large;
font-size: x-large;
font-size: xx-large;
font-size: smaller; /* Relative to parent */
font-size: larger; /* Relative to parent */
}Font Size Units
| Property | Values | Description |
|---|---|---|
px (pixels) | 16px, 24px | Fixed size. Easy to understand, not responsive. |
em | 1em, 1.5em | Relative to parent font size. Can compound in nested elements. |
rem | 1rem, 2rem | Relative to root (html) font size. Predictable, recommended. |
% | 100%, 150% | Percentage of parent font size. |
Keywords | small, medium, large | Predefined size keywords. |
Font Size Examples
em vs rem: The Difference
em vs rem Comparison
Best Practice: Use rem for most font sizes because it's predictable and doesn't compound. Use em only when you specifically want sizes relative to the parent element (like padding/margin proportional to font size).
font-weight
The font-weight property controls how thick or bold the text appears.
/* Keyword values */
.element {
font-weight: normal; /* Default (400) */
font-weight: bold; /* Bold (700) */
font-weight: lighter; /* Lighter than parent */
font-weight: bolder; /* Bolder than parent */
}
/* Numeric values (100-900) */
.element {
font-weight: 100; /* Thin */
font-weight: 200; /* Extra Light */
font-weight: 300; /* Light */
font-weight: 400; /* Normal/Regular */
font-weight: 500; /* Medium */
font-weight: 600; /* Semi Bold */
font-weight: 700; /* Bold */
font-weight: 800; /* Extra Bold */
font-weight: 900; /* Black/Heavy */
}Font Weight Values
Important: Not all fonts support all weight values. If a font doesn't have a specific weight (like 300 or 600), the browser will use the closest available weight or synthesize it, which may not look good. Always test your chosen fonts.
font-style
The font-style property controls whether text is italic, oblique, or normal.
/* Font style values */
.element {
font-style: normal; /* Default - upright text */
font-style: italic; /* Italic text */
font-style: oblique; /* Slanted text (synthesized if no italic) */
}Font Style Examples
Italic vs Oblique: Italic uses specially designed slanted characters, while oblique is just the normal font slanted at an angle. Most fonts look better with italic, but if a font doesn't have an italic version, the browser will use oblique automatically.
font-variant
The font-variant property controls the use of alternate glyphs, most commonly small-caps.
/* Font variant values */
.element {
font-variant: normal; /* Default */
font-variant: small-caps; /* Lowercase letters as smaller capitals */
}Font Variant Examples
Web Fonts
Web fonts allow you to use custom fonts beyond the system fonts installed on users' computers. The most popular source is Google Fonts, but you can also host your own fonts.
Using Google Fonts
Google Fonts provides hundreds of free, high-quality fonts. Here's how to use them:
- Visit fonts.google.com
- Choose a font and click "Select this style"
- Copy the
<link>tag and add it to your HTML<head> - Use the font in your CSS
<!-- 1. Add this to your HTML <head> -->
<head>
<!-- Import Roboto font -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
</head>/* 2. Use the font in your CSS */
body {
font-family: 'Roboto', sans-serif;
}
/* Multiple Google Fonts example */
body {
font-family: 'Open Sans', sans-serif;
}
h1, h2, h3 {
font-family: 'Playfair Display', serif;
}Popular Google Font Combinations
Popular Font Combinations
Self-Hosting Fonts with @font-face
You can also host font files on your own server using the @font-face rule:
/* Define custom font */
@font-face {
font-family: 'MyCustomFont';
src: url('fonts/MyCustomFont.woff2') format('woff2'),
url('fonts/MyCustomFont.woff') format('woff');
font-weight: normal;
font-style: normal;
font-display: swap; /* Improves loading performance */
}
/* Use custom font */
body {
font-family: 'MyCustomFont', Arial, sans-serif;
}
/* Multiple weights */
@font-face {
font-family: 'MyCustomFont';
src: url('fonts/MyCustomFont-Bold.woff2') format('woff2');
font-weight: bold;
font-style: normal;
}
/* Italic variant */
@font-face {
font-family: 'MyCustomFont';
src: url('fonts/MyCustomFont-Italic.woff2') format('woff2');
font-weight: normal;
font-style: italic;
}Font Formats: WOFF2 is the modern standard (best compression and performance). WOFF is the fallback for older browsers. Include both formats for maximum compatibility.
Font Loading Performance
Use font-display to control how fonts load:
@font-face {
font-family: 'MyFont';
src: url('font.woff2') format('woff2');
font-display: swap; /* Show fallback immediately, swap when loaded */
}
/* font-display options: */
@font-face {
font-display: auto; /* Browser default behavior */
font-display: block; /* Hide text briefly, then show with custom font */
font-display: swap; /* Show fallback, swap when loaded (RECOMMENDED) */
font-display: fallback; /* Show fallback, swap if loads quickly */
font-display: optional; /* Use custom font only if cached */
}⚡ Performance Tip:
Use font-display: swap for better performance. This shows text immediately with a fallback font, then swaps to your custom font when it loads. This prevents invisible text (FOIT - Flash of Invisible Text) and improves perceived performance.
Font Shorthand Property
The font shorthand combines multiple font properties into one declaration:
/* Shorthand syntax */
.element {
font: [font-style] [font-variant] [font-weight] font-size/line-height font-family;
}
/* Examples */
.element {
/* Only required: font-size and font-family */
font: 16px Arial;
/* With line-height */
font: 16px/1.5 Arial;
/* Full syntax */
font: italic small-caps bold 16px/1.5 Georgia, serif;
}
/* Common patterns */
.element {
/* Normal weight, 16px size, Arial font */
font: 16px Arial, sans-serif;
/* Bold, 20px, with line-height */
font: bold 20px/1.6 "Helvetica Neue", Helvetica, sans-serif;
/* Italic, 18px */
font: italic 18px Georgia, serif;
}Important: When using the font shorthand, you must include at least font-size and font-family. Any omitted properties reset to their default values. Use with caution!
Typography Best Practices
1. Establish a Type Scale
Use consistent font sizes throughout your site:
/* Recommended type scale */
:root {
--font-size-xs: 0.75rem; /* 12px */
--font-size-sm: 0.875rem; /* 14px */
--font-size-base: 1rem; /* 16px */
--font-size-lg: 1.125rem; /* 18px */
--font-size-xl: 1.25rem; /* 20px */
--font-size-2xl: 1.5rem; /* 24px */
--font-size-3xl: 1.875rem; /* 30px */
--font-size-4xl: 2.25rem; /* 36px */
--font-size-5xl: 3rem; /* 48px */
}
body {
font-size: var(--font-size-base);
}
h1 {
font-size: var(--font-size-4xl);
}
h2 {
font-size: var(--font-size-3xl);
}
small {
font-size: var(--font-size-sm);
}2. Limit Font Families
- Use 2-3 font families maximum
- One for headings, one for body text
- Keep it simple and consistent
3. Consider Readability
/* Optimal body text settings */
body {
font-size: 16px; /* Minimum for body text */
line-height: 1.6; /* 1.5-1.8 is optimal */
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
/* Paragraph width for readability */
p {
max-width: 70ch; /* 60-75 characters per line */
}
/* Adequate contrast */
body {
color: #333; /* Dark gray on white */
background: white;
}
/* Don't use pure black on pure white */
body {
color: #1a1a1a; /* Better than #000 */
}4. Load Fonts Efficiently
- Only load the font weights you actually use
- Use
font-display: swapfor better performance - Consider system fonts for faster loading
- Subset fonts to include only needed characters
Modern System Font Stack
For maximum performance, consider using system fonts that are already installed on users' devices:
/* Modern system font stack */
body {
font-family:
-apple-system, /* macOS/iOS */
BlinkMacSystemFont, /* macOS/iOS */
"Segoe UI", /* Windows */
Roboto, /* Android */
"Helvetica Neue", /* macOS */
Arial, /* Fallback */
sans-serif; /* Generic fallback */
}
/* Monospace system font stack */
code, pre {
font-family:
ui-monospace,
"SF Mono",
Consolas,
"Liberation Mono",
Menlo,
Monaco,
monospace;
}Advantages of system fonts:
- Zero loading time (already installed)
- No additional HTTP requests
- Native look and feel on each platform
- Excellent readability (optimized for each OS)
Key Takeaways
- font-family specifies which font to use with fallback stacks
- font-size controls text size (use rem for scalability)
- font-weight controls text thickness (100-900 or keywords)
- font-style controls italic/oblique text
- Always include generic font family as final fallback
- Use
remfor font sizes (predictable, doesn't compound) - Google Fonts provides hundreds of free web fonts
@font-facelets you host custom fonts- Use
font-display: swapfor better loading performance - Limit font families to 2-3 maximum
- 16px minimum for body text, 1.5-1.8 line-height optimal
- System fonts provide best performance (no loading time)
What's Next?
Now that you've mastered font properties, you're ready to learn about Text Styling. In the next lesson, we'll explore properties like text-align, text-decoration, text-transform, line-height, letter-spacing, and more advanced text effects. You'll learn how to fine-tune your typography for maximum readability and visual appeal.
Typography is fundamental to web design—well-chosen fonts and sizes create visual hierarchy, improve readability, and set the tone for your entire website. Practice combining different fonts and weights to create beautiful, accessible typography!