Web Open Font Format (WOFF2) 2.0
Modern, high-compression webfont container built for fast, efficient font delivery
In Simple Terms
WOFF2 is the modern web font standard. Use it for all web projects. 97%+ browser support, smallest file size (30% smaller than WOFF, 60-70% smaller than TTF).Uses Brotli compression for superior compression ratios. Self-hosting WOFF2 is faster than Google Fonts CDN in most cases.Implementation: @font-face with src: url('font.woff2') format('woff2'). Add WOFF fallback only if supporting pre-2014 browsers.
WOFF2 Format at a Glance
Developer
W3C WebFonts Working Group with major contributions from browser vendors
Type
Brotli-compressed web wrapper for sfnt fonts (TrueType or OpenType)
File Extension
.woff2
Platform Support
All modern browsers; primary format for web typography
MIME Type
font/woff2, application/font-woff2
Primary Use
Fast self-hosted and CDN-served fonts, variable fonts, multilingual web UIs
Choose your target format below
All conversions preserve font quality and metadata
In this article
What is Web Open Font Format 2.0 (WOFF2)?
WOFF2 is the modern successor to WOFF 1.0. It packages an existing OpenType or TrueType font inside a web-optimized container and applies advanced compression to reduce transfer size. The underlying font remains an sfnt-based font; WOFF2 changes delivery efficiency, not typographic capability. To create a WOFF2 file, convert TTF to WOFF2 or OTF to WOFF2; to recover the desktop original, convert WOFF2 to TTF.
The main improvements over WOFF 1.0:
- Brotli compression instead of zlib
- Optional table transformations that compress outline data more effectively
- Better performance for large Unicode fonts and variable families
- Reduced bandwidth cost for web applications and design systems
Format History
WOFF2 is the second-generation Web Open Font Format designed to reduce the real-world cost of typography on the modern web. It was created to keep the OpenType/TrueType ecosystem intact while dramatically improving network efficiency for large families, multilingual UI fonts, and the rising use of variable fonts.
Before WOFF: The Early Web Font Problem
In the early era of web typography, authors either depended on system fonts or served raw TTF/OTF files. That approach had predictable problems: large downloads, inconsistent metadata handling, and weak alignment with browser security and licensing expectations.
- Raw TTF/OTF delivery was bulky and not purpose-built for the browser
- Font licensing models were uneasy about uncontrolled distribution
- Performance penalties increased sharply as designers adopted multi-weight families
- Global products needed large Unicode coverage, multiplying payload size
WOFF 1.0: The First Web Standardization
WOFF 1.0 stabilized the situation by defining a browser-oriented wrapper around sfnt fonts. It offered a standard header and directory model, optional metadata blocks, and compression with widely supported tooling. This gave the industry a shared, reliable baseline for distributing fonts on the web.
What WOFF 1.0 Solved
- Interoperability: a consistent container across browser engines
- Packaging: clearer separation of font data and optional metadata
- Practical compression: smaller than raw TTF/OTF for most families
The Pressure That Exposed WOFF 1.0 Limits
As web applications became heavier and more global, WOFF 1.0 began to show its ceiling. The shift to mobile-first products, larger UI typography systems, and multi-script design pushed zlib-based compression to a point where meaningful gains required a new strategy.
- Large Unicode fonts for global products significantly increased transfer size
- Design systems normalized multiple weights and styles as default baselines
- Performance budgets tightened due to mobile networks and low-power devices
- Early variable font adoption highlighted the need for better compression efficiency
The WOFF2 Approach
WOFF2 was built as an evolution, not a replacement of the underlying font model. The crucial change is the combination of Brotli compression with table transforms applied to known OpenType/TrueType structures before compression. Instead of compressing tables as-is, WOFF2 can normalize and reorganize outline and metric data to create more redundancy, which Brotli exploits effectively.
Design Goals
- Reduce transfer size without altering glyph fidelity
- Preserve full OpenType feature behavior
- Improve outcomes for large families and complex scripts
- Maintain the same authoring sources (TTF/OTF)
Practical Results
- Better compression ratios than WOFF 1.0 in most real stacks
- Stronger savings for TrueType outline-heavy fonts
- More efficient delivery of variable fonts
- Lower bandwidth cost for high-traffic products
Milestones and Adoption Arc
The WOFF2 specification matured through the mid-2010s alongside improvements in browser font pipelines. Once modern engines aligned on Brotli support and transform handling, WOFF2 became the default target in production webfont workflows.
| Phase | Industry Context | WOFF2 Role |
|---|---|---|
| Pre-WOFF baseline | Raw TTF/OTF, inconsistent delivery patterns | No standardized browser-first container |
| WOFF 1.0 stabilization | Web typography becomes mainstream | Reliable packaging with modest compression |
| WOFF2 emergence | Mobile performance budgets tighten; global UIs expand | Higher compression via Brotli + transforms |
| WOFF2 default era | Variable fonts and large design systems normalize | Primary delivery format; WOFF becomes fallback |
What WOFF2 Did Not Change
WOFF2 does not redefine typography. It does not create new shaping rules, new OpenType features, or new layout behavior. It is a transport and packaging improvement layered on top of the same sfnt model used by OpenType and TrueType sources.
- Ligatures, alternates, kerning, and complex scripts behave the same as in the source font
- Color and variable tables remain intact
- Authoring and licensing still originate from the OTF/TTF masters
Historical Summary
WOFF2 marks the point where web typography scaled to modern performance realities. It kept the industry’s investment in OpenType/TrueType intact while making rich, global, and variable typography viable under strict network and UX constraints.
Lessons from WOFF2's Evolution
- Web standards follow performance pressure: the format exists because the network cost became a product-level bottleneck
- Backward-compatible evolution wins: WOFF2 improved delivery without fragmenting the font ecosystem
- Compression alone isn't enough: domain-aware transforms enabled the real leap forward
In practical terms, WOFF2 is now the default endpoint for browser delivery. WOFF remains relevant as a compatibility fallback, while OTF/TTF remain the authoritative sources for design, licensing, and authoring.
Technical Specifications
Core Properties
- Internal format: TrueType or OpenType sfnt
- Compression: Brotli over a transformed font data stream
- Feature preservation: GSUB/GPOS and all OpenType tables remain available
- Metadata: Optional blocks for descriptive and private data
- Goal: Smaller files and faster downloads with no loss of rendering data
Why WOFF2 Is Smaller
WOFF2 compresses more aggressively by reorganizing certain table data before compression. This is especially effective for TrueType outline tables and large glyph sets.
Practical Impact
- Better first-load performance for design-heavy sites
- Smaller variable font packages compared to multi-file static families
- Reduced cost for high-traffic sites serving many language subsets
WOFF2 File Structure
WOFF2 keeps a compact header and directory concept similar to WOFF 1.0, but the font data is stored as a single compressed stream with optional transforms applied to specific known tables.
| Component | Purpose |
|---|---|
| WOFF2 header | Identifies the container and declares sizes, counts, and block offsets |
| Table directory | Lists tables and indicates whether a transform is used |
| Compressed font data stream | Brotli-compressed stream containing the font tables, potentially in transformed form |
| Metadata / private blocks (optional) | Human-readable or vendor-specific information |
After decompression and reverse-transform steps, the browser reconstructs an in-memory sfnt font equivalent to the original TTF or OTF source.
Compression and Table Transforms
WOFF2 improves compression by applying optional transforms to known table types before Brotli compression. These transforms normalize and reorder data to improve redundancy. The sections below break down how zlib and Brotli compare, and what each achieves on a real font file.
Common Transform Targets
- glyf/loca: TrueType outlines re-encoded for better compression
- hmtx: Horizontal metrics optimization
- other known tables: Normalized encoding improves cross-glyph pattern matching
Mental Model
- Start with a standard sfnt font
- Apply WOFF2 transforms where applicable
- Compress the transformed stream with Brotli
- Browser reverses transforms and reconstructs the sfnt font
Web font formats use compression to reduce file sizes for faster delivery. WOFF (Web Open Font Format) was the first web-specific font format, using zlib compression. WOFF2 replaced it with Brotli compression plus font-specific preprocessing, achieving significantly better results.
Font data has distinctive compression characteristics compared to text or binary executables. A typical OpenType font contains several data types with different entropy profiles: the glyph outline data in the glyf or CFF table consists of coordinate sequences with small delta values between consecutive points; the horizontal metrics table (hmtx) stores advance widths that cluster around the font's predominant character width; and layout tables (GSUB, GPOS) contain highly regular structural patterns from their record formats. General-purpose compressors like zlib can exploit this repetition, but font-specific preprocessing reorganizes the data into streams with even higher regularity before compression, which is why WOFF2 outperforms WOFF by more than Brotli alone would account for.
The practical impact of compression on page load time depends on the network context. On modern broadband connections, the difference between a 150KB WOFF and a 115KB WOFF2 may be imperceptible in isolation. However, fonts are typically render-blocking resources: the browser must download and parse a font before it can display text using that font. A 25% smaller file directly reduces the time before text appears, which affects Core Web Vitals metrics like Largest Contentful Paint and Time to First Contentful Paint. For applications serving global audiences across varied network conditions, WOFF2's compression advantage compounds with geographic CDN distribution to produce meaningful user experience improvements.
Format Comparison
| Aspect | WOFF | WOFF2 |
|---|---|---|
| Algorithm | zlib (DEFLATE) | Brotli + preprocessing |
| Compression vs TTF | 40-50% smaller | 55-65% smaller |
| WOFF2 vs WOFF | N/A | 20-30% smaller |
| Browser Support | 99%+ (IE9+) | 97%+ (2015+) |
| Decompression Speed | Fast | Slightly slower* |
| Specification | W3C 2012 | W3C 2018 |
*Brotli decompression is marginally slower than zlib, but the difference is negligible for typical font file sizes. The smaller download time more than compensates.
Real-World Size Benchmarks
Actual compression ratios vary by font complexity. Latin-only text fonts compress more efficiently than CJK fonts with thousands of glyphs. These measurements are from common production fonts:
| Font | TTF Size | WOFF | WOFF2 | WOFF2 vs WOFF |
|---|---|---|---|---|
| Inter Regular (Latin) | 308 KB | 181 KB | 142 KB | −22% |
| Noto Sans (Latin+Greek+Cyrillic) | 556 KB | 298 KB | 228 KB | −23% |
| Source Serif 4 Variable | 890 KB | 541 KB | 391 KB | −28% |
| Subset Latin (pyftsubset) | 40 KB | 24 KB | 18 KB | −25% |
Values approximate. Actual sizes depend on font content, hinting data, and OpenType table count. Variable fonts compress especially well in WOFF2 due to delta encoding in gvar table preprocessing.
WOFF 1.0: zlib Compression
WOFF wraps font data with a new header and compresses each table independently using zlib (the same algorithm used by gzip). It's straightforward but not optimized for font data.
WOFF 1.0 File Structure
├── WOFF Header (44 bytes)
│ ├── signature: "wOFF"
│ ├── flavor: font type (TrueType/CFF)
│ ├── length: total file size
│ └── numTables, totalSfntSize, etc.
│
├── Table Directory
│ └── [tag, offset, compLength, origLength, origChecksum]
│
└── Compressed Table Data
├── Each table compressed separately with zlib
└── Tables < compLength uncompressedWOFF's zlib (DEFLATE) compression is the same algorithm used in gzip and ZIP files. It operates as a general-purpose compressor with no font-specific optimizations. Each table is compressed independently, which means patterns that span table boundaries cannot be exploited. The compression level (1–9) can be tuned during WOFF generation, with level 6 being the common default that balances speed and compression ratio.
When WOFF Is Still Appropriate
Supporting IE11: While IE11 support has declined dramatically, sites with legacy traffic can use WOFF as the exclusive fallback since IE11 does not support WOFF2.
Corporate intranets: Environments with locked-down browsers on older OS versions may lack WOFF2 support. A WOFF fallback ensures universal rendering.
Rapid prototyping: WOFF is faster to generate than WOFF2 (no Brotli encoding step), making it useful for development environments where iteration speed matters more than file size.
WOFF's zlib (DEFLATE) compression operates as a two-stage algorithm: LZ77 for finding repeated byte sequences within a 32KB sliding window, followed by Huffman coding to encode those matches and literal bytes with variable-length bit codes proportional to their frequency. The 32KB window limit is a meaningful constraint for font data: the glyf table in a large Latin font might span 200KB, so patterns in glyphs near the beginning of the table fall outside the window when processing glyphs near the end. Higher zlib compression levels (1–9) extend the pattern search and produce smaller output at the cost of longer compression time; decompression speed is largely constant regardless of compression level. Level 6 is the common default, balancing compression ratio against generation time.
WOFF2: Brotli + Preprocessing
WOFF2 doesn't just use a better compression algorithm. It first transforms font data into a more compressible format, then applies Brotli compression. The technical specifications above cover browser support history and delivery best practices.
WOFF2 Preprocessing Steps
Glyph Data Transform
Converts TrueType glyf table to more compressible format
loca Table Reconstruction
loca table is omitted (reconstructed from glyf)
hmtx Optimization
Delta-encodes horizontal metrics for better compression
Brotli Compression
All transformed data compressed with Brotli
Why Preprocessing Matters
Brotli alone would give ~10% improvement over zlib. The font-specific preprocessing contributes the other ~20%. This preprocessing recognizes patterns specific to font data that generic compression misses.
How Brotli Achieves Superior Compression
Brotli (developed by Google in 2013) uses three key techniques that outperform DEFLATE for font data: a larger sliding window for back-references (up to 16MB vs zlib's 32KB), a static dictionary of common byte sequences pre-loaded into the compressor, and second-order context modeling that predicts byte values based on the previous two bytes rather than just one.
For WOFF2 specifically, the glyph data transform is what makes the biggest difference. Before Brotli compression, the glyf table is restructured: coordinate data is separated from flags, x-coordinates and y-coordinates are stored in separate streams, and delta encoding converts absolute coordinates to smaller delta values. This preprocessing converts a table full of large mixed values into streams of small, highly regular numbers that are exactly what Brotli's context modeling excels at compressing.
# Converting TTF to WOFF2 with Python fonttools from fontTools.ttLib import TTFont from fontTools import ttLib import brotli # pip install brotli # Using woff2 command-line tool (recommended) # pip install brotli fonttools[woff] python -m fonttools ttLib.woff2 compress myfont.ttf # Output: myfont.woff2 # Size comparison # myfont.ttf = 245,890 bytes # myfont.woff = 148,230 bytes (−40%) # myfont.woff2 = 113,450 bytes (−54% from TTF, −23% from WOFF)
Practical Recommendations
/* Optimal @font-face declaration */
@font-face {
font-family: 'MyFont';
src: url('myfont.woff2') format('woff2'),
url('myfont.woff') format('woff');
font-display: swap;
}
/* Order matters: browsers use first supported format */
/* WOFF2 first → most browsers use it */
/* WOFF fallback → IE11 and very old browsers */
/* No need for TTF/OTF in @font-face anymore */
/* 97%+ support for WOFF2, 99%+ for WOFF */Always Use WOFF2 Primary
97%+ browser support, best compression. Include WOFF as fallback for the remaining 2%.
Subset Before Compressing
Subsetting provides 70-90% reduction vs 30% from compression. Do both for optimal size.
Compression vs Subsetting: Prioritize Correctly
Developers often focus on compression format (WOFF vs WOFF2) when subsetting provides far larger gains. Consider a typical font serving only English content:
Subsetting to Basic Latin characters (U+0020–U+007E) plus common punctuation reduces font size by 85–93% compared to the full font. Compression then provides an additional 20–25% on top of that. Always subset first, then compress. To understand how these file size reductions translate into measurable rendering speed improvements, see font loading metrics and measurement techniques. For projects with large font files, our webfont generator tool automates subsetting and WOFF2 conversion in a single step, and practical strategies for addressing size at scale are covered in the large font files solutions guide.
Typography Features and CSS Integration
WOFF2 preserves all typographic features from the source font. Ligatures, alternates, kerning, complex scripts, color tables, and variable axes work the same way as with the original OpenType or TrueType font.
Recommended @font-face Stack
@font-face {
font-family: 'BrandSans';
src: url('/fonts/BrandSans.woff2') format('woff2'),
url('/fonts/BrandSans.woff') format('woff');
font-weight: 100 900; /* supports variable axis if present */
font-style: normal;
font-display: swap;
}
:root {
font-family: 'BrandSans', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}OpenType Feature Control
/* Works identically for WOFF2-served fonts */
.body-text {
font-feature-settings: 'liga' 1, 'kern' 1, 'calt' 1;
}
.small-caps {
font-variant-caps: small-caps;
}
.numerals {
font-variant-numeric: oldstyle-nums tabular-nums;
}If the font is variable, axis control uses the same CSS syntax as any other OpenType variable font.
Usage and Applications
Primary Webfont Format
- Default choice for modern websites and web apps
- Best format for variable fonts on the web
- Efficient for large multilingual UI fonts
- Ideal for self-hosting with long-term caching
Performance Patterns
Choosing the right loading strategy has a measurable impact on page performance. Review font loading metrics and benchmarks to understand how WOFF2 affects Core Web Vitals.
- Serve WOFF2 first, WOFF second
- Subset by script or product area
- Use unicode-range for selective loading
- Preload critical UI fonts
unicode-range Example
@font-face {
font-family: 'GlobalUI';
src: url('/fonts/GlobalUI-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC;
font-display: swap;
}
@font-face {
font-family: 'GlobalUI';
src: url('/fonts/GlobalUI-devanagari.woff2') format('woff2');
unicode-range: U+0900-097F, U+1CD0-1CFF;
font-display: swap;
}Advantages and Disadvantages
Advantages
- Best compression: Smaller than WOFF, TTF, and OTF for web transport
- Feature complete: Preserves full OpenType layout and color capabilities
- Ideal for variable fonts: One file can replace many static weights
- Strong browser support: Modern baseline across engines
- Better UX: Faster font loading reduces layout shifts and slow text rendering
Disadvantages
- Web-only: Not used as an installable desktop font
- Build step required: Must be generated from a licensed source font
- Fallback planning: WOFF may still be needed for older browsers
- License constraints: Conversion and self-hosting depend on font licensing
Deployment Rule
Use WOFF2 as the primary webfont target. Generate WOFF from the same source only when an explicit legacy browser requirement exists.
WOFF2 vs Other Font Formats
| Format | Compression | Role | Best Use |
|---|---|---|---|
| WOFF2 | Brotli + transforms | Modern web delivery standard | Primary format for all new web projects |
| WOFF | zlib | Legacy web fallback | Secondary source in @font-face stacks |
| TTF | None | Desktop/source format | Installation and authoring masters |
| OTF | None | Desktop/source format | Professional print and feature-rich families |
| EOT | Legacy | IE-only webfont | Historical support scenarios |
| SVG Fonts | XML-based | Obsolete legacy web format | Avoid for modern stacks |
WOFF2 is the correct endpoint for web delivery. OTF/TTF remain the correct sources for authoring and distribution outside the browser.
Working with WOFF2 Files
Generating WOFF2
WOFF2 files are generated from OpenType or TrueType sources. Common CLI flows:
# Basic WOFF2 generation
woff2_compress MyFont.ttf
woff2_compress MyFont.otf
# Generate a WOFF fallback from the same source (tool-specific)
sfnt2woff MyFont.ttf
# Subset directly to WOFF2
pyftsubset MyFont.ttf \
--flavor=woff2 \
--layout-features+=liga,kern,calt \
--unicodes="U+0000-00FF" \
--output-file="MyFont-latin.woff2"Deployment Checklist
- Confirm webfont rights in the license
- Convert from a clean, up-to-date OTF/TTF master
- Subset per script and product needs
- Serve WOFF2 with a WOFF fallback when required
- Set long cache headers and versioned file names
- Use preload for critical UI fonts
For GUI workflows, use Font Converter Tool and a subsetting utility to produce paired WOFF2/WOFF bundles from a single source. For a complete browser-based pipeline, the webfont generator tool handles conversion, subsetting, and CSS output in one step.
Written & Verified by
Sarah Mitchell
Typography expert specializing in font design, web typography, and accessibility
Frequently Asked Questions
Is WOFF2 universally supported?
WOFF2 is supported across all modern browsers. WOFF 1.0 remains the practical fallback for older engines if legacy support is required.
Does WOFF2 change font quality or features?
WOFF2 is a container and compression method. It preserves the same outlines, metrics, and OpenType tables as the source font.
Can I install WOFF2 fonts on my computer?
WOFF2 is not intended as an installable OS font. Convert to TTF or OTF for system installation, subject to licensing.
Do variable fonts work better with WOFF2?
Variable fonts work the same at the feature level, but WOFF2 typically delivers them with significantly smaller transfer size.
Should I ship only WOFF2?
Use WOFF2 as primary. Add WOFF only if the support matrix includes older browsers that lack WOFF2.
Ready to Work with WOFF2 Fonts?
Convert any font format to WOFF2 with our free online converter
