shadcn.io is not affiliated with official shadcn/ui
A topographic map behind your content: thin contour lines circle hills and hollows, every fifth one heavier, like the index contours on a survey map. The map is traced from a seeded noise field when the component renders, so the same seed always draws the same map, on the server and in the browser. The lines draw in once, level by level, then the whole map pans and zooms slowly with one CSS animation; nothing is recomputed or repainted while it moves.
Use it for outdoor, travel, mapping and data pages, where a line drawing fits better than color. For filled, colored altitude bands, use Terrain; for a wireframe surface rising and falling as waves cross it, Wave Grid; for a plain structural backdrop, Grid Pattern.
Installation
Usage
import { Topography } from "@/components/ui/topography";<Topography className="flex min-h-[480px] items-center justify-center">
<h1 className="text-5xl font-semibold">Find your next trail</h1>
</Topography>Topography is a container: give it a size, put your content inside, and the map sits behind it. For a backdrop behind the whole page, render it empty with className="fixed inset-0 -z-10".
Demos
In a card
The map fills any box. Here seed={4} draws a different map, count={8} keeps it sparse, and fade="none" runs the lines to the card's edges.
Color
lineColor takes any CSS color, here the theme's primary at 45%. count={18} gives a denser map, and the --topography-stroke variable, set to 1.25 in the class, a bolder line.
Accessibility
The map is decoration: it's hidden from assistive tech and never takes the pointer. With reduced motion the lines appear complete and the map stays still. Nothing flashes.
The lines are 18% of your text color by default, so copy on top in text-foreground keeps its full contrast; the radial fade also keeps the middle of the box calm. A strong lineColor behind small text deserves a lower opacity.
FAQ
How are the contour lines made?
A small noise function gives a height at each point of a 48 × 30 grid. For each level, the component finds where the height crosses it in every cell (marching squares), joins those crossings into rings and smooths them into one SVG path per level. That happens once, when it renders.
Does the map change on every load?
No. One seed draws one map, the same on the server and in the browser, so the page never flickers on hydration. Pass another seed for another map, and scale={2} for twice as many, smaller hills.
What moves?
First each level's line draws itself in, 80 ms after the level below. Then the whole map pans and zooms slowly, back and forth, with one CSS transform on a wrapper. speed scales that drift, and speed={0} holds the map still.
How do I change the density and the color?
count sets the number of levels, from 3 to 24; every fifth line is heavier. lineColor takes any CSS color. The width is the --topography-stroke variable, in pixels (className="[--topography-stroke:1.5]"), and stays the same in a small card and a full-width hero.
API Reference
Topography
<div> data-slot="topography"
count?number
How many contour levels, from 3 to 24. Every fifth is drawn heavier, like a map's index contours.
- Default
12
fade?"none" | "radial" | "top" | "bottom"
Where the lines fade out: toward every edge, toward the top, toward the bottom, or nowhere.
- Type
"none" | "radial" | "top" | "bottom"- Default
"radial"
lineColor?string
The lines' colour, any CSS colour.
- Default
18% of `var(--foreground)`
scale?number
The size of the hills: 2 draws twice as many, each half as wide. @default 1.
- Default
1
seed?number
Which map to draw. The same seed always draws the same map, on the server and in the browser.
- Default
1
speed?number
How fast the map drifts, as a multiplier: 2 is twice as fast, 0 holds it still.
- Default
1
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.
--topography-colorstring
The lines' colour (18% of --foreground).
--topography-speedstring
How fast the map drifts, a multiplier (1).
--topography-strokestring
The lines' width in pixels (1); index lines are 1.75 times as wide.
Related
- Pro


Terrain Background
GenerativeThe same contours as a lit, shaded relief
- Pro


Blueprint Background
GridsTechnical line drawing
- Pro


Wave Grid Background
WavesA wireframe surface rising and falling
- Pro


Paths Background
WavesAnimated curves
- Pro


Dunes Background
WeatherLayered landscape


Grid Pattern
GridsA quieter structural backdrop