How to opentype colour font tables: complete reference
- Step 1COLR + CPAL (always a pair) — `COLR` maps each base glyph to a sequence of layers; each layer names a glyph ID and a palette index. `CPAL` holds one or more palettes of RGBA entries. COLRv0 layers are flat; COLRv1 adds a paint graph (gradients, transforms, compositing). `COLR` is meaningless without `CPAL`.
- Step 2sbix (Apple bitmap) — `sbix` (Standard Bitmap Graphics) stores per-glyph image data — typically PNG — across one or more strikes (resolutions). A header lists strikes; each strike has per-glyph offsets to the image bytes. No vector data; pure raster.
- Step 3CBDT / CBLC (Google bitmap) — `CBLC` (Colour Bitmap Location) is the index — strikes and per-glyph metrics/offsets; `CBDT` (Colour Bitmap Data) holds the actual image bytes. The pair mirrors the older monochrome `EBLC`/`EBDT` design but for colour PNGs.
- Step 4SVG (embedded documents) — The `SVG ` table maps glyph-ID ranges to embedded SVG document fragments. The most expressive model — it can do anything SVG can — but the heaviest and least portable across engines.
- Step 5Renderer priority — When multiple formats are present, each engine uses its own preference (broadly: SVG, then COLR, then bitmap on some engines; CoreText favours `sbix`). If the preferred format is missing and the others aren't supported, the engine renders the base outline.
- Step 6What the remover keeps — The remover deletes all colour/bitmap tables and keeps the outline data plus `cmap`, metrics, `name`, and layout tables. The result is a valid monochrome SFNT — see [the remover](/font-tools/colour-table-remover).
Colour table field summary
High-level structure of each table. Exact byte layouts are in the OpenType spec; the remover treats each as an opaque tagged blob to delete.
| Table | Key fields | Stores | Partner table |
|---|---|---|---|
COLR v0 | version, baseGlyphRecords (glyphID → layer range), layerRecords (glyphID + paletteIndex) | Flat colour layer composition | CPAL (required) |
COLR v1 | v0 fields + baseGlyphListOffset (paint graph: gradients, transforms, compositing) | Rich vector colour | CPAL (required) |
CPAL | numPalettes, numPaletteEntries, colorRecords (BGRA) | Colour palette(s) | COLR |
sbix | version, flags, numStrikes, strike offsets → glyph data records (PNG) | Per-glyph PNG bitmaps | — (standalone) |
CBLC/CBDT | CBLC: bitmapSizeTables + index subtables; CBDT: image data | Colour PNG bitmaps + location | Each other (pair) |
SVG | version, svgDocumentList (glyphID ranges → SVG doc offsets) | Embedded SVG documents | — (standalone) |
EBLC/EBDT | Legacy embedded bitmap location + data | Mono/grayscale embedded bitmaps | Each other (pair) |
Support and removal matrix
Browser support is for colour rendering of that table. The remover drops every row.
| Table | Vendor | Renders in | Removed? |
|---|---|---|---|
COLR v0 + CPAL | Microsoft | All modern browsers | Yes |
COLR v1 + CPAL | Microsoft | Chrome 98+, Firefox 109+, Safari 16.4+ | Yes |
sbix | Apple | Safari / CoreText | Yes |
CBDT/CBLC | Chrome, Firefox | Yes | |
SVG | Adobe/Mozilla | Firefox; partial elsewhere | Yes |
EBDT/EBLC | (legacy) | Limited | Yes |
Cookbook
How these tables appear in real fonts and how to read or remove them.
COLR/CPAL layer composition (conceptual)
ExampleA base glyph references a run of layers; each layer is a glyph drawn in a palette colour. CPAL supplies the colours.
COLR baseGlyph 'A' -> layers [ (glyph=A.base, palette=0),
(glyph=A.accent, palette=2) ]
CPAL palette 0: entries [ #1A1A1A, #E10000, #0044CC, ... ]
-> 'A' renders as A.base in #1A1A1A under A.accent in #0044CCsbix strikes (conceptual)
Examplesbix carries multiple resolutions (strikes). Each strike has a PNG per glyph; the renderer picks the strike closest to the target size.
sbix strikes: [ ppem=20, ppem=32, ppem=64, ppem=128 ] strike ppem=128 -> glyph 0x1F600 -> <PNG 128x128 bytes> -> heavy: every glyph stored as several PNGs
Identify colour tables in a directory dump
ExampleRun a font through the metadata extractor and read the table tags to know what colour format it carries.
tables: cmap glyf head hhea hmtx COLR CPAL name OS/2 post
^^^^ ^^^^ -> Microsoft COLR/CPAL vector colourRemove every colour table
ExampleThe remover deletes all eight tags and keeps the rest. The directory is rebuilt and re-sorted by tag.
before: cmap glyf COLR CPAL sbix SVG CBDT CBLC name OS/2
after : cmap glyf name OS/2
(COLR CPAL sbix 'SVG ' CBDT CBLC all gone; EBDT/EBLC too if present)Renderer priority when formats coexist
ExampleA font with both COLR and sbix is painted differently per engine; each uses its preferred format, others are inert.
font tables: glyf, COLR, CPAL, sbix Safari -> uses sbix Chrome -> uses COLR Firefox -> uses COLR (remove all -> every engine renders glyf outlines)
Edge cases and what actually happens
Every row below was probed against the live API. Some documented requirements (alphabetical axis order, numerical tuple order) are not actually enforced in practice — useful to know if you've been blaming the wrong thing for a 400.
`COLR` present without `CPAL`
Invalid fontCOLR references palette indices that live in CPAL. Without CPAL there is nothing to reference and the font is malformed; renderers fall back to outlines. The remover deletes COLR regardless, which clears the invalid pairing.
The `SVG ` tag's trailing space
Spec detailThe OpenType tag is exactly four characters: S, V, G, space. Tools that match "SVG" (three chars) will miss it. The remover matches the correct SVG tag, so the table is actually removed.
Multiple `CPAL` palettes (dark mode)
SupportedCPAL can hold several palettes (e.g. a light and a dark variant) selectable by the renderer. Removing colour discards all palettes along with COLR; if you need palette-aware behaviour, that's a colour feature you're choosing to drop.
`sbix` strikes at sizes you don't need
Bloatsbix often stores many resolutions, most of which a given site never uses — a major reason these fonts are huge. The remover deletes the whole table; there is no 'keep one strike' option. For partial trimming you'd need a dedicated bitmap editor.
`EBDT`/`EBLC` grayscale bitmaps removed
ExpectedThe legacy embedded-bitmap pair can hold mono or grayscale strikes, not just colour. The remover drops them because its goal is outline-only output. If you specifically wanted hinted embedded bitmaps, this isn't the tool.
head checkSumAdjustment after removal
By designRemoving tables changes offsets, but the remover does not recompute the head table's checkSumAdjustment. Renderers ignore it; strict validators may flag it. Run a checksum fixer if your validation requires a conformant value.
Renderer priority varies by engine
Engine-specificThere is no single universal priority order — CoreText favours sbix, Chromium/Gecko favour COLR/SVG depending on version. Don't assume one order across all browsers; test, or strip to outlines for fully predictable rendering.
Variable colour font (COLRv1 + fvar)
SupportedCOLRv1 can interact with variations. The remover deletes COLR/CPAL but leaves fvar/gvar and the outlines intact, so you keep a variable monochrome font. The colour-axis behaviour is what you're discarding.
`.ttc` collection with colour faces
Unsupported formatSystem emoji fonts often ship as .ttc. The remover rejects collections (ttcf magic). Extract a single face first, then strip its colour tables.
Frequently asked questions
Which OpenType tables carry colour?
COLR+CPAL (Microsoft vector), sbix (Apple PNG bitmaps), CBDT+CBLC (Google PNG bitmaps), and SVG (embedded SVG documents). The legacy EBDT+EBLC pair carries embedded bitmaps too. The Colour Table Remover drops all of them.
What's the difference between COLRv0 and COLRv1?
v0 composes flat colour layers — each layer is a glyph drawn in a palette colour. v1 adds a paint graph: gradients (linear/radial/sweep), affine transforms, and compositing/blend modes. v1 needs newer browsers (Chrome 98+, Firefox 109+, Safari 16.4+).
Why does COLR always need CPAL?
COLR only stores palette indices, not actual colours. CPAL holds the RGBA palette those indices point into. A font with COLR but no CPAL is malformed and renders as outlines.
Can a font have several colour formats at once?
Yes — e.g. COLR+CPAL plus sbix or SVG . Each engine renders its preferred one; the rest is dead weight on that platform. The remover strips all of them for guaranteed monochrome output.
How big is a typical colour-emoji font?
It's dominated by the format. A sbix font like Apple Color Emoji can be tens of MB; Google's CBDT Noto Color Emoji is multi-MB; a COLR vector build of similar coverage is a small fraction of that — vector colour is far more compact than bitmap.
Which engine renders which table?
COLR v0 everywhere; COLRv1 in Chrome 98+/Firefox 109+/Safari 16.4+; sbix in Safari/CoreText; CBDT/CBLC in Chrome/Firefox; SVG mostly Firefox. That fragmentation is why a monochrome fallback is often useful.
Why does the SVG table have a trailing space?
OpenType table tags are exactly four bytes. 'SVG' is three letters, so it's padded with a space to SVG . Tools that match the three-letter string miss it; the remover matches the correct four-character tag.
Does removing colour tables leave a valid font?
Yes — the directory is rebuilt (entries re-sorted by tag, offsets recomputed) and the outline/metrics/name/layout tables are preserved. The one caveat is the head checkSumAdjustment, which isn't recomputed but which renderers ignore.
Can I keep one colour format and drop the rest?
Not with this tool — it removes all eight tags and has no options. For selective removal you'd need a custom directory-surgery step that keeps the tags you want.
What happens to variable-font tables?
They're preserved. The remover only deletes the colour/bitmap tags; fvar, gvar, avar, etc. survive, so a variable colour font becomes a variable monochrome font.
How do I see which colour tables a font has?
Dump the table directory with Font Metadata Extractor and look for COLR/CPAL, sbix, CBDT/CBLC, or SVG . To check an individual glyph's outline, use Glyph Inspector.
What's the renderer priority when formats conflict?
There isn't one universal order — it depends on the engine and version (CoreText leans to sbix, Chromium/Gecko to COLR/SVG ). For predictable rendering across engines, strip to outlines with the Colour Table Remover.
Privacy first
Every JAD Font tool runs entirely in your browser using opentype.js and the wawoff2 WASM Brotli encoder. Your fonts never leave your device — verified by zero outbound network requests during processing.