Skip to content

Options Reference

Jace edited this page Jun 6, 2026 · 1 revision

Options Reference

The complete HighlightOptions object: every field, grouped, with its type, default, range, and meaning. This is the field-level reference for tuning a mark. For the function signatures that consume these options (highlight, highlightAll, highlightSelection, the framework bindings), see API-Reference.

All fields are optional. Defaults below are the resolved baseline from DEFAULT_OPTIONS. A partial object is deep-merged over that baseline by resolveOptions(): scalars take your value, the namespaced groups (tip, ink, speed, edge, paper, glow, animation) merge field-wise, and shape/markType collapse onto a single mark kind.

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

highlight("p", {
  markType: "highlight",
  color: { palette: "fluorescent", swatch: "yellow" },
  opacity: 0.6,
  edge: { waviness: 1.5, cap: "round" },
  animation: { duration: 480, direction: "center-out" },
});

There is no preset option and no named-color shorthand. Some JSDoc snippets show { preset: "wet", color: "pink" } style usage. HighlightOptions has no preset field, and a bare string like "pink" is passed straight through as a CSS color, not a palette lookup. To reach a palette swatch you pass { palette, swatch } (see Color-and-Palettes). Treat any preset/named-color examples as aspirational; the real fields are below.


Top-level

Option Type Default Range / values Meaning
shape ShapeType "highlight" "highlight" | "underline" | "overline" | "strike-through" Mark kind. Synonym of markType.
markType MarkType "highlight" same as shape Mark kind. Synonym of shape; whichever is provided last wins.
color ColorValue | PaletteSwatch "#f5e6a8" (mildyellow) any CSS color string, or { palette, swatch } Solid ink color or palette reference. Empty/whitespace string is treated as unset.
palette PaletteName (unset) "fluorescent" | "mild" | "vintage" | "neutral" | "calm" Palette family to draw the default swatch from when color is unset.
gradient GradientConfig null see GradientConfig Multi-stop gradient; overrides color when present.
opacity number 0.55 0-1 (clamped) Overall ink alpha.
blendMode BlendMode "multiply" "multiply" | "normal" | "darken" | "screen" | "overlay" | "color-burn" Ink compositing model.
tip TipOptions see tip - Nib geometry.
ink InkOptions see ink - Ink behavior.
speed SpeedDynamicsOptions see speed - Speed-aware ink deposit (live selection only; Beta).
edge EdgeOptions see edge - Edge waviness, roughness, cap, radius.
paper PaperOptions see paper - Paper surface.
glow GlowOptions see glow - Additive fluorescence/glow.
snap SnapMode "word" (baseline; per-entry-point default differs) "none" | "word" | "line" | "glyph" Boundary-snapping mode. highlight() derives it from the target; highlightAll()"line"; highlightSelection()"word".
fadeOnClear boolean true - Fade the live selection out on clear instead of removing instantly. Live-selection only.
seed number null any number Explicit deterministic seed; derived from target identity when omitted.
renderer RendererTierPreference "auto" "auto" | "svg" | "css" | "highlight-api" Renderer tier preference / pin.
animation AnimationOptions see animation - Entrance animation.
semantic boolean false - Wrap each targeted run in a real <mark> element for semantics. Reversible by remove().
contrastBackground ColorValue null any CSS color Background the mark composites against; drives only the dev-time WCAG-contrast warning. Not rendered.

ColorValue = string: any CSS color string (hex, rgb(), hsl(), named, currentColor, or var(...)).

shape and markType are two names for the same field. Pick one; if both are present, the last-provided value wins.

<!-- Svelte: underline instead of a highlight -->
<p use:highlight={{ markType: "underline", color: "#3b82f6" }}>
  Underlined text.
</p>

See Mark-Types-and-Shapes for the four mark kinds and Snapping-and-Overshoot for snap.


tip — TipOptions

The nib geometry. The renderer derives the chisel lean from angle and the band width.

Field Type Default Range Meaning
type TipType "chisel" "chisel" | "bullet" | "fine" Nib shape.
width number 16 px Reserved. Not consumed by the renderer.
thickness number 4 px Reserved. Not consumed by the renderer.
angle number 35 degrees Nib angle relative to the stroke (chisel slant).
overshoot number 2 signed px How far each outer end runs past the text edge; negative pulls in short. Inner edges of a wrapped run always overlap.
overshootJitter number 1 px, >= 0 Per-end deterministic variance of overshoot.
angleJitter number 0 degrees, >= 0 Per-line deterministic variance on the chisel angle.

width and thickness are schema-only: they exist on the type but the renderer ignores them. See Tips-and-Edges.

highlight("h2", {
  tip: { type: "chisel", angle: 28, overshoot: 4, overshootJitter: 2 },
});

ink — InkOptions

How the ink behaves as it lays down. All fields are normalized 0-1 unless noted.

