Customizing Color Fonts on the Web

Color fonts provide a way to add richness to your designs without sacrificing any of the many benefits of using plain text. Regardless of how decorative a color font is, the underlying text is always searchable, copy/paste-able, scalable, translatable, and compatible with screen readers.

WebKit now supports CSS @font-palette-values. With this at-rule, you can access predefined color palettes provided by the font designer, and you can customize them in order to make the color font a perfect match for the colors in your designs.

ONCE upon a time in the middle of winter, when the flakes of snow were falling like feathers from the clouds, a Queen sat at her palace window, which had an ebony black frame, stitching her husband’s shirts. While she was thus engaged and looking out at the snow she pricked her finger, and three drops of blood fell upon the snow. Now the red looked so well upon the white that she thought to herself, “Oh, that I had a child as white as this snow, as red as this blood, and as black as the wood of this frame!” Soon afterwards a little daughter came to her, who was as white as snow, and with cheeks as red as blood, and with hair as black as ebony, and from this she was named “Snow-White.” And at the same time her mother died.

THIS answer so angered the Queen that she became quite yellow with envy. From that hour, whenever she saw Snow-White, her heart was hardened against her, and she hated the little girl. Her envy and jealousy increased so that she had no rest day or night, and she said to a Huntsman, “Take the child away into the forest. I will never look upon her again. You must kill her, and bring me her heart and tongue for a token.” The Huntsman listened and took the maiden away, but when he drew out his knife to kill her, she began to cry, saying, “Ah, dear Huntsman, give me my life! I will run into the wild forest, and never come home again.”

You can try out @font-palette-values today in Safari 15.4 or later.

Color palettes work great in WebKit with the COLRv0 font file format, and we are investigating other formats like SVG.

Background on the font above

The font in this demo is a revival of Bradley, a “fairytale blackletter” originally released in 1895. The typeface came with a special set of ornate Initial caps meant for drop caps (see also ::initial-letter) and other titling uses, which David digitized this past December for his Font of the Month Club, just in time for the holidays.

Each glyph is made up of a handful of distinct layers (letterform, backdrop, ornate linework, letter outline, and border). Making the layers different-yet-coordinated colors adds depth to the design, taking it beyond what a simple foreground/background can provide. It felt like the perfect use case for a color font with multiple color palettes, and a unique opportunity for a 127-year-old font to play a small part in an emerging font technology.

Palettes in CSS

Fonts can define one or more of their own color palettes inside the CPAL table inside the font file. The palettes are ordered, and so they are identified by index. For example, a font might define color palette #3 that uses blues and greens, but another palette #5 might use reds and oranges. Colors within a palette inside the font are also identified by index – all palettes contain the same number of colors within themselves.

These color palettes can be tweaked or overridden in CSS using font-palette-values. An example looks like this:

@font-palette-values --lilac-blossom {
    font-family: "Bradley Initials DJR Web";
    base-palette: 7;
    override-colors: 0 #fff, 1 #F3B0EB;
}

This example means “Make a color palette named Lilac Blossom, that, when applied to Bradley Initials DJR Web, is just like the 7th palette in the font, but overrides color #0 in that palette to be white, and color #1 in the palette to be #F3B0EB.” If you don’t want to override any colors, that’s no problem – just delete the entire override-colors descriptor.

You can then apply this color palette by simply supplying it to the font-palette property like this:

font-palette: --lilac-blossom;
The Round Table

 

Progressive Enhancement

If you’re using an older version of Safari, or a different browser which doesn’t understand the font-palette property, it will render the default (0th) color palette in the font. Here’s what the above example would look like in such a browser:

The Round Table

 

If the fallback behavior is undesirable for your particular font, you can detect browsers that understand CSS color palettes in your stylesheet by using the @supports media query, like so:

@supports (font-palette: --lilac-blossom) {
    .lilacblossom {
        font-palette: --lilac-blossom;
    }
}

@font-palette-values --lilac-blossom {
    font-family: "Bradley Initials DJR Web";
    base-palette: 7;
    override-colors: 0 #fff, 1 #F3B0EB;
}

Dark Mode

Not all color palettes are clearly visible on all backgrounds. Without color fonts, the color used to render text was entirely determined by the CSS author, but now that fonts can have color palettes defined inside them, it’s up to CSS authors to pick or create a color palette that is legible on the background it’s being rendered on. This can be particularly tricky when font fallback occurs, or when the user has blocked some fonts from loading.

Fonts such as Bradley Initials DJR Web have an extra tool for helping with this, though. Fonts can indicate that certain palettes inside them are usable with light backgrounds or usable with dark backgrounds, and these palettes are hooked up to the font-palette property. You don’t even have to use @font-palette-values!

So, if you want to use a color palette on a dark background, you can simply say font-palette: dark, like this:

ABCDEFG

And the same thing for a light background: font-palette: light:

ABCDEFG

Because the font-palette property has no effect on non-color fonts, it’s safe to set it in conjunction with the prefers-color-scheme media query, like this:

@media (prefers-color-scheme: dark) {
    :root {
        background: black;
        color: white;
        font-palette: dark;
    }
}

Fallback

Because @font-palette-values blocks are scoped to a specific font, you can make multiple of them that share a name. This is really powerful – it means you can define a single color palette name, and have it applied differently to whatever font happens to be rendered with it. Here’s an example:

@font-palette-values --lilac-blossom {
    font-family: "Bradley Initials DJR Web";
    base-palette: 1;
}

@font-palette-values --lilac-blossom {
    font-family: "Megabase";
    base-palette: 2;
}

<div style="font-palette: --lilac-blossom;">
    <div style="font-family: 'Bradley Initials DJR Web';">Pizza is amazing!</div>
    <div style="font-family: 'Megabase Web';">Is there any food better than pizza?</div>
</div>

This will have Bradley Initials DJR Web’s Lilac Blossom palette applied to Bradley Initials DJR Web, and Megabase’s Lilac Blossom palette applied to Megabase. And you only had to specify the font-palette property once!

Contextual color

In addition to pulling colors from palettes, some color fonts set aside special shapes that are connected to the foreground color of the current element. This makes them extra flexible, but it also means that these shapes operate independently from font-palette. In these cases, you can simply use the color property to change their color, like in this demo using Megabase.

<div style="font-family: 'Megabase Web';">
    <div style="color: black;">They were just pushed into space.</div>
    <div style="color: blue;">As much as I care about you.</div>
</div>

They were just pushed into space.

As much as I care about you.

Conclusion

Of course, with power comes responsibility; just because you can change colors, doesn’t mean you always should. Often the colors in a palette are coordinated to harmonize aesthetically, so it’s good to have a sense of how they are meant to relate to one another. You can look at the font’s predefined color palettes to see how the font designer assigned the roles for each color in the palette, and tweak accordingly.

It is also important to choose colors that contrast strongly against the background in order to keep your text readable and your webpage accessible. Colors in the palette that are used to form the base of the letters should typically “pop” against the background, while supporting layers like shadows, outlines, and decorative elements might contrast less in order to keep them from overpowering the letterforms.

Color fonts are a great improvement over graphic images, because they work by default with screen readers, copy/paste, and find-in-page. Also, they gracefully show fallback text if the font somehow fails to load, and they reflow if the browser window resizes. Not only that, color fonts are more flexible than graphic images, because they can incorporate the foreground color of the element using them into the design of the font.

Color fonts are not meant to take the place of single-color fonts. But used in moderation, at a big enough size in the right circumstance, they can be the perfect icing on the cake!