Using CSS font-palette to Customize Color Fonts

The CSS font-palette property allows developers to select and alter the color schemes embedded within multi-colored vector fonts, such as OpenType-SVG and COLR/CPAL fonts, without editing font files directly. By pairing font-palette with the @font-palette-values at-rule, you can choose from predefined palette sets, create custom color combinations, and override specific color indices. This capability brings responsive color theming, dark mode adaptability, and brand alignment to rich, multi-layered web typography purely through CSS.

The Architecture of Multi-Colored Vector Fonts

Traditional digital fonts contain monochromatic vector paths colored entirely by the CSS color property. In contrast, multi-colored vector fonts contain multiple layers of geometry, each assigned a specific color.

These designs rely on font tables such as the Color Palette Table (CPAL) paired with vector glyph definitions (like the SVG table in OpenType-SVG or the COLR table). The CPAL table acts as an indexed color swatches palette:

  • Layer 1 maps to Color Index 0.
  • Layer 2 maps to Color Index 1.
  • Layer 3 maps to Color Index 2.

A font designer can embed several alternative palettes within the same font file—for instance, one tuned for light backgrounds and another for dark backgrounds.

Selecting Predefined Palettes with font-palette

When a color font contains multiple built-in color configurations, the font-palette property can activate them directly.

.badge-light {
  font-family: "MyColorFont", sans-serif;
  font-palette: light;
}

.badge-dark {
  font-family: "MyColorFont", sans-serif;
  font-palette: dark;
}

The property accepts standard system keywords:

  • normal: The default appearance defined by the font designer.
  • light: The palette tagged by the font creator as optimized for light backgrounds.
  • dark: The palette tagged by the font creator as optimized for dark backgrounds.

Creating Custom Color Palettes with @font-palette-values

When built-in palettes do not match a project's design system, developers can define custom palettes using the @font-palette-values at-rule. This rule binds to a specific font-family and exposes descriptors to remap the embedded colors.

@font-palette-values --BrandTheme {
  font-family: "MyColorFont";
  base-palette: 0;
  override-colors: 
    0 #ff0055,
    1 #00cc88,
    2 #1a1a2e;
}

Key Descriptors inside @font-palette-values

  1. font-family: Explicitly links the custom palette rule to a declared font family name.
  2. base-palette: Specifies the starting point for customization. It can accept a palette index number (e.g., 0, 1) or keywords like light or dark. Any colors not explicitly overridden will inherit from this base.
  3. override-colors: Maps a specific layer's index to a new CSS color definition. The syntax follows a comma-separated list of [index] [color] pairs. Modern CSS color formats, including hsl(), oklch(), and standard hex codes, are fully supported.

Applying the Custom Palette

Once declared, custom palettes are assigned to an element by passing the custom dashed-ident identifier to the font-palette property.

.custom-heading {
  font-family: "MyColorFont", sans-serif;
  font-palette: --BrandTheme;
}

Responsive and Dynamic Color Changes

Because font-palette integrates directly into the CSS cascade, it responds seamlessly to user preferences, dynamic themes, and interactions without reloading font assets.

@font-palette-values --DynamicPalette {
  font-family: "MyColorFont";
  base-palette: light;
}

@media (prefers-color-scheme: dark) {
  @font-palette-values --DynamicPalette {
    font-family: "MyColorFont";
    base-palette: dark;
    override-colors: 0 #ffd700;
  }
}

.icon-text {
  font-family: "MyColorFont", sans-serif;
  font-palette: --DynamicPalette;
}

Using this setup, the browser swaps out the color layers instantly when switching between themes, providing complete stylistic control over vector color glyphs using standard CSS syntax.