Field Type Default Range Meaning
flow number 0.45 0-1 Deposit amount; raises width, softens edges.
viscosity number 0.5 0-1 Inverse flow; raises edge sharpness and skip frequency.
feathering number 0.2 0-1 Capillary lateral edge spread.
streakiness number 0.25 0-1 Lengthwise lighter/darker lanes within a stroke.
dryout number 0.1 0-1 Probabilistic alpha gaps (skipping), coupled to viscosity.
startEndBuildup number 0.1 -1-1 Deposit variation at stroke ends: positive pools ink, negative suppresses end darkening.
flowFade number 0.5 0-1 Directional dry-out along each line: saturated at touchdown, drier toward the end.

See Ink-and-Optics for how these interact with paper.absorbency and the renderer tier.

// A wetter, glossier stroke
highlight(".note", {
  ink: { flow: 0.7, viscosity: 0.3, feathering: 0.35, dryout: 0 },
});

speed — SpeedDynamicsOptions (Beta, live-selection only)

Speed-aware ink deposit: a faster swipe deposits less ink. This group engages only under highlightSelection(), and only during a primary-button fine-pointer (mouse/pen) drag. It is suppressed under prefers-reduced-motion, and is a byte-identical no-op for programmatic, keyboard, or static selections, for touch, for SSR, and when enabled is false. The resolver clamps slowSpeed/fastSpeed so fastSpeed >= slowSpeed.

Field Type Default Range Meaning
enabled boolean false - Master enable.
sensitivity number 1 0-1 (clamped; 0 disables) Overall strength.
slowSpeed number 2.5 px/ms, >= 0 Swipe speed at/below which ink is wettest.
fastSpeed number 10.5 px/ms, >= 0 Swipe speed at/above which ink is driest.
minDeposit number 0.4 0-1 (clamped) Legibility floor: the fastest swipe still deposits this fraction.
smoothing number 1 0-1 (clamped) Velocity EMA weight on the newest sample.
resolution number 24 clamped 4-24, rounded Core gradient stops per line.
dryoutBoost number 1 0-1 (clamped) How much a fast swipe adds skipping.
streakBoost number 0.08 0-1 (clamped) How much a fast swipe adds streakiness.
featherReduce number 1 0-1 (clamped) How much a fast swipe sharpens the edge.
poolBoost number 1 0-1 (clamped) How much deceleration into a line end pools ink there.
import { highlightSelection } from "@highlighters/core";

highlightSelection({
  speed: { enabled: true, sensitivity: 0.8, minDeposit: 0.5 },
});

See Selection-Highlighting for the live-selection lifecycle and Animation for the reduced-motion gate.


edge — EdgeOptions

Edge appearance, from straight to frayed. Setting waviness and roughness to 0 yields clean geometric edges.

Field Type Default Range Meaning
waviness number 1 absolute px Peak wavy-edge displacement.
frequency number 22 px Wave density, as the px segmentLength between grid vertices. Width-independent.
roughness number 0.2 0-1 High-frequency micro-jitter on the base wave.
cap EdgeCap "round" "flat" | "round" | "square" End-cap style for the band's leading/trailing edges.
radius number 5 absolute px (clamped against short marks) Corner radius.

frequency is a px segment length, not a count, so the wave reads the same density regardless of mark width. See Tips-and-Edges.

// Crisp, near-geometric band
highlight(".badge", {
  edge: { waviness: 0, roughness: 0, cap: "square", radius: 2 },
});

paper — PaperOptions

The paper surface. Multiplies feathering and softens edges.

Field Type Default Range Meaning
absorbency number 0.3 0-1 Higher wicks more, growing feather and softening edges.
highlight("blockquote", { paper: { absorbency: 0.6 } });

glow — GlowOptions

Additive fluorescence emission over the multiply ink. Off by default.

Field Type Default Range Meaning
enabled boolean false - Master enable.
intensity number 0.5 0-1 Additive emission strength.
spread number 4 px Bloom spread radius.
color ColorValue "" (resolves to a brightened form of the ink color) CSS color Emission hue.

When color is left empty, the glow hue is derived from the ink color at render time. See Ink-and-Optics.

highlight("mark.live", {
  color: { palette: "fluorescent", swatch: "green" },
  glow: { enabled: true, intensity: 0.7, spread: 6 },
});

animation — AnimationOptions

The entrance animation (the draw-on swipe). Automatically suppressed under prefers-reduced-motion: reduce.

