Mischief

80 / Scenes

Cursor Trail

A fading mark behind the pointer, drawn only inside its own box and only while the pointer is in it.

Move the pointer through here

Installation

Copy the source into your project, or keep it behind a package.

npx shadcn@latest add Tinkerers-Labs/mischief-ui/cursor-trail
import { CursorTrail } from "mischief-ui/cursor-trail"

Or paste it in yourself. The source imports the shared cn helper from @/lib/utils, so point that at your own copy.

registry/default/cursor-trail/cursor-trail.tsx
"use client" import * as React from "react"import {  RenderSurface,  useThemeColors,  type SurfaceColor,} from "@/registry/default/render-surface/render-surface"import { cn } from "@/lib/utils" export type CursorTrailProps = React.HTMLAttributes<HTMLDivElement> & {  color?: string  /** Widest the trail gets, in pixels. */  size?: number

Usage

export function Panel() {
  return (
    <CursorTrail className="rounded-xl border p-12">
      <p>Move the pointer through here</p>
    </CursorTrail>
  )
}

Inside its box, not on the page

A trail attached to the whole window follows people into forms, over text they are trying to read, and across every other part of the interface. This one covers the element you put it on and nothing else, which makes it something you can use in one place without it becoming the personality of the entire site.

It also stops. The loop runs while the pointer is over the box and for as long afterwards as it takes the last mark to fade, then pauses. A page holding one of these is running no animation until somebody points at it.

Under reduced motion

No marks are made at all. A trail is nothing but movement, and a frozen one is a row of dots that means nothing.

API

colorstringA theme property or CSS colour. Defaults to "--primary".
sizenumberWidest the trail gets, in pixels. Defaults to 26.
lifenumberSeconds a mark takes to fade. Defaults to 0.7.

Accessibility

The canvas is decoration, hidden from assistive technology, and transparent to the pointer, so anything underneath stays clickable. Nothing is drawn under reduced motion. Nothing here carries meaning, so there is nothing to miss.