Sora UI

Pixel Background

A canvas-based pixel grid that animates in on hover, with configurable reveal patterns.

Made by Axyl

Hover the panel to reveal a grid of pixels staggered by the selected pattern.

Hover me

Installation

File Structure

pixel-background.tsx
use-prefers-reduced-motion.tsx

Usage

import { PixelBackground } from '@/components/sora-ui/effects/pixel-background';

export default function Hero() {
  return (
    <PixelBackground className="h-[420px] w-full" pattern="center">
      <div className="flex h-full items-center justify-center">
        <h1 className="text-2xl font-medium">Hover me</h1>
      </div>
    </PixelBackground>
  );
}

Custom colors — pass a comma-separated list directly, no CSS setup required:

<PixelBackground className="h-[420px] w-full" colors="#f8fafc,#f1f5f9,#cbd5e1">
  {children}
</PixelBackground>

Optional: theme-aware colors via CSS custom properties (updates live on a .dark class or data-theme toggle, no theme library required) — define the tokens once in your global CSS:

:root {
  --pixel-bg-1: #d4d4d4;
  --pixel-bg-2: #bdbdbd;
  --pixel-bg-3: #a3a3a3;
}
.dark {
  --pixel-bg-1: #2a2a2a;
  --pixel-bg-2: #3b3b3b;
  --pixel-bg-3: #525252;
}
<PixelBackground
  className="h-[420px] w-full"
  colors="var(--pixel-bg-1),var(--pixel-bg-2),var(--pixel-bg-3)"
>
  {children}
</PixelBackground>

Touch / coarse-pointer devices — play once the element scrolls into view instead of requiring hover:

<PixelBackground trigger="inView">{children}</PixelBackground>

Props

PropTypeDefault
children?
ReactNode
-
colors?
string
"#d4d4d4,#bdbdbd,#a3a3a3"
pattern?
AnimationPattern
"center"
gap?
number
5
speed?
number
35
pixelOpacity?
number
1
trigger?
"hover" | "inView"
"hover"
className?
string
-

When to Use

Use PixelBackground behind hero copy, cards, or CTA panels where a subtle, decorative reveal on hover adds texture without competing with the content. Give the root element real height (e.g. a fixed-height section) — the canvas fills its parent.

For content-dense areas where motion could distract from reading, skip it — the effect is purely decorative.

Accessibility

The canvas is aria-hidden — it's decorative and carries no information. Visibility is tracked via IntersectionObserver, so the animation loop is fully cancelled while the element is offscreen, not just paused visually. When prefers-reduced-motion: reduce is set, no animation frames are ever scheduled — the setting is watched live via usePrefersReducedMotion, so toggling it while the page is open takes effect immediately.

Credits

Inspired by React Bits.

Built by Axyl. A motion-first component registry for React.

Last updated: 7/12/2026