Field Type Default Range / values Meaning
draw boolean true - Enable the draw-on swipe (subject to the reduced-motion gate).
duration number 420 ms (positive; non-positive falls back to default) Duration of a single band's draw-on.
easing EasingValue "ease-out" "linear" | "ease" | "ease-in" | "ease-out" | "ease-in-out", or any valid CSS easing string Easing for the draw-on sweep.
direction AnimationDirection "left-to-right" "left-to-right" | "right-to-left" | "center-out" Sweep direction across each band.
stagger number 90 ms Per-line / per-mark delay (sequential pen travel).
trigger AnimationTrigger "immediate" "immediate" | "in-view" When the animation begins. in-view arms an IntersectionObserver.
threshold number 0.2 0-1 IntersectionObserver threshold for in-view.
rootMargin string "0px" CSS margin string IntersectionObserver root margin for in-view.
repeat boolean false - Re-animate every time the mark enters view, vs one-shot.
// React: draw on scroll-into-view, once
import { Highlight } from "@highlighters/react";

<Highlight options={{
  animation: { trigger: "in-view", threshold: 0.4, repeat: false },
}}>
  Reveals as it scrolls into view.
</Highlight>

See Animation for the full draw-on model and reduced-motion behavior.


Gradient types

GradientConfig

A multi-stop gradient. When present, it overrides color.

interface GradientConfig {
  type: "linear";
  angle?: number;        // CSS degrees. Defaults to 85deg.
  stops: GradientStop[]; // Two or more for a visible gradient.
}
Field Type Default Meaning
type "linear" (required) Discriminant. Only "linear" is supported.
angle number 85 Gradient angle in CSS degrees.
stops GradientStop[] (required) Color stops; supply two or more for a visible gradient.

GradientStop

interface GradientStop {
  offset: number;   // 0 (start) to 1 (end).
  color: ColorValue;
  opacity?: number; // 0-1. Defaults to 1.
}
Field Type Default Range Meaning
offset number (required) 0-1 Position of the stop along the gradient.
color ColorValue (required) any CSS color Stop color.
opacity number 1 0-1 Stop opacity.
highlight(".headline", {
  gradient: {
    type: "linear",
    angle: 85,
    stops: [
      { offset: 0, color: "#fff14d" },
      { offset: 1, color: "#ff6fae" },
    ],
  },
});

PaletteSwatch

A reference into a palette family, used as the object form of color.

interface PaletteSwatch {
  palette: PaletteName; // "fluorescent" | "mild" | "vintage" | "neutral" | "calm"
  swatch: string;       // a swatch name within that family
}
Field Type Meaning
palette PaletteName The palette family.
swatch string The swatch name within that family.

You can reach a palette color in two ways: pass the swatch object as color, or pass palette alone to use that family's default swatch.

// Explicit swatch
highlight("p", { color: { palette: "mild", swatch: "pink" } });

// Family default swatch (mild → yellow)
highlight("p", { palette: "mild" });

The full swatch tables live in Color-and-Palettes.


Enums

Type Values
MarkType / ShapeType "highlight" | "underline" | "overline" | "strike-through"
TipType "chisel" | "bullet" | "fine"
EdgeCap "flat" | "round" | "square"
BlendMode "multiply" | "normal" | "darken" | "screen" | "overlay" | "color-burn"
SnapMode "none" | "word" | "line" | "glyph"
RendererTierPreference "auto" | "svg" | "css" | "highlight-api"
RendererTier "svg" | "css" | "highlight-api"
AnimationDirection "left-to-right" | "right-to-left" | "center-out"
AnimationTrigger "immediate" | "in-view"
EasingValue "linear" | "ease" | "ease-in" | "ease-out" | "ease-in-out" or any valid CSS easing string
PaletteName "fluorescent" | "mild" | "vintage" | "neutral" | "calm"
ColorValue string (any CSS color)

Resolution and merging

resolveOptions(input?) turns a partial HighlightOptions into a fully-defaulted ResolvedOptions (every field non-optional). It is pure and SSR-safe:

  • opacity is clamped to 0-1.
  • speed fields are clamped as noted in the speed table.
  • animation.duration must be positive; non-positive values fall back to the default.
  • Non-finite numbers fall back to their defaults.
  • A palette with no color resolves to that family's default swatch.

mergeOptions(base, override) deep-merges two partials: scalars take override; the namespaced groups (tip, ink, speed, edge, paper, glow, animation) merge field-wise; shape/markType collapse onto a single mark kind (override wins, then override.shape, then base). MarkHandle.update() and highlightSelection().update() compose options through this same merge, so partial updates accumulate without re-seeding stable geometry.

import { resolveOptions, mergeOptions, DEFAULT_OPTIONS } from "@highlighters/core";

const resolved = resolveOptions({ opacity: 2 }); // opacity clamped to 1
const merged = mergeOptions({ ink: { flow: 0.4 } }, { ink: { viscosity: 0.7 } });
// merged.ink === { flow: 0.4, viscosity: 0.7, ...defaults }

See How-It-Works for the determinism model and SSR-Support for the DOM-free path.


Related pages

Clone this wiki locally