
Color Fonts on the Web: COLRv1, SVG, and What Browsers Support
- Maria
- Typography
- 23 Oct, 2026
Every emoji you've ever typed is a color font at work. The smiley faces and flags on your phone aren't images inserted into text. They're glyphs in a font, just like the letter "a", except that each one carries its own colors. The same technology lets type designers make display fonts with gradients, layered shading, and multiple built-in color schemes, all of which stay real, selectable, searchable text.
The catch is that color fonts come in several competing formats, and browsers don't all support the same ones. A font that looks spectacular in Chrome can render as flat black letters in another browser, or not at all. If you want to use color fonts on a production site, you need to understand which format you're shipping, who can see it, and what everyone else gets.
This guide covers the four main color font formats, current browser support, how to load a color font with a safe fallback, and how to change a font's colors with font-palette.
What Makes a Font a Color Font
A regular font stores each glyph as a single outline. The browser fills it with whatever color you set. A color font stores additional data that says how to paint each glyph: which layers to draw, in which colors, sometimes with gradients or images.
Because the result is still text, color fonts keep the advantages of type:
- Text stays selectable, copyable, and searchable.
- Screen readers read it as normal text.
- It scales cleanly, since vector formats are resolution-independent.
- It reflows and wraps like any other text.
That's the main argument for color fonts over images or SVG illustrations of headlines. You get a visual treatment without giving up the text.
The Four Color Font Formats
Different companies developed different formats around the same time, and all of them are now part of the OpenType specification. That's why support is fragmented.
| Format | Origin | How glyphs are drawn | Vector or bitmap |
|---|---|---|---|
| COLR v0 + CPAL | Microsoft | Stacked layers of flat colors | Vector |
| COLR v1 + CPAL | Google and others | Layers with gradients, transforms, and blending | Vector |
| OpenType-SVG | Adobe and Mozilla | An SVG document embedded per glyph | Vector (can embed bitmaps) |
| sbix, CBDT/CBLC | Apple, Google | Bitmap images at fixed sizes | Bitmap |
COLRv0
The original COLR (color) table defines each glyph as a stack of ordinary outlines, each filled with a single color from a CPAL (color palette) table. It's simple and compact, and it's supported nearly everywhere. Its limit is that every layer is a flat color: no gradients, no transparency effects beyond what the palette defines.
COLRv1
COLRv1 extends the same table with linear, radial, and sweep gradients, transformations, and compositing modes. It can produce glossy, three-dimensional, and multicolor effects while keeping file sizes small, because it reuses outlines and describes paint operations instead of storing images. Google has used it for its Noto Color Emoji font, and display fonts like Nabla and Bungee Spice on Google Fonts are built with it.
OpenType-SVG
OpenType-SVG fonts embed an SVG document for each glyph. That gives designers the full power of SVG, including gradients, patterns, and even embedded images. Files can be large, and because each glyph is an SVG document, rendering can be heavier than with COLR.
Bitmap Formats
Apple's sbix and Google's older CBDT/CBLC store each glyph as a PNG image at one or more fixed sizes. They're mainly used for emoji. Bitmaps get blurry when scaled beyond their stored resolution and make files large, so they aren't a good choice for web fonts you ship yourself.
Browser Support
Support has changed a lot over the past few years, and it's still uneven. The broad picture at the time of writing:
| Format | Chromium (Chrome, Edge) | Firefox | Safari |
|---|---|---|---|
| COLRv0 | Yes | Yes | Yes |
| COLRv1 | Yes | Yes | Check current status |
| OpenType-SVG | No | Yes | Yes |
| sbix | Varies by platform | Varies | Yes |
| CBDT/CBLC | Yes | Varies | No |
Two things stand out. First, no single advanced format works everywhere: COLRv1 and OpenType-SVG each miss at least one major engine, and Safari has historically been the gap for COLRv1. Second, COLRv0 is the safe common denominator, though it's also the least capable. Check caniuse for the current state before you make a decision, because this is an area where support keeps moving.
When a browser doesn't support a font's color format, what happens depends on the font. Most color fonts also contain regular monochrome outlines, so the browser falls back to drawing those in the current color. Some fonts don't include fallback outlines, and the text may not render at all. Always test the failure case.
Loading a Color Font with a Fallback
The @font-face rule's src descriptor supports a tech() function that tells the browser which technology a file needs. A browser that doesn't support that technology skips the file and tries the next one.
@font-face {
font-family: "Headline Color";
src: url("/fonts/headline-mono.woff2") format("woff2");
src:
url("/fonts/headline-colrv1.woff2") format("woff2") tech(color-COLRv1),
url("/fonts/headline-svg.woff2") format("woff2") tech(color-SVG),
url("/fonts/headline-mono.woff2") format("woff2");
font-display: swap;
}
The first src line is a safety net. Older browsers that don't understand tech() may treat the second src declaration as invalid and drop it, falling back to the first declaration. Browsers that do understand tech() use the second declaration and pick the first file whose technology they support.
The valid color technology keywords are color-COLRv0, color-COLRv1, color-SVG, color-sbix, and color-CBDT.
You can also check for support in CSS:
.hero__title {
font-family: "Headline Mono", system-ui, sans-serif;
color: #0f172a;
}
@supports font-tech(color-COLRv1) {
.hero__title {
font-family: "Headline Color", system-ui, sans-serif;
}
}
This lets you adjust other styles too. A color font might look best on a dark background, so you can switch the background only when the color version will actually render. Support for font-tech() in @supports is itself not universal, so treat it as an enhancement and make sure the default styles look good on their own.
For general advice on serving fonts from your own domain, see Self-Hosting Web Fonts. For format details beyond color, read WOFF2 vs WOFF vs TTF vs OTF.
Using Google Fonts
Google Fonts has a small collection of color fonts. You can load them like any other family:
<link
href="https://fonts.googleapis.com/css2?family=Nabla&display=swap"
rel="stylesheet"
/>
.festival-title {
font-family: "Nabla", system-ui;
font-size: clamp(3rem, 10vw, 7rem);
}
Test the result in every browser you support, since what you see depends on the format the browser receives and whether it can render it.
Changing Colors with font-palette
Color fonts in COLR format store their colors in palettes, and many fonts include several palettes, for example a light and a dark version. CSS gives you two tools to work with them.
Choosing a Built-In Palette
The font-palette property selects a palette:
.badge {
font-palette: normal; /* the font's default palette */
}
.badge--dark {
font-palette: dark; /* the palette the font marks as suitable for dark backgrounds */
}
light and dark only work if the font designer tagged palettes for those uses. Otherwise, use @font-palette-values to pick one by index.
Defining a Custom Palette
@font-palette-values lets you choose a base palette and override individual colors:
@font-palette-values --brand {
font-family: "Nabla";
base-palette: 1;
override-colors:
0 #0ea5e9,
1 #0369a1,
2 #f8fafc;
}
.festival-title {
font-family: "Nabla", system-ui;
font-palette: --brand;
}
base-palette picks a palette by its index in the font. override-colors replaces specific color entries, identified by their index within that palette. To find out how many palettes and colors a font has, check the font's documentation or inspect it with a tool like Wakamai Fondue.
You can switch palettes on hover, in dark mode, or for different sections of a site:
@font-palette-values --night {
font-family: "Nabla";
base-palette: 3;
}
@media (prefers-color-scheme: dark) {
.festival-title {
font-palette: --night;
}
}
font-palette and @font-palette-values are supported in current Chrome, Edge, Firefox, and Safari, but they only affect fonts that have CPAL palettes. OpenType-SVG fonts can define colors differently, and the palette override may not apply to them.
The color Property and Color Fonts
In a color font, the color property usually doesn't change the colors the glyphs are painted with, because the font defines them. Many COLR fonts reserve one palette entry for "the current text color", so parts of the glyph do follow color. That's how some fonts let you tint one layer while keeping the others fixed. If changing color has no visible effect, the font simply doesn't use that feature.
Emoji and Color Fonts
Emoji are the most common color fonts you'll deal with. Each operating system ships its own emoji font, in its own format, which is why the same emoji looks different on different devices. You don't need to do anything to display them, but there are two useful controls.
To keep emoji consistent across platforms, you can load a web emoji font, like Noto Color Emoji, and put it in your font stack:
body {
font-family: system-ui, sans-serif, "Noto Color Emoji";
}
Emoji fonts are large, so load them only if consistent emoji really matter, and consider subsetting to the emoji you need.
The font-variant-emoji property asks the browser to show a character as emoji (colorful) or text (monochrome) when both presentations exist, for example for symbols like the heart or the copyright sign:
.legal-footer {
font-variant-emoji: text;
}
Support for font-variant-emoji is still limited, so check MDN before relying on it. Unicode variation selectors in the text itself are the more widely supported way to request a specific presentation.
When to Use Color Fonts
Color fonts are a display tool. They work best in a few specific places:
- Headlines and hero text where you want a strong visual treatment and still need real text.
- Event, campaign, and entertainment sites, where expressive type is part of the brand.
- Logos and wordmarks set in text, as long as you have a solid fallback.
- Emoji, which are color fonts by nature.
They're a poor fit for:
- Body text. Multi-color glyphs at small sizes are hard to read and look noisy.
- UI elements, like buttons and labels, where clarity matters more than decoration.
- Icons. Color fonts can draw icons, but they bring the same accessibility and loading problems as other icon fonts. The sibling post on icon fonts vs SVG icons explains why SVG is usually the better choice.
For choosing expressive headline faces more generally, see Display Typefaces.
Accessibility and Performance
Color fonts are text, which is good for accessibility. A few things still need attention:
- Contrast. Contrast checkers measure the
colorproperty, but a color font may paint glyphs in completely different colors. Check the rendered result manually, especially gradients that get light in places. - Forced colors and high contrast modes. Test how the font looks when the operating system overrides colors. Make sure the text is still readable.
- File size. COLRv1 fonts tend to be compact, but SVG and bitmap fonts can be large. Subset to the characters you need, and avoid preloading a large color font that only appears below the fold.
- Fallback quality. The monochrome fallback is what a share of your visitors will actually see. Make sure it looks deliberate, not broken.
Common Mistakes
- Testing only in Chrome, then discovering the font renders flat or blank in Safari or Firefox.
- Shipping a font without monochrome fallback outlines, so unsupported browsers show nothing.
- Using a single
srcwithtech(), which older browsers may drop entirely. - Expecting
colorto recolor the font, when the colors come from the font's palette. - Using bitmap color fonts on the web, which bloat file size and blur when scaled.
- Setting body text in a color font, which hurts readability.
- Skipping contrast checks because the CSS
colorvalue passes, even though the rendered glyphs don't use it.
Conclusion
Color fonts let you ship expressive, multicolored type that stays real text. COLRv0 is supported almost everywhere but limited to flat layers. COLRv1 adds gradients and effects in compact files, and OpenType-SVG offers similar power through embedded SVG. Neither of the advanced formats works in every browser, so fallbacks aren't optional.
If you want to use one, load it with tech() and a plain src fallback, use @supports font-tech() for any styles that depend on the color version, and control its colors with font-palette and @font-palette-values. Keep color fonts for headlines and expressive moments, check what the fallback looks like, and test in every browser your readers use.


