Skip to content

Color and Palettes

Jace edited this page Jun 6, 2026 · 1 revision

Color and Palettes

Every mark resolves to one ink color (or a gradient). You set it three ways: a raw CSS color string, a { palette, swatch } reference into a curated palette family, or a multi-stop gradient. This page covers all three, plus the named swatches available out of the box.

The default color is the mild family's yellow swatch (#f5e6a8) at opacity: 0.55.

Note: There is no preset option and no named-color shorthand. A bare string like "pink" is passed straight through as a CSS named color, not a palette lookup. To reach a palette swatch you must use the { palette, swatch } object form shown below.


CSS color strings

color accepts any CSS color string: hex (3- or 6-digit), rgb()/rgba(), hsl()/hsla(), CSS named colors, currentColor, or var(--token). The type is ColorValue = string.

import { highlight } from "@highlighters/core";

highlight(".term", { color: "#ffd54f" });
highlight(".term", { color: "rgb(255 213 79)" });
highlight(".term", { color: "hsl(48 100% 65%)" });
highlight(".term", { color: "var(--brand-highlight)" });
highlight(".term", { color: "currentColor" });

An empty or whitespace-only string is treated as unset, so the resolved color falls back to the palette default (if given) or the library default.

Opacity and blend mode

color sets the hue; opacity (0-1, default 0.55) sets overall ink alpha, and blendMode (default "multiply") controls how the ink composites over the text behind it.

highlight(".term", {
  color: "#5ad7ff",
  opacity: 0.7,
  blendMode: "multiply",
});

blendMode accepts "multiply" | "normal" | "darken" | "screen" | "overlay" | "color-burn". Marker ink reads best with "multiply" (the default), which lets the page text stay legible through the color. See Ink-and-Optics for the full ink model.


Palettes and named swatches

A palette is a curated family of swatches tuned so any pair within it reads coherently when you color-code. There are five families. Each family's swatches map is ordered, and that order is the color-coding cycle.

PaletteName = "fluorescent" | "mild" | "vintage" | "neutral" | "calm".

fluorescent

Swatch Hex
yellow (default) #fff14d
green #9bff5a
orange #ffb24d
pink #ff6fae
blue #5ad7ff
purple #c08bff

mild (library default family)

Swatch Hex
yellow (default) #f5e6a8
green #bfe0b2
blue #aacfe0
pink #eec2cf
orange #f0cdb0
purple #cdc1e0

vintage

Swatch Hex
mustard (default) #e3c567
olive #bcc06a
rust #d99873
rose #d39ba0
teal #7fb3a8
plum #a98bb0

neutral

Swatch Hex
sand (default) #e7dcc4
stone #d8d2c4
clay #dcc3b0
sage #cdd6c2
slate #c4ccd2
taupe #d3c8c2

calm

Swatch Hex
sky (default) #bcd6ec
mint #bfe4d6
lavender #cfcae8
blush #ecd2da
seafoam #c6e3df
periwinkle #c2cce8

Default swatch per family: fluorescent → yellow, mild → yellow, vintage → mustard, neutral → sand, calm → sky (the least text-obscuring hue in each).

Using a palette swatch

Pass color as a { palette, swatch } object:

highlight(".term", { color: { palette: "fluorescent", swatch: "pink" } });

Or pin a family and let it use that family's default swatch by setting palette with no color:

highlight(".term", { palette: "vintage" }); // resolves to mustard #e3c567

