Backgrounds

Dot Grid

A dotted grid background with an optional radial fade mask toward the edges.

Install

npx shadcn@latest add @paragon/dot-grid

dot-grid.tsx

import * as React from "react";
import { cn } from "@/lib/utils";

export interface DotGridProps extends React.ComponentProps<"div"> {
  /** Spacing between dot centers in px. */
  gap?: number;
  /** Dot radius in px. */
  dotSize?: number;
  /** Fade the grid toward the edges with a radial mask. */
  fade?: boolean;
}

/**
 * A dotted grid background with an optional radial fade toward the edges.
 *
 * Pure CSS: a repeating radial-gradient paints the dots and a radial
 * mask-image handles the fade — zero JS, zero animation. Dots inherit
 * `currentColor`, so retint via a text color class (e.g. `text-primary/25`);
 * the default tracks `--foreground` and stays legible in both themes.
 * Absolutely positioned — parent needs position: relative (and usually
 * overflow-hidden).
 */
export function DotGrid({
  gap = 16,
  dotSize = 1,
  fade = true,
  className,
  style,
  ...props
}: DotGridProps) {
  return (
    <div
      aria-hidden
      data-slot="dot-grid"
      className={cn(
        "pointer-events-none absolute inset-0 text-foreground/20",
        className,
      )}
      style={{
        backgroundImage: `radial-gradient(currentColor ${dotSize}px, transparent ${dotSize}px)`,
        backgroundSize: `${gap}px ${gap}px`,
        backgroundPosition: "50% 50%",
        ...(fade && {
          maskImage:
            "radial-gradient(ellipse at 50% 50%, black 45%, transparent 90%)",
          WebkitMaskImage:
            "radial-gradient(ellipse at 50% 50%, black 45%, transparent 90%)",
        }),
        ...style,
      }}
      {...props}
    />
  );
}