Skip to content
WANCRAFT

C.44Typography & Text

Marker Highlight

Hand-drawn annotations — marker swipes, underlines, circles, boxes — that draw in on view.

NewReactSVGCSSTailwindintermediate

Overview

Marker Highlight wraps inline text and draws a hand-made annotation around it: a felt-tip highlight, a wobbly underline, a loose circle, a pen box, a strike-through or brackets. The SVG paths are generated from a seed with a small deterministic PRNG, so they look drawn by hand but are identical on every render, and they are only built after measuring on the client, so there is nothing to mismatch during hydration. Highlights, underlines and strikes follow each wrapped line separately (via getClientRects) and draw line after line. It can draw when scrolled into view, on hover or focus, or on mount, and re-measures on resize and once fonts load.

01Installation

Method 01 · Registry

CLI verified

Uses the shadcn CLI in a project initialised with shadcn init. Installs the file to components/ui/marker-highlight.tsx and adds its dependencies.

npx shadcn@latest add https://wancraft.my/r/marker-highlight.json

Method 02 · Copy and paste

  1. 1. No extra dependencies — React and Tailwind CSS only.
  2. 2. Copy the source from the Code tab into components/ui/marker-highlight.tsx.
  3. 3. Import it and adjust props.
Dependencies
None
Peer
react ≥ 18, tailwindcss ≥ 4
Added
13 Oct 2026
Updated
—

02Usage

The default configuration. Change properties above to generate a tailored example in the Usage tab.

example.tsx
import { MarkerHighlight } from "@/components/ui/marker-highlight";

export function MarkerHighlightExample() {
  return (
    <p className="max-w-md text-2xl leading-snug">
      <MarkerHighlight>
        the part that matters
      </MarkerHighlight>
    </p>
  );
}

03Props

PropTypeDefaultDescription
type"highlight" | "underline" | "circle" | "box" | "strike" | "bracket""highlight"Annotation style.
colorstring"#FF7448"Stroke / marker colour.
strokeWidthnumber2Stroke width in px; the highlight marker is sized from the line height.
durationnumber800Total draw time in ms, shared across lines and strokes by length.
delaynumber0Delay before drawing, in ms.
trigger"view" | "hover" | "mount""view"What draws the annotation. Hover also responds to focus within, and undraws on leave.
paddingnumber4Space between text and annotation, in px.
seednumber7Seed for the hand-drawn wobble.
multilinebooleantrueAnnotate each wrapped line separately (highlight, underline, strike).
childrenReactNode—Inline content to annotate.

04Features

  • 01Six annotation types with seeded, hand-drawn SVG paths
  • 02Stable shapes: the same seed always draws the same path
  • 03Per-line highlights, underlines and strikes via getClientRects
  • 04Draws stroke after stroke, with time shared by length
  • 05View, hover/focus and mount triggers
  • 06Re-measures on resize and after web fonts load
motion · tweenmotion · staggerinput · viewportinput · hoverinput · focus

05Accessibility

  • The text stays real, selectable inline text; the annotation SVG is aria-hidden and ignores the pointer.
  • The annotation is decorative emphasis — wrap the text in <mark> or <strong> yourself when the emphasis carries meaning.
  • With prefers-reduced-motion the annotation appears fully drawn, without animation.

06Limitations

  • Circle, box and bracket wrap the whole element; across several lines they enclose the combined bounds.
  • Shapes are drawn after client-side measurement, so they do not exist in server-rendered HTML.