What Is @font-face?
The @font-face at-rule specifies a custom font for displaying text on a web page. Unlike web-safe fonts that come pre-installed on users' devices, web fonts must be downloaded before they can render. The browser can load these fonts from either a remote server or locally-installed fonts on the user's computer, as documented in the MDN Web Docs @font-face reference.
Before @font-face became widely supported, web designers were limited to a small set of fonts that were virtually guaranteed to exist on users' computers—fonts like Arial, Times New Roman, and Georgia. This limitation often forced designers to choose between using generic-looking typography or risking that their carefully crafted designs would fall back to unexpected fonts on users' machines.
The @font-face rule changed everything by allowing developers to define custom fonts and tell the browser where to find them. This CSS at-rule is fundamental to modern web development and enables the brand-consistent typography that distinguishes professional websites.
Required Descriptors
Every valid @font-face declaration requires two descriptors: font-family and src. These define the name that will be used to reference the font and the location of the font file itself.
font-family Descriptor
The font-family descriptor specifies a name that will be used as the font face value for font properties throughout your CSS. This name doesn't have to match the actual font file name or the font's official name—it's simply an identifier that you'll use in your stylesheets. Proper naming conventions help maintain organized CSS architecture across larger projects.
src Descriptor
The src descriptor specifies references to font resources and provides hints about the font format. It can include both local font references and URL-based downloads. The url() function points to the font file location, while the format() hint helps browsers determine whether they can use a particular font before downloading it.
Using the local() Function
The local() function within src allows you to check for fonts already installed on the user's device. If found, the browser uses the local version instead of downloading. This approach can save bandwidth and improve loading speed for users who already have the font installed. For optimal page performance, consider combining local() checks with fallback URLs.
1@font-face {2 font-family: 'CustomFont';3 src: url('fonts/customfont.woff2') format('woff2');4}5 6body {7 font-family: 'CustomFont', sans-serif;8}Optional Descriptors for Control
Beyond the required descriptors, @font-face offers numerous optional descriptors that give you fine-grained control over how fonts load and render.
font-weight and font-style
These descriptors specify the weight and style of the font face, allowing you to define multiple variations of the same font family for different weights and styles like bold and italic.
font-display Descriptor
The font-display descriptor determines how a font face is displayed based on whether and when it's downloaded and ready to use. This is crucial for user experience and Core Web Vitals performance.
The font-display property accepts several values:
- auto: Browser default behavior
- block: Hides text until the font loads (FOIT)
- swap: Shows fallback font immediately, then swaps (FOUT)
- fallback: Short swap period with temporary fallback
- optional: Leaves the decision to the browser
For most websites, font-display: swap is recommended because it ensures text remains visible while the custom font loads.
unicode-range Descriptor
The unicode-range descriptor specifies the range of Unicode code points to be used from the font. This enables incremental loading where the browser only downloads font files if the page contains characters from that range.
size-adjust Descriptor
The size-adjust descriptor defines a multiplier for glyph outlines and metrics, making it easier to harmonize designs when using multiple fonts at the same font size. This can help prevent layout shifts when fonts swap.
Font Formats and Modern Best Practices
Web fonts come in several formats, each with different characteristics regarding file size, compression, and browser support.
WOFF2: The Modern Standard
WOFF2 (Web Open Font Format 2) is currently the most recommended format for web fonts. It offers superior compression, with a 26% higher average compression ratio than WOFF1, thanks to its use of Brotli compression.
WOFF2 is supported by all modern browsers, making it the safest choice for new projects. For modern development, serving only WOFF2 files is generally recommended.
Converting Fonts to WOFF2
If you have fonts in other formats, you can convert them to WOFF2 using various tools. Online services like CloudConvert offer easy conversion, or you can use command-line tools for batch processing. Proper font format selection is a key component of web performance optimization.
Performance Optimization Strategies
Optimizing font performance is critical for Core Web Vitals metrics, particularly Largest Contentful Paint (LCP) and Cumulative Layout Shift (CLS).
Self-Hosting Fonts
Self-hosting web fonts on your own domain eliminates the need for additional DNS lookups and HTTP connections to third-party servers. This reduces Time To First Byte (TTFB) and can improve overall page load performance.
Font Subsetting
Font subsetting involves creating font files that only include the characters you actually use on your website. This can dramatically reduce file sizes, especially for fonts with extensive character sets.
Preloading Critical Fonts
For fonts that are essential for above-the-fold content, you can use the <link rel="preload"> HTML element to prioritize their loading.
Limiting Font Families
A simple but effective optimization is limiting the number of font families used on a page. Each additional font family requires another font file download. For most websites, using no more than two font families provides a good balance between design flexibility and performance.
1/* Complete @font-face declaration with best practices */2@font-face {3 font-family: 'PrimaryFont';4 src: url('fonts/primary-regular.woff2') format('woff2'),5 url('fonts/primary-regular.woff') format('woff');6 font-weight: 400;7 font-style: normal;8 font-display: swap;9 unicode-range: U+0000-00FF;10}11 12@font-face {13 font-family: 'PrimaryFont';14 src: url('fonts/primary-bold.woff2') format('woff2'),15 url('fonts/primary-bold.woff') format('woff');16 font-weight: 700;17 font-style: normal;18 font-display: swap;19 unicode-range: U+0000-00FF;20}21 22/* System font stack for maximum performance */23body {24 font-family: 'PrimaryFont', system-ui, -apple-system, sans-serif;25}Understanding the full range of options available
Custom Font Loading
Load any custom web font from your server or third-party sources using the src descriptor with url() and local() functions.
Font Display Control
Use font-display values like swap, block, and optional to control how fonts appear during loading.
Unicode Range Subsetting
Specify exactly which characters a font file covers with unicode-range for incremental loading.
Multiple Weights and Styles
Define separate @font-face rules for different weights and styles, all referencing the same font-family name.
Metric Adjustments
Fine-tune font metrics with size-adjust, ascent-override, and descent-override for consistent layout.
Performance Optimization
Self-host WOFF2 fonts, preload critical faces, and subset to minimize file sizes and improve loading.
Frequently Asked Questions
Conclusion
The @font-face at-rule is the cornerstone of modern web typography, enabling designers to create unique, brand-consistent visual experiences while maintaining broad compatibility across devices and browsers. By understanding its syntax, descriptors, and best practices, you can implement custom fonts that enhance rather than hinder your website's performance.
Key takeaways include prioritizing WOFF2 format, using font-display: swap to ensure text visibility, self-hosting fonts for better performance, and being strategic about the number of font families and weights you use.
Related Resources
Sources
- MDN Web Docs: @font-face - Official CSS reference documentation
- DEV Community: The Practical Guide to Optimizing @font-face - Optimization techniques and code examples
- DebugBear: The Ultimate Guide to Font Performance Optimization - Performance metrics and best practices