Examples
Product Grid
Ecommerce-style cards with automatic responsive columns.
Product grids usually need reliable card width more than shortest-column
balancing. Use Masonry with columnWidth and maxColumns.
New
Furniture
Linen lounge chair
Rating 4.8 / 5.0
Low stock
Lighting
Halo task lamp
Rating 4.9 / 5.0
Bundle
Workspace
Ceramic desk set
Rating 4.7 / 5.0
Popular
Travel
Canvas weekend bag
Rating 4.6 / 5.0
Gift pick
Home
Soft wool throw
Rating 4.9 / 5.0
Limited
Decor
Frosted glass vase
Rating 4.8 / 5.0
Example
import { clsx } from 'clsx';
import { Masonry } from 'masonix';
type Product = {
id: string;
name: string;
category: string;
price: string;
rating: string;
badge: string;
gradient: string;
height: number;
};
function ProductCard({ product }: { product: Product }) {
return (
<article
className={clsx(
'overflow-hidden',
'rounded-xl border',
'border-zinc-200 bg-white text-zinc-950 dark:border-zinc-800 dark:bg-zinc-950 dark:text-zinc-50',
)}
>
<div
className="relative"
style={{ height: product.height, background: product.gradient }}
>
<span
className={clsx(
'absolute left-3 top-3',
'px-2 py-1',
'rounded-full',
'text-xs font-medium',
'bg-white/85 text-zinc-900',
)}
>
{product.badge}
</span>
</div>
<div className="p-4">
<div className="flex items-start justify-between gap-3">
<div>
<p className="text-xs text-zinc-500 dark:text-zinc-400">
{product.category}
</p>
<h3 className="mt-1 text-sm font-semibold">{product.name}</h3>
</div>
<span className="shrink-0 text-sm font-semibold">
{product.price}
</span>
</div>
<p className="mt-3 text-xs text-zinc-500 dark:text-zinc-400">
Rating {product.rating} / 5.0
</p>
</div>
</article>
);
}
export function ProductGrid({ products }: { products: Product[] }) {
return (
<Masonry
items={products}
columnWidth={180}
maxColumns={3}
gap={16}
itemKey={(product) => product.id}
render={({ data }) => <ProductCard product={data} />}
/>
);
}When to use
Use this for catalogs, collections, marketplace cards, and browse pages where all items can render up front.
Notes
- Keep card actions inside the render component.
- Use
itemClassNamefor shared wrapper effects. - Use
MasonryBalancedonly if product card heights vary enough to look uneven.