Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Backgrounds

Free

Grid Pattern for React

A static grid of thin lines behind your content, like graph paper, with optional filled cells and dashed lines. For React with Base UI, when a hero, a card header or an editor needs quiet structure behind it.

Framework

Grid Pattern draws a grid of thin lines behind whatever you put inside it, like graph paper. One SVG pattern fills the box at any size and stays sharp at any zoom. You can fill cells with squares, dash the lines with strokeDasharray, and fade the grid toward the edges with fade. Nothing moves and nothing runs in the browser: it renders to plain markup on the server.

Use it when a page needs structure without motion: a hero, a card header, a canvas or editor backdrop. For dots instead of lines, use Dot Pattern; for cells that light up under the pointer, Interactive Grid Pattern; for a grid in perspective scrolling toward a horizon, Retro Grid.

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
Use email insteadNo credit card

Usage

import { GridPattern } from "@/components/ui/grid-pattern";

Grid Pattern is a container: give it a size and put your content inside. The grid sits behind the content, and the box clips it.

<GridPattern className="flex min-h-[420px] items-center justify-center" fade="radial">
  <h1 className="text-5xl font-semibold">Plan it on paper first</h1>
</GridPattern>

For a backdrop behind the whole page, leave it empty and fix it under everything else:

<GridPattern className="fixed inset-0 -z-10" fade="radial" />

Demos

Squares

squares fills cells by [column, row], counted from the top-left cell, here in a card-sized box that fades out toward its bottom edge with fade="bottom". squareColor sets their colour.

Preview width

Dashed lines

strokeDasharray dashes the lines in SVG's dash syntax, here "4 2" on a tighter grid (cellSize={24}), tinted with lineColor.

Preview width

Accessibility

The grid is decoration: it's hidden from screen readers and lets every click through to the content. It never moves, so there's nothing to reduce and nothing that flashes. The lines use your theme's border colour, faint enough that text on top stays readable; keep that text in the foreground colour. The fade options are masks, so the grid fades into whatever is behind it, in light and dark.

FAQ

How do I make the grid denser or sparser?

Set cellSize, the side of one cell in pixels: 16 to 24 for a dense grid, 64 and up for a sparse one. The default is 40.

Can I highlight specific cells?

Pass squares={[[0, 0], [2, 1]]}: each pair is [column, row], counted from the top-left cell. They fill exactly between the lines, in squareColor (your theme's muted colour by default).

How do I get dashed or dotted lines?

Use strokeDasharray in SVG's dash syntax: "4 4" for dashes, "1 3" for dots. The dashes start over in every cell, so pick a dash and gap that add up to a divisor of cellSize (8 on the default 40) for an even rhythm across cells.

How do I fade the edges?

fade="radial" fades toward every edge from the centre, and "top" or "bottom" toward that edge. It's a mask on the grid, so it fades into any background, in light and dark.

How do I change the colours?

lineColor and squareColor take any CSS colour, such as color-mix(in oklab, var(--primary) 30%, transparent). By default the lines use your theme's --border and the squares its --muted, so they follow light and dark. You can also set --grid-pattern-line and --grid-pattern-square from your own CSS.

Does it run any JavaScript?

No. It renders an SVG on the server and ships no script. Each grid gets its own pattern id, so several on one page never clash.

Why an SVG pattern and not CSS gradients?

The browser draws the pattern tile once and repeats it, it stays sharp at any zoom, and it takes any dash pattern and the filled cells in the same element. Two gradients make the same solid grid but need extra layers for dashes.

API Reference

GridPattern

<div> data-slot="grid-pattern"

PropType
cellSize?number

The side of one square cell, in pixels. @default 40.

Default
40
fade?"none" | "radial" | "top" | "bottom"

Where the grid fades out: toward every edge from the centre (radial), toward the top, or toward the bottom. It's a mask, so the grid fades into whatever is behind it.

Type
"none" | "radial" | "top" | "bottom"
Default
"none"
lineColor?string

The lines' colour, any CSS colour. @default "var(--border)".

squareColor?string

The filled cells' colour, any CSS colour. @default "var(--muted)".

squares?[number, number][]

Cells to fill, each [column, row] counted from the top-left cell, [0, 0].

strokeDasharray?string

The lines' dashes, in SVG's dash syntax: "4 4" for dashes, "1 3" for dots. Solid when left out.

render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

CSS variableType
--grid-pattern-linestring

The lines' colour (var(--border)).

--grid-pattern-squarestring

The filled cells' colour (var(--muted)).

All 100 backgrounds