🎨 Typography: Custom Web Fonts
The Magic of Bringing Your Own Fonts to the Web
Imagine you’re writing a story. You want it to look special, not like everyone else’s story. The words on the web usually come from a small box of crayons that every computer already has. But what if you could bring your own special crayons from home?
That’s what custom web fonts do! They let you use any font you want on your website, even fonts that aren’t already on someone’s computer.
🎭 The Analogy: The Font Delivery Truck
Think of fonts like ice cream flavors:
- Default fonts = Vanilla and Chocolate (everyone has them)
- Custom fonts = Unique flavors like Mango-Chili or Lavender-Honey (you need to bring them yourself!)
When you use custom fonts, you’re like an ice cream truck driver delivering your special flavors to every visitor’s computer!
📦 @font-face: Your Font Delivery Address
The @font-face rule is like writing a delivery label on a package. It tells the browser:
- What’s the font’s name? (The label)
- Where can I find it? (The address)
- What style is it? (Bold? Italic? Normal?)
The Simple Recipe
@font-face {
font-family: 'MySpecialFont';
src: url('fonts/special.woff2');
}
What Each Part Means
| Part | What It Does |
|---|---|
font-family |
Gives your font a name to use later |
src |
Tells browser where to find the font file |
A Real Example
@font-face {
font-family: 'Adventure';
src: url('fonts/adventure.woff2')
format('woff2');
font-weight: normal;
font-style: normal;
}
h1 {
font-family: 'Adventure', sans-serif;
}
What happens here:
- We name our font “Adventure”
- We tell the browser it’s at
fonts/adventure.woff2 - We say it’s
woff2format - We use it on all
<h1>headings!
📁 Web Font Formats: The Different Ice Cream Containers
Just like ice cream comes in cones, cups, and tubs, fonts come in different formats. Each format is like a different container—some browsers like certain containers better!
The Format Family
graph TD A["🎨 Web Font Formats"] --> B["WOFF2"] A --> C["WOFF"] A --> D["TTF"] A --> E["EOT"] B --> F["✅ Best! Smallest size"] C --> G["✅ Good backup"] D --> H["⚠️ Old but works"] E --> I["❌ Only old IE"]
Format Comparison
| Format | Size | Browser Support | Use It? |
|---|---|---|---|
| WOFF2 | Tiny 🏆 | Modern browsers | YES! First choice |
| WOFF | Small | All browsers | Yes, as backup |
| TTF | Big | Older browsers | Maybe, for safety |
| EOT | Medium | Only old IE | Rarely needed |
💡 The Golden Rule
Use WOFF2 first, WOFF second. That’s usually enough!
Providing Multiple Formats
@font-face {
font-family: 'Friendly';
src: url('fonts/friendly.woff2')
format('woff2'),
url('fonts/friendly.woff')
format('woff');
}
The browser reads top to bottom and uses the first format it understands. It’s like offering someone water or juice—they’ll pick what they can drink!
⏱️ font-display: How Fast Should the Font Show Up?
Here’s a problem: What if your special font takes a long time to download?
Should the website:
- Wait until the font loads? (Blank text!)
- Show ugly default font first, then switch?
- Never switch and just use whatever loaded?
The font-display property answers this question!
The Five Loading Styles
graph TD A["font-display Options"] --> B["auto"] A --> C["block"] A --> D["swap"] A --> E["fallback"] A --> F["optional"] B --> B1["Browser decides"] C --> C1["Wait for font<br>brief invisible text"] D --> D1["Show backup first<br>then swap"] E --> E1["Quick swap<br>or give up"] F --> F1["Only if fast<br>else skip"]
What Each Value Does
| Value | Behavior | Best For |
|---|---|---|
auto |
Let browser decide | When unsure |
block |
Hide text briefly, wait | Brand logos |
swap |
Show default, then switch | Body text |
fallback |
Quick swap or give up | Headlines |
optional |
Only if super fast | Nice-to-have fonts |
⭐ The Most Popular Choice: swap
@font-face {
font-family: 'Adventure';
src: url('fonts/adventure.woff2')
format('woff2');
font-display: swap;
}
Why swap rocks:
- Users see text immediately (no blank screen!)
- Font appears as soon as it loads
- Best experience for reading
🎯 Putting It All Together
Here’s a complete, real-world example:
/* Step 1: Define your custom font */
@font-face {
font-family: 'StoryBook';
src: url('fonts/storybook.woff2')
format('woff2'),
url('fonts/storybook.woff')
format('woff');
font-weight: 400;
font-style: normal;
font-display: swap;
}
/* Step 2: Use it! */
body {
font-family: 'StoryBook',
Georgia,
serif;
}
What This Does
- Names the font “StoryBook”
- Provides WOFF2 (best) and WOFF (backup)
- Says it’s normal weight, not italic
- Uses swap so text is never invisible
- Applies it to the whole page
- Falls back to Georgia if needed
🌟 Quick Tips for Success
✅ Do This
- Use WOFF2 as your first format
- Always add font-display: swap
- Include a fallback font like
sans-serif - Keep font files in a
/fonts/folder
❌ Avoid This
- Don’t use only TTF or EOT formats
- Don’t forget the
format()hint - Don’t skip the fallback font
- Don’t use too many custom fonts (slow!)
🎬 The Story So Far
You’ve learned three superpowers:
| Superpower | What It Does |
|---|---|
@font-face |
Brings custom fonts to your site |
| Font Formats | WOFF2 & WOFF are your best friends |
font-display |
Controls how fonts appear while loading |
You’re now a font delivery expert! 🚚✨
Every time someone visits your website, you’re giving them a special reading experience with fonts that make your content unique and beautiful.
🧠 Remember This
@font-face = “Here’s my special font!”
WOFF2 = “The smallest, fastest format!”
font-display: swap = “Show text now, pretty font later!”
You’ve got this! 🎉
