Particles <mv-particles>

Canvas particles that drift and twinkle, pushed away or pulled in by the cursor with an elastic return; an optional constellation mode links neighbors and the pointer.

CategoryBackgrounds
TypeWeb Component (<mv-particles>)
Statusstable
Keywordsparticles, sparkles, constellation, interactive, hero, canvas

When to use

  • A hero should respond to the cursor with drifting particles that scatter or gather
  • A network, AI or blockchain story fits a constellation of points linked to each other and the pointer
  • Ambient sparkle is wanted on a light or dark surface using the theme colors

Avoid when

  • A space theme with depth, star flares or warp speed is the goal → use Starfield instead
  • Low-end mobile at high density with constellation links; a static CSS pattern is far cheaper → use Dot Pattern instead

Install

node scripts/add.mjs particles --out ./src/marvelous

AI agent with the Marvelous UI MCP server: install_components({ slugs: ["particles"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).

Files copied (dependencies included): tokens/tokens.css, core/base.css, core/canvas.js, core/dom.js, core/element.js, core/i18n.js, core/motion.js, core/pointer.js, components/particles/particles.js, components/particles/particles.css.

Usage

Canonical markup, to start from and customize with attributes, data-* and CSS variables:

<div style="display:flex;flex-wrap:wrap;min-width:0;min-height:320px">
  <section style="flex:1.6 1 20rem;min-height:320px;position:relative;display:grid;place-items:center;text-align:center;overflow:hidden;padding:2rem">
    <mv-particles data-fill connect></mv-particles>
    <div style="position:relative">
      <p style="margin:0;font:700 clamp(1.6rem,4vw,2.6rem)/1.1 var(--mv-font-sans);letter-spacing:-.03em">Everything is connected</p>
      <p style="margin:.6rem auto 1.2rem;max-width:30rem;color:var(--mv-fg-muted)">A constellation that parts as your cursor passes through.</p>
      <a class="mv-button" href="#particles">Build my network</a>
    </div>
  </section>
  <section style="flex:1 1 14rem;min-height:240px;position:relative;display:grid;place-items:center;text-align:center;overflow:hidden;box-shadow:-1px 0 0 var(--mv-border);padding:1.5rem">
    <mv-particles data-fill interaction="attract" color="var(--mv-accent)" density="1.4"></mv-particles>
    <div style="position:relative">
      <strong style="display:block;font-size:1.1rem">Attracted sparks</strong>
      <span style="font-size:.85rem;color:var(--mv-fg-muted)">interaction="attract"</span>
    </div>
  </section>
</div>

API

Attributes

NameTypeDefaultDescription
countnumberFixed count (otherwise proportional to the area, max 500 / 220 with connect).
densitynumber1Multiplies the automatic count.
interactionrepel | attract | nonerepelReaction to the cursor.
radiusnumber120Cursor influence radius (px).
connectbooleanLinks nearby particles (constellation), and the cursor.
link-distancenumber120Max link distance (px).
colorCSS colorvar(--mv-particles-color)Particle color (tokens accepted, follows the theme).
link-colorCSS colorvar(--mv-particles-link)Link color.
sizenumber2Max particle radius (px).
speednumber1Drift speed.
data-fillbooleanFills the positioned parent; the cursor is then tracked on the parent.

CSS variables

NameDefaultDescription
--mv-particles-colorfg 75%Default particle color.
--mv-particles-linkaccent 70%Default link color.

Accessibility

Decorative: the canvas is aria-hidden and never takes pointer events, while content placed inside the element stays readable by assistive tech; with data-fill the whole element ignores the pointer and the parent section drives the interaction. The loop pauses off screen and in hidden tabs; every listener and observer is released on disconnect. Reduced motion (OS or [data-motion="reduce"]): a still image with no cursor reaction. Forced colors and print hide the canvas.