Using CSS font-palette for Multi-Color Fonts

Modern web typography has evolved beyond monochrome glyphs with the rise of multi-color OpenType fonts (specifically formats like COLRv0, COLRv1, and SVG). The modern CSS font-palette property, paired with the @font-palette-values at-rule, gives web developers direct control over the internal color layers of these multi-color fonts, enabling dynamic theme switching, custom brand alignments, and responsive palette adaptations without modifying the underlying font file.

How Multi-Color Fonts Work

Traditional web fonts are treated as single-color vector masks, styled via the standard color CSS property. Multi-color fonts, by contrast, contain embedded layers of vector data, each with distinct color definitions baked into the font file. Formats such as COLRv1 allow for gradients, transforms, and alpha blending across multiple layers.

Font designers typically package these fonts with one or more pre-built color palettes (for example, a default palette, a light-mode palette, and a dark-mode palette). Prior to the introduction of font-palette, developers had no native mechanism to switch between or modify these embedded colors.

Selecting Built-In Palettes

The font-palette property provides a straightforward mechanism to select built-in palettes designed into the font:

.emoji-heading {
  font-family: 'ColorFont', sans-serif;
  font-palette: dark;
}

The primary standard keywords for font-palette include:

  • normal: The browser uses the font's default palette (index 0).
  • light: Directs the browser to use a palette marked by the designer as optimized for light backgrounds.
  • dark: Directs the browser to use a palette optimized for dark backgrounds.

If the font author did not designate light or dark variations, the browser falls back to the default palette.

Custom Palettes with @font-palette-values

To override specific colors or construct an entirely new color scheme, CSS provides the @font-palette-values rule. This rule defines a custom identifier scoped to a specific font-family.

@font-palette-values --BrandTheme {
  font-family: 'ColorFont';
  base-palette: 0;
  override-colors:
    0 #ff4a54,
    1 #2b3a4a,
    2 #ffd166;
}

.custom-styled-text {
  font-family: 'ColorFont';
  font-palette: --BrandTheme;
}

The key descriptors within @font-palette-values include:

  • font-family: Explicitly links the custom palette to a matching font declaration.
  • base-palette: Specifies which internal palette index (or light/dark keyword) to use as the starting point.
  • override-colors: A comma-separated list of index-color pairs that replace specific color indices inside the selected font.

Dynamic Theming and Integration

Because @font-palette-values integrates with standard CSS, it supports media queries and dynamic theme switches. Developers can adapt multi-color fonts to system preferences without changing HTML or loading separate font assets:

@font-palette-values --SystemAdaptive {
  font-family: 'ColorFont';
  base-palette: light;
}

@media (prefers-color-scheme: dark) {
  @font-palette-values --SystemAdaptive {
    font-family: 'ColorFont';
    base-palette: dark;
    override-colors: 0 #00f0ff;
  }
}

body {
  font-family: 'ColorFont';
  font-palette: --SystemAdaptive;
}

Performance and Implementation Advantages

Controlling multi-color rendering natively via CSS eliminates the need for SVG sprite workarounds, layered DOM elements, or generating multiple colored font variants. Since the rendering takes place inside the browser's hardware-accelerated text stack, multi-color fonts rendered with font-palette retain complete text functionality, including accessibility, text selection, searchability, and responsive font-size scaling.