CSS @font-face At-Rule

Beginner
⏱️ 7 min read
📚 Updated: Jul 2026
🎯 4 Examples
At-Rules

What You’ll Learn

The @font-face at-rule lets you load custom font files into your website. Define a family name, point to the font file, then use that name in font-family like any other font.

01

Custom fonts

Load your own.

02

font-family

Name the font.

03

src url()

Font file path.

04

WOFF2

Best format.

05

font-display

Loading behavior.

06

Fallbacks

Backup fonts.

Introduction

The @font-face at-rule in CSS lets web developers load custom font files on their websites. Without it, you are limited to fonts already installed on the user’s device or generic families like serif and sans-serif.

Definition and Usage

@font-face is not a CSS property — it is an at-rule, like @media or @charset. It registers a font family name and links it to one or more font files. Once registered, you reference that name in the font-family property on any selector.

This is how brand fonts, icon fonts, and downloadable typefaces reach every visitor consistently — regardless of what is installed on their computer or phone.

💡
Beginner Tip

Think of @font-face as “installing” a font for your webpage. You declare it once, then use the family name everywhere you would normally write font-family.

📝 Syntax

The basic syntax defines a font family name and where to find the font file:

syntax.css
@font-face {
  font-family: 'MyFont';
  src: url('fonts/myfont.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

After defining the font, apply it with font-family and always include fallback fonts:

usage.css
body {
  font-family: 'MyFont', system-ui, sans-serif;
}

Common Descriptors

DescriptorDescription
font-familyThe name you will use in font-family rules. Wrap multi-word names in quotes.
srcWhere to find the font: url() for files, local() for installed fonts, or both.
format()Hints the file type: woff2, woff, truetype, opentype.
font-weightWhich weight this file represents (e.g. 400 normal, 700 bold).
font-styleWhether the file is normal or italic.
font-displayControls text visibility while the font loads. swap is a good default.
woff2 preferred font-display: swap Always add fallbacks

Multiple Formats

List several src entries so older browsers can pick a supported format:

multi-format.css
@font-face {
  font-family: 'MyFont';
  src: url('myfont.woff2') format('woff2'),
       url('myfont.woff') format('woff');
}

⚡ Quick Reference

QuestionAnswer
TypeAt-rule (not a CSS property)
Required descriptorsfont-family and src
Best formatwoff2 for modern browsers
Apply the fontfont-family: 'MyFont', sans-serif;
Loading behaviorfont-display: swap shows text immediately
Bold / italicSeparate @font-face blocks per weight/style
Browser supportUniversal for @font-face; WOFF2 in all modern browsers

When to Use @font-face

Reach for @font-face when you need typography beyond system fonts:

  • Brand identity — Match your company’s official typeface on the web.
  • Design consistency — Ensure headings and body text look the same on every device.
  • Self-hosted fonts — Host font files on your own server instead of relying on a third-party CDN.
  • Custom weights — Load only the weights you need (e.g. 400 and 700) to keep file sizes small.
  • Icon fonts — Some icon sets are delivered as font files (though SVG icons are often preferred today).

Skip @font-face when system fonts or a service like Google Fonts (via <link>) already meet your needs and you do not need full control over hosting.

👀 Live Preview

Compare custom typography with system fonts and see how a fallback stack keeps text readable:

Custom serif (Georgia) Beautiful typography starts with the right font.
System UI sans-serif System fonts load instantly with no extra download.
Recommended fallback pattern font-family: 'MyFont', system-ui, sans-serif;

Examples Gallery

Practice @font-face with a basic declaration, WOFF2 loading, bold weight variants, and fallback font stacks.

🔠 Core Patterns

Start with a simple declaration, then load a real web font file.

Example 1 — Basic @font-face

Define a custom font family and apply it with font-family. This example uses local() so it works without downloading a file.

font-face-basic.css
@font-face {
  font-family: 'DemoSerif';
  src: local('Georgia');
}

body {
  font-family: 'DemoSerif', Georgia, serif;
  padding: 1.5rem;
  color: #1e293b;
}
Try It Yourself

How It Works

@font-face registers DemoSerif as a usable family name. The browser then applies it wherever you write font-family: 'DemoSerif'.

Example 2 — WOFF2 Web Font

Load a font file from a URL using src: url() and the woff2 format.

font-face-woff2.css
@font-face {
  font-family: 'Lato';
  src: url('fonts/lato.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
}

body {
  font-family: 'Lato', system-ui, sans-serif;
}
Try It Yourself

How It Works

The browser downloads the WOFF2 file, registers the Lato family, and applies it. font-display: swap shows fallback text until the file arrives.

🎨 Variants & Fallbacks

Load bold weights separately and always provide backup fonts.

Example 3 — Bold Weight Variant

Use separate @font-face blocks for regular and bold weights with matching font-weight values.

font-face-bold.css
@font-face {
  font-family: 'Lato';
  src: url('lato-400.woff2') format('woff2');
  font-weight: 400;
}

@font-face {
  font-family: 'Lato';
  src: url('lato-700.woff2') format('woff2');
  font-weight: 700;
}

h1 { font-weight: 700; }
p { font-weight: 400; }
Try It Yourself

How It Works

Each @font-face block maps one file to one weight. When you set font-weight: 700, the browser picks the bold file automatically.

Example 4 — Fallback Font Stack

Always list backup fonts after your custom family so text stays readable if loading fails.

font-face-fallback.css
@font-face {
  font-family: 'Lato';
  src: url('lato.woff2') format('woff2');
  font-display: swap;
}

body {
  font-family: 'Lato', system-ui, -apple-system, sans-serif;
  line-height: 1.6;
}
Try It Yourself

How It Works

The browser tries Lato first. If the file is missing or blocked, it moves to system-ui, then sans-serif.

💬 Usage Tips

  • Prefer WOFF2 — Smaller files and excellent browser support for modern sites.
  • Use font-display: swap — Avoid invisible text while fonts download.
  • Load only what you need — Include just the weights and styles your design uses.
  • Quote family names — Use quotes when the name contains spaces: 'Open Sans'.
  • Host fonts correctly — Place files in a fonts/ folder and use relative paths in src.

⚠️ Common Pitfalls

  • Forgetting fallbacks — Without backup fonts, failed loads can leave text in an unexpected typeface.
  • Wrong file paths — A broken url() silently falls back; always verify paths in DevTools Network tab.
  • Fake bold — Browsers may stretch a regular file if you skip the bold @font-face block.
  • Loading too many weights — Each file adds download time; trim unused variants.
  • Confusing with font-family@font-face registers the font; font-family applies it.

♿ Accessibility

  • Readable typefaces — Choose fonts with clear letter shapes for body text.
  • Adequate size and line-height — Custom fonts still need comfortable reading settings.
  • font-display: swap — Prevents long periods of invisible text (FOIT) that block reading.
  • Contrast — Font choice does not replace color contrast requirements.
  • Respect user preferences — Some users override fonts in browser settings; fallbacks help.

🧠 How @font-face Works

1

@font-face is parsed

The browser reads your @font-face block and registers the family name.

Register
2

Font file is downloaded

When an element uses that family, the browser fetches the file from src.

Download
3

font-display controls timing

With swap, fallback text shows immediately and updates when the font is ready.

Display
=

Custom typography applied

Text renders in your chosen typeface across devices.

🖥 Browser Compatibility

The @font-face at-rule has universal support in all modern browsers. WOFF2 is supported in all current Chrome, Firefox, Safari, Edge, and Opera versions.

Baseline · Universal support

@font-face + WOFF2

Custom web fonts work in every major browser. WOFF2 is the standard format for production sites.

100% @font-face rule
Google Chrome @font-face + WOFF2
Full support
Mozilla Firefox @font-face + WOFF2
Full support
Apple Safari @font-face + WOFF2
Full support
Microsoft Edge @font-face + WOFF2
Full support
Opera All modern versions
Full support
@font-face at-rule 100% supported

Bottom line: @font-face is safe for production. Use WOFF2 for file size and speed; keep WOFF only if you must support very old browsers.

🎉 Conclusion

The @font-face at-rule is essential for custom typography on the web. Define your font once with font-family and src, apply it with font-family on your elements, and always include fallback fonts for reliability.

Prefer WOFF2, use font-display: swap, and load only the weights you need. With these habits, your pages look polished without sacrificing performance or readability.

💡 Best Practices

✅ Do

  • Use WOFF2 as your primary font format
  • Set font-display: swap for readable loading
  • Include fallback fonts in every font-family stack
  • Declare separate @font-face blocks per weight/style
  • Subset fonts to include only characters you need

❌ Don’t

  • Load every weight if you only use regular and bold
  • Forget to check font file paths in DevTools
  • Rely on browser-synthesized bold or italic
  • Confuse @font-face with the font-family property
  • Use unlicensed font files on public websites

Key Takeaways

Knowledge Unlocked

Five things to remember about @font-face

Use these points when loading custom fonts on your site.

5
Core concepts
src 02

Font file

url() or local().

Source
w2 03

WOFF2

Best format.

Format
swap 04

font-display

Show text fast.

Loading
fb 05

Fallbacks

Backup fonts.

Safety

❓ Frequently Asked Questions

The @font-face at-rule lets you load custom font files into a webpage. You give the font a family name, point to the font file with src, then use that name in the font-family property like any other font.
After @font-face registers a family name, apply it with font-family on any selector. Always include fallback fonts: font-family: 'MyFont', system-ui, sans-serif; so text stays readable if the file fails to load.
WOFF2 is the best choice for modern browsers — it is compressed and widely supported. You can list multiple src entries with different formats (woff2, woff) so older browsers have a fallback file.
font-display controls how text appears while a web font is loading. swap shows fallback text immediately and swaps to the custom font when ready — a good default for readable pages.
Yes. @font-face has been supported in all major browsers for many years. WOFF2 is supported in all current Chrome, Firefox, Safari, Edge, and Opera versions.

Practice in the Live Editor

Open the HTML editor, add an @font-face block, and apply your custom font with font-family.

HTML Editor →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful