All hooks / Events and input

usePointerPosition

198 B minified and brotliedSourceMarkdown✓ Works in all modern browsers

Where the mouse, pen, or finger is over an element, in pixels from its top-left corner, or null while it's outside (and on the server). Attach the returned ref to the element.

With a mouse it follows hovering; with a finger, only while it touches, and it turns null when the finger lifts. Re-renders on every move, so keep the component small, or skip React for pure visuals (see below).

Import

import { usePointerPosition } from '@vincent.ri/react-tils'
// or only this hook
import { usePointerPosition } from '@vincent.ri/react-tils/usePointerPosition'

Usage

const [ref, pointer] = usePointerPosition<HTMLDivElement>()
return (
  <div
    ref={ref}
    className="card"
    style={{ '--x': `${pointer?.x ?? -999}px`, '--y': `${pointer?.y ?? -999}px` } as CSSProperties}
  />
)
// .card { background: radial-gradient(200px at var(--x) var(--y), #fff3, transparent) }

Live demo

Move the mouse over the box, or touch it.

outside

When to use it

A spotlight or glow that follows the cursor on a card, a tooltip or magnifier at the pointer, crosshairs on a chart, or a hover preview that depends on the position (scrubbing a video thumbnail).

When not to

Plain hover styling (CSS :hover); a drag (useDrag); or a page-wide custom cursor, which re-renders the whole app per move: use useEventListener('window', 'pointermove', …) and set a CSS variable or transform on the element directly.

API

function usePointerPosition<T extends Element = HTMLElement>(): [(element: T | null) => void, PointerPosition | null]

Returns [ref, position]: position is { x, y }, or null while the pointer is outside.

Types

export type PointerPosition = {
  /** Pixels from the element's left edge. */
  x: number;
  /** Pixels from the element's top edge. */
  y: number;
};

Browser support

UsesChromeEdgeFirefoxSafariChrome AndroidSafari iOS
Pointer eventsWidely available55+12+59+13+55+13+

First version with support, from MDN's compatibility data (web-features 3.42.0, @mdn/browser-compat-data 8.1.5).

Coming from another library?

Other libraries call this useMouse (react-use), useMousePosition, usePointer.