cssgridgen

shadcn Grid Generator

Draw the layout. Get a shadcn-style component, not a class string.

Open in
1180px

Drag across the grid to draw an area. Arrow keys nudge, Shift + arrows resize.

1220px21fr3
1auto21fr3auto4
header1 / 1 / 2 / 3
main2 / 2 / 3 / 3
footer3 / 1 / 4 / 3
nav2 / 1 / 3 / 2

Named areas. The CSS is a picture of the layout, and only the properties that actually change get repeated inside each media query.

.layout {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr auto;
  gap: 16px;
  grid-template-areas:
    "header"
    "main"
    "footer";
}

.layout > .header { grid-area: header; }
.layout > .main { grid-area: main; }
.layout > .footer { grid-area: footer; }
.layout > .nav { display: none; }

@media (min-width: 768px) {
  .layout {
    grid-template-columns: 220px 1fr;
    grid-template-areas:
      "header header"
      "nav    main"
      "footer footer";
  }

    .layout > .nav { grid-area: nav; }
}

Free tool

Layout is the gap in shadcn/ui

shadcn/ui gives you dialogs, comboboxes and forms. It does not give you a grid, because layout is meant to be Tailwind classes on a div — which is fine until the same class string is copied across six pages. This generates that div as a proper component, following the same conventions as shadcn's own primitives.

How to use it

  1. Draw the layout

    Drag across the grid to create areas. Each one becomes a named part of the component you get back.

  2. Set each breakpoint

    Move the ruler past a breakpoint marker and rearrange. The responsive prefixes are written for you.

  3. Open the shadcn/ui tab

    The output panel has a shadcn/ui tab beside CSS, HTML and Tailwind.

  4. Paste it into your project

    Drop the file in components/, keep the cn() import, and use the compound components as shown in the usage comment.

What the output follows

Three shadcn conventions. cn() merges incoming classes so a caller can override the defaults without a specificity fight. data-slot gives every part a stable styling and testing hook. React.ComponentProps<"div"> keeps native props working, so id, onClick and aria-* pass straight through.

Compound parts, not one blob

A root component plus one named part per area, exported together and shown with a usage comment. The point is that col-start-2 md:row-start-1 lives inside LayoutMain rather than being scattered across every page that renders the layout.

You do not need shadcn installed

cn() is the only dependency, and it is four lines of clsx plus tailwind-merge. Swap it for a template literal and the component works in any React and Tailwind project. If you want the plain version instead, the Tailwind tab gives you the raw markup.

Frequently asked questions

Does shadcn/ui have a grid component?
No — shadcn/ui ships interactive primitives like Dialog and Command, not layout containers. Layout is expected to be plain Tailwind classes on a div. This generator gives you that div as a proper shadcn-style component, so a grid you use in several places has one definition instead of a class string copied around.
What makes a component "shadcn-style"?
Three conventions: cn() to merge incoming classes so callers can override, a data-slot attribute to give the part a styling and testing hook, and React.ComponentProps<"div"> so it still accepts every native prop. The output here follows all three.
Why does the output use compound components?
Because that is how shadcn composes: a root plus named parts, exported together. <Layout><LayoutSidebar /><LayoutMain /></Layout> keeps the grid placement with the component instead of scattering col-start-2 across your pages.
What is cn() and do I need it?
cn() is shadcn's helper combining clsx and tailwind-merge. It merges class strings and resolves Tailwind conflicts so a className passed by the caller wins over the default. It lives in @/lib/utils in any shadcn project; if yours does not have it, npx shadcn@latest init creates it.
Can I use this without shadcn/ui installed?
Yes. The only shadcn-specific dependency is cn(). Replace it with a template literal, or the two-line clsx + tailwind-merge version, and the component works in any React and Tailwind project.
Does it work with shadcn for Vue or Svelte?
The Tailwind classes do — they are framework-agnostic. The generated file is React. Take the class strings from the Tailwind tab and wrap them in your own component for shadcn-vue or shadcn-svelte.