proNew144 lines · framer-motion
Gallery Masonry
A gallery wall where every tile is drawn, not downloaded. A full-width responsive masonry gallery of generated abstract CSS/SVG artwork tiles, with a hover lift + zoom and a staggered reveal as tiles enter the viewport.
- Use it for
- A visual 'gallery' or 'work' section on a Cards-category page that needs brick-wall variety without sourcing a single external image.
- Themes
- Light + dark
- License
- Commercial use
Live
Showcase
Every piece, framed on its own
A generated gallery wall — nothing pulled from outside, every tile drawn from the same design tokens as the rest of the page.
tsx
"use client";
import * as React from "react";
import { motion, useReducedMotion } from "framer-motion";
import { cn } from "@/lib/utils";
function useReducedMotionSafe() {
const prefersReduced = useReducedMotion();
const [mounted, setMounted] = React.useState(false);
React.useEffect(() => setMounted(true), []);
return mounted ? !!prefersReduced : false;
}
/**
* Full-width "Cards" gallery: a responsive CSS multi-column masonry of generated
* abstract CSS/SVG artwork tiles (no external images), with a hover lift + zoom and
* a staggered reveal as tiles enter the viewport.
*/
export interface GalleryMasonryProps {
eyebrow?: string;
title?: string;The rest is in Pro.
Full source, the rebuild prompt and registry install unlock with Pro or Lifetime.
Get ProHow it behaves
- →Layout is CSS multi-column (columns-1 to columns-4 by breakpoint) with break-inside-avoid tiles, rather than the experimental native CSS grid masonry value, so it renders reliably everywhere.
- →Each tile's artwork is generated purely from CSS (linear/radial/conic gradients sampling design tokens like --signal/--info/--lime/--ok/--warn) plus a low-opacity SVG dot pattern; no raster images are used.
- →Tile heights come from a fixed deterministic array indexed by tile position, so the wall always has the same brick-like height variety for a given tile count.
- →tileCount (9–14) changes how many tiles render; palette swaps which design-token colour pairs feed the gradients; radius and gap are applied directly via inline style/CSS variable to every tile.
- →Hover lifts a tile (-y, scale up slightly) via a framer-motion whileHover transform, not a CSS transform, so it never fights the entrance animation running on the same element.
- →Tiles fade/slide up into place with a per-index stagger using framer-motion whileInView/viewport={{ once: true }}, so a tile already in the viewport on mount settles into its final state immediately rather than waiting for a scroll.
- →prefers-reduced-motion disables both the entrance animation (tiles render in their final position immediately) and the hover lift.
Accessibility
- ✓All generated artwork (gradients, SVG dot pattern) is purely decorative and marked aria-hidden; the gallery carries no interactive or informational content that would need text alternatives.
- ✓Tiles never clip focus outlines and keep a visible border so the grid reads clearly against both the light and dark background tokens.
- ✓Honours prefers-reduced-motion.