CSS font-palette: Color fonts without extra files
Color font palettes without multiple font files
Color fonts used to mean shipping several font files or baking colors into the glyphs. font-palette and @font-palette-values switch palettes inside one font, including custom overrides for light and dark themes.
The old hack vs the modern fix
View demo/* separate font files per theme */
@font-face {
font-family: "BrandBlue";
src: url("brand-blue.woff2") format("woff2");
}
@font-face {
font-family: "BrandGrey";
src: url("brand-grey.woff2") format("woff2");
}
.logo { font-family: "BrandBlue", fantasy; }
@media (prefers-color-scheme: dark) {
.logo { font-family: "BrandGrey", fantasy; }
}@font-palette-values --brand {
font-family: "Nabla";
base-palette: 2;
override-colors: 0 #38bdf8, 1 #0f172a;
}
.logo {
font-family: "Nabla", fantasy;
font-palette: --brand;
}
/* one color font, custom palette, no second file */Font palette browser support
Live demo
Why the modern way wins
One file, many looks
Color fonts can ship several built-in palettes. Switch with font-palette instead of downloading another font.
Custom overrides
@font-palette-values lets you rename a base palette and rewrite individual color slots to match your brand.
Theme aware
Use the font's light or dark metadata, or swap custom palettes under prefers-color-scheme.
- Lines Saved
- Extra fonts → 1
- Palette switch, not new files
- Old Approach
- Multiple color fonts
- Duplicate downloads per theme
- Modern Approach
- font-palette
- @font-palette-values overrides
How it works
Color fonts store more than one palette. font-palette: normal uses the default. light and dark pick the first palette the font marked for those backgrounds, when the font provides that metadata.
For full control, define a named palette with @font-palette-values. Point it at a font-family, choose a base-palette index, and optionally rewrite slots with override-colors. Then set font-palette: --your-name on the text.
The palette paints the glyphs. The regular color property does not override it, even with !important. If you need themeable color text that is not a color font, keep using color on a normal font instead.