Highlighter

Free · MIT

Draws a marker highlight, hand-drawn underline, circle, box or strike-through behind a phrase when it scrolls into view, in six colors.

MarkdownOpen in v0
Open in v0

Installation

$ npx shadcn@latest add https://goodui.dev/r/highlighter.json

The file lands in components/goodui/highlighter.tsx and is yours to edit. With the @goodui registry added, npx shadcn@latest add @goodui/highlighter works too.

Usage

import { Highlighter } from "@/components/goodui/highlighter"

export function Benefit() {
  return (
    <p className="max-w-xl text-lg text-muted-foreground">
      Automatic SMS reminders{" "}
      <Highlighter className="text-foreground">cut no-shows by 40%</Highlighter>
      {" "}for salons in their first month, and clients can{" "}
      <Highlighter action="underline" color="sky" delay={0.4}>reschedule in one tap</Highlighter>.
    </p>
  )
}

When to use

Use it for
  • Drawing attention to the key phrase of a landing-page paragraph as it scrolls into view ("cut no-shows by 40%").
  • Pricing and comparison copy: circle the saving, strike the old price.
  • Onboarding and docs, to point at the one thing to notice, controlled by your own state.
Reach for something else
  • A highlighted word inside a heading: heading with treatment="highlight" or "underline-squiggle" and *marked* words is simpler.
  • Search-result matches in lists and tables: use a plain <mark>; animation there is distracting.
  • Coloring a word without a mark: use gradient-text or text with a tone.
If you needUse
Marker behind a phrase (wraps across lines)action="highlight" (default)
Hand-drawn underlineaction="underline"
Circle a number or priceaction="circle"
Box a termaction="box"
Old priceaction="strike" color="rose"
Follow the theme colorcolor="primary"
Draw from your own stateshow={step === 2}

Examples

Old and new price

<p className="text-2xl font-semibold">
  <Highlighter action="strike" color="rose">$49</Highlighter>{" "}
  <Highlighter action="circle" color="emerald" delay={0.5} padding={8}>$29</Highlighter>
  <span className="text-base text-muted-foreground"> / month</span>
</p>

Controlled by an onboarding step

<Highlighter action="box" color="primary" show={step === 2}>Connect your calendar</Highlighter>

API reference

PropTypeDefault
action
Marker highlight (wraps across lines), or a hand-drawn underline, circle, box or strike-through.
"highlight" | "underline" | "circle" | "box" | "strike""highlight"
color
Marker and stroke color, tuned for light and dark; "primary" follows the theme.
"amber" | "emerald" | "sky" | "rose" | "violet" | "primary""amber"
show
Controlled: true draws, false erases. Leave undefined to draw when scrolled into view.
boolean—
once
With automatic triggering: draw only the first time it enters the viewport.
booleantrue
delay
Seconds before drawing starts.
number0
duration
Seconds the stroke takes.
number0.8
strokeWidth
Stroke width in px for underline, circle, box and strike (not used by highlight).
number2
padding
Extra space in px between the text and a circle or box.
number6

Also accepts every <span> attribute.

Accessibility

  • The text stays plain text in a <span>; the drawn shapes are an aria-hidden SVG with pointer-events: none.
  • The marker is decoration: if the emphasis carries meaning, also use <strong> or <em> inside it.
  • Each color has separate light and dark values; the dark-mode marker is a translucent tint (about 30% opacity) that light text shows through.

Motion

  • highlight: the marker grows from left to right by animating background-size over `duration` s (0.8) on cubic-bezier(0.65, 0, 0.35, 1), after `delay` s. It wraps across lines.
  • underline, circle, box, strike: an SVG path built from the measured text size draws itself (pathLength) with the same duration, delay and easing.
  • Without show, it draws when 80% of the phrase is visible, once by default (once={false} erases and redraws on each visit).
  • Reduced motion: marks appear at once, without drawing.

Notes for AI

Coding agents read these rules through MCP and llms.txt, or paste this page with Copy page.

  • Wrap only the phrase to mark; children are the text.
  • Durations and delay are seconds. strokeWidth and padding (px) only affect the SVG actions, not highlight.
  • Colors are amber, emerald, sky, rose, violet and primary; there is no custom color prop.
  • underline, circle, box and strike turn the span into an inline-block, so keep those phrases short enough to stay on one line; use highlight for phrases that wrap.
  • Stagger several highlights with delay rather than separate timers.

FAQ

Does the marker work across line breaks?

Yes, action="highlight" is a CSS background on the inline text, so it follows every line. The SVG actions make the phrase an inline-block, so they belong on short phrases.

Does it redraw when the text resizes?

Yes. The SVG actions re-measure with a ResizeObserver, so shapes keep fitting after font loads and layout changes.

Related