Resolution rules, in order:

  1. A non-empty color string wins outright.
  2. A color object ({ palette, swatch }) resolves through that family.
  3. Otherwise, if palette is set, the family's default swatch is used.
  4. Otherwise, the library default (mild → yellow, #f5e6a8).

PaletteSwatch is { palette: PaletteName; swatch: string }. An unknown family or swatch throws at resolve time.

Color-coding by cycling swatches

Because each family is ordered, you can walk it to color-code categories. There is no built-in cycler; index into the palette yourself:

import { highlight, getPalette } from "@highlighters/core";

const family = "fluorescent";
const names = Object.keys(getPalette(family).swatches);

categories.forEach((cat, i) => {
  const swatch = names[i % names.length];
  highlight(cat.selector, { color: { palette: family, swatch } });
});

Custom colors and palette helpers

You do not have to use a palette at all; any CSS string is a valid custom color. For programmatic access to the curated families, the core exports four helpers (all pure and SSR-safe, also available from @highlighters/core/path).

import {
  PALETTES,      // Record<PaletteName, Palette> - all families as data
  getPalette,    // (name) => Palette        - throws on unknown family
  resolveSwatch, // (ref)  => ColorValue      - throws on unknown swatch
  defaultSwatch, // (name) => ColorValue      - the family's default color
} from "@highlighters/core";

resolveSwatch({ palette: "calm", swatch: "blush" }); // "#ecd2da"
defaultSwatch("neutral");                              // "#e7dcc4"
getPalette("mild").swatches.green;                     // "#bfe0b2"
interface Palette { name: PaletteName; swatches: Record<string, ColorValue>; }
interface PaletteSwatch { palette: PaletteName; swatch: string; }

You can resolve a swatch to its hex and then tweak it before passing it as a custom color, e.g. to darken or add alpha for a specific surface.


Gradients

For a multi-stop ramp, set gradient. When present it overrides color. Only linear gradients are supported.

interface GradientConfig {
  type: "linear";
  angle?: number;        // CSS degrees, defaults to 85
  stops: GradientStop[]; // two or more for a visible gradient
}
interface GradientStop {
  offset: number;        // 0 (start) to 1 (end)
  color: ColorValue;     // any CSS color string
  opacity?: number;      // 0-1, defaults to 1
}
highlight(".term", {
  gradient: {
    type: "linear",
    angle: 85,
    stops: [
      { offset: 0, color: "#fff14d" },
      { offset: 1, color: "#ff6fae" },
    ],
  },
});

Each stop's color is an independent CSS string, so you can mix palette hexes and arbitrary colors by resolving swatches first:

import { highlight, resolveSwatch } from "@highlighters/core";

highlight(".term", {
  gradient: {
    type: "linear",
    stops: [
      { offset: 0, color: resolveSwatch({ palette: "fluorescent", swatch: "yellow" }) },
      { offset: 1, color: resolveSwatch({ palette: "fluorescent", swatch: "orange" }), opacity: 0.8 },
    ],
  },
});

Glow color

The optional Ink-and-Optics glow layer has its own glow.color. When left as the empty default it resolves to a brightened form of the ink color at render time; set it to override the emission hue.

highlight(".term", {
  color: "#9bff5a",
  glow: { enabled: true, intensity: 0.6, color: "#d6ff8a" },
});

Contrast checking

contrastBackground declares the background the mark composites against. It is not rendered; it drives only a dev-time WCAG-contrast warning so you catch low-legibility combinations during development. See Accessibility-and-Reflow.

highlight(".term", {
  color: "#bcd6ec",
  contrastBackground: "#ffffff",
});

Framework usage

The same color, palette, and gradient fields apply everywhere. All bindings re-export PaletteName, PaletteSwatch, Palette, GradientConfig, and GradientStop.

React

import { Highlight, useHighlight } from "@highlighters/react";

// Component
<Highlight as="mark" options={{ color: { palette: "mild", swatch: "pink" } }}>
  rendered text
</Highlight>

// Hook
function Term() {
  const ref = useRef<HTMLSpanElement>(null);
  useHighlight(ref, { color: "#5ad7ff", opacity: 0.7 });
  return <span ref={ref}>rendered text</span>;
}

Vue

<script setup>
import { Highlight } from "@highlighters/vue";
</script>

<template>
  <Highlight as="mark" :options="{ color: { palette: 'vintage', swatch: 'teal' } }">
    rendered text
  </Highlight>
</template>
// Composable
import { useHighlight } from "@highlighters/vue";
const el = ref<HTMLElement | null>(null);
useHighlight(el, { palette: "calm" }); // calm's default swatch (sky)

Svelte

<script>
  import { highlight } from "@highlighters/svelte";
</script>

<p use:highlight={{ color: { palette: "fluorescent", swatch: "green" } }}>
  rendered text
</p>

<p use:highlight={{
  gradient: {
    type: "linear",
    stops: [
      { offset: 0, color: "#fff14d" },
      { offset: 1, color: "#ff6fae" },
    ],
  },
}}>
  gradient ink
</p>

See also

  • Ink-and-Optics - how the ink deposits, blends, and glows over the color you pick
  • Options-Reference - the full color / palette / gradient / opacity / blendMode field reference
  • API-Reference - signatures for getPalette, resolveSwatch, defaultSwatch, PALETTES
  • Accessibility-and-Reflow - contrastBackground and legible color choices
  • Recipes - color-coding, multi-category highlighting, and themed marks

Clone this wiki locally