30 Tailwind CSS Grid Layouts

30 Pure TailwindPublished

30 Tailwind CSS grid layouts for editorial features, docs pages with sticky tables of contents, photo galleries, bento product sections, analytics dashboards, pricing tables, and kanban boards — spanning holy-grail and 12-column page systems, masonry and mosaic photo walls, subgrid-aligned cards, container-query teasers, scroll-snap carousels, and dense auto-packed asset libraries. Scoped under .tgx-NN for no-collision pasting, prefers-reduced-motion guarded, framework-agnostic.

Related15 Tailwind Card Grid Layouts15 CSS Card Grid Layouts30 CSS Grid Layouts17 CSS Dashboard Layouts

Premium upgradePartner: Untitled UI

Affiliate link

Building a whole Tailwind app, not just this component?

You just browsed 30 Tailwind grid layouts v2. Untitled UI Pro unlocks 5,000+ components and sections and 250+ page examples for React, styled with Tailwind CSS v4. One licence is a one-time $349 with lifetime updates; teams start at $999.

Get Untitled UI Pro

Untitled UI React. We may earn a commission, at no extra cost to you.

Newsletter

Enjoying these demos? Get new ones by email.

A short email when a new collection ships. Unsubscribe any time.

at

Almost there: check your inbox to confirm.Manage

Newsletter

Enjoying these demos? Get new ones by email.

A short email when a new collection ships. Unsubscribe any time.

at

Almost there: check your inbox to confirm.Manage

Newsletter

Enjoying these demos? Get new ones by email.

A short email when a new collection ships. Unsubscribe any time.

at

Almost there: check your inbox to confirm.Manage

FAQ

Frequently asked questions

How do I build a responsive card grid in Tailwind that reflows on its own, without writing a single media query?
Reach for an intrinsic track definition instead of breakpoints. The integrations directory (demo 11) and the photo gallery (demo 03) both use one arbitrary utility: grid-cols-[repeat(auto-fill,minmax(220px,1fr))]. The minmax(220px,1fr) says every column is at least 220px, and shares leftover space equally; auto-fill asks the grid to lay down as many of those tracks as the container can hold. At 1400px you get six columns, at 700px three, at 360px one — and the card content never has to know. Add gap-4 for the gutters. The one thing to get right is the min value: pick the narrowest a card can be before its text looks cramped, not the width you want on desktop. Because the tracks are computed from the container, this keeps working inside a sidebar, a modal or a dashboard cell with zero extra classes.
What is the actual difference between auto-fill and auto-fit, and why does my grid stretch its cards into giant columns?
Both create as many minmax() tracks as fit, but they treat the empty tail differently. With auto-fill the grid keeps the extra empty tracks at their minimum width, so a row of three cards stays card-sized with blank space on the right. With auto-fit those empty tracks collapse to zero and the 1fr flexible maximum lets the surviving cards absorb all the leftover width — which is exactly your giant-column bug. Two items in a wide container each balloon to half the row. The fix is to decide intent: if items should grow to fill the row, keep auto-fit; if they should stay a fixed size and leave a gap, switch to auto-fill. The gallery grids here use auto-fill so a half-empty last row reads as a grid, not two stretched banners. Nothing else in the class list changes.
How do the pricing and template cards keep their buttons on one baseline when every card has different amounts of text?
They use subgrid. Demos 15 and 17 make each card a grid item that also becomes a grid, inheriting the parent's row lines with grid-rows-subgrid and spanning the rows it needs (row-span-4 on the card). Now the title row, the description row and the button row are shared tracks across all cards, not private to each. A card with a two-line title and a card with a four-line description still place their button in the same shared final row, so every CTA lands on one baseline regardless of content length. Without subgrid you would be reaching for equal-height hacks or a fixed min-height that breaks the moment copy grows. The gotcha: the card must span the exact number of rows the parent defines, and the parent needs those rows declared (grid-rows-[auto_auto_1fr_auto]) so the 1fr soaks up the slack and pins the button down.
For the masonry and dense-packed grids, why do my items read in a jumbled order for keyboard and screen-reader users?
Because grid-auto-flow-dense (demo 24) and span-driven mosaics (demo 23) reorder the visual placement to backfill holes, but the DOM order — which is what focus and a screen reader follow — never moves. A tile that visually sits fourth may still be tenth in source, so Tab order and reading order diverge from what the eye sees. This is a genuine WCAG concern (meaningful sequence), not cosmetic. The rule the collection follows: only use dense packing when the order is not meaningful — a decorative photo wall or an asset library where any order is fine. For anything ordered (steps, a ranked list, a table), keep the natural flow and accept the occasional gap. Never use CSS order or dense packing to fake a sequence, and don't rely on it to move a call-to-action earlier — put it earlier in the markup instead.
How does the article teaser switch between a stacked and a side-by-side layout based on where I drop it, not the viewport width?
That is a container query, and it is the whole point of demo 20. The teaser's wrapper is marked @container, and the card's internal grid keys off the card's own width with container variants like @md:grid-cols-[200px_1fr]. Dropped into a wide main column the card is wider than the threshold, so it goes horizontal — image left, text right. Dropped into a narrow sidebar the same component falls back to a single stacked column, with no change to its markup or props. Media queries can't do this: they only know the browser width, so the identical card would render the same in both slots. The setup cost is two things — a parent that establishes containment (@container) and children that use the @-prefixed variants rather than sm:/md:. Reuse the teaser anywhere and it adapts to its actual space.
How is the periodic table placed so precisely — can I really put an element at an exact row and column with Tailwind?
Yes, and demo 30 is the extreme case: a real 18-column table where hydrogen sits at column 1 and helium jumps to column 18 on the same row. The parent is grid-cols-18, and each cell uses explicit line placement — col-start-1 for hydrogen, col-start-18 for helium — so the gap between them is real empty grid, not a spacer element. The status map (demo 28) does the same trick with col-start/row-start to drop coordinate pins onto a graticule. The mechanism is that CSS grid lets any item name the line it begins and ends on, independent of source order, so you place items by coordinate rather than by flow. The one caution: coordinate placement is precise but not fluid — a fixed 18-column grid needs a horizontal scroll container on narrow screens, which is why the table wraps in an overflow region rather than trying to reflow chemistry.
How do the docs and help-center layouts keep the sidebar and table-of-contents fixed while the main column scrolls?
Two different tools for two different needs. The help center (demo 07) uses genuinely fixed rails — a 170px category column that never moves — by giving the grid fixed side tracks (grid-cols-[170px_1fr_220px]) and letting only the centre track's content scroll. The docs page (demo 02) instead uses sticky top-0 (or a small offset) on the on-this-page rail, so it scrolls with the article until it reaches the top of the viewport, then pins. Sticky is usually what you want for a TOC because it releases at the end of the content instead of overlapping the footer. The classic bug: sticky silently does nothing if any ancestor has overflow-hidden or overflow-auto, because that ancestor becomes the scroll container and the element sticks to it instead of the page. Keep the sticky element's scroll ancestor clean and give it a defined top.
When should I not use CSS grid for these layouts — is there a case where flexbox or plain block is the better call?
Grid earns its keep when you control both axes at once: dashboards (demo 16), the 12-column marketing system (demo 08), coordinate placement (demos 28, 30) and any subgrid alignment. Reach for something simpler when you don't. A single row or column that just needs items to wrap and space out — a logo wall's fallback, a tag list, a button group — is cleaner as flexbox, because grid's track machinery is overhead you never use. Long-form prose (demo 01) is really one measured column; a max-width block beats a one-column grid. And a truly staggered height masonry, where items pack vertically by shortest column, still isn't grid's strength unless you accept the reading-order tradeoff above — a dedicated masonry approach or columns may serve better. The test: if you're only positioning along one axis, or fighting the grid to reorder for accessibility, you probably want flex or block instead.

Related collections

15 CSS Aspect Ratio Demos preview

15 CSS Aspect Ratio Demos

15 hand-coded CSS aspect-ratio demos for video embeds, product galleries, IAB ad slots, native dialogs, and CLS-safe placeholders: 16:9 iframe YouTube embed with click-to-load facade + up-next rail, 21:9 full-screen hero video with min-height/max-height:100svh guardrails + Ken Burns drift, 1:1 Instagram-style square grid with 2×2 feature tile, 4:3 magazine card image cover, 9:16 vertical stories rail (TikTok/Reels/Shorts pattern) with scroll-snap + segment bars, 4:5 apparel product image gallery with radio-driven state + 1:1 thumbnails, 1:1 zoom thumbnail carousel with pointer-tracked --zx/--zy magnifier, prevent-layout-shift placeholder with live PerformanceObserver CLS meter (before/after side-by-side lab), dynamic content fallback with three policies (bend/strict/auto) via :has() toggle, IAB ad banner slots (728×90 leaderboard, 300×250 medium rectangle, 300×600 half-page, 320×50 mobile) with skeletons + container-query mobile swap, responsive modal dialog sized min(92vw, 88svh×16/9, 1080px) with @starting-style animation, responsive OpenStreetMap iframe wrapper with 16:9 → 1:1 container-query narrow swap, media query orientation live HUD + resize:both container-ratio playground, object-fit logo cloud with contain/cover/fill switcher via :has(), and side-by-side padding-top hack (height:0 + padding-top:56.25%) → modern aspect-ratio migration comparison with live ratio picker. 11 truly Pure CSS + 4 with a tiny optional vanilla JS snippet (facade swap, pointer magnifier, CLS meter, native dialog). Every demo is scoped under a unique .car-NN prefix so it drops into any project without CSS collisions, ships prefers-reduced-motion guards, and is framework-agnostic (works as-is in React, Vue, Svelte, Astro, Next.js, Remix, or plain HTML).

6 CSS Bento Grid Layouts preview

6 CSS Bento Grid Layouts

6 production CSS bento grid layouts with 12 hand-coded designs — Apple-style product showcase, SaaS feature value-prop matrix, analytics dashboard overview, creative portfolio, e-commerce category hub, and link-in-bio social hub. Each topic ships 2 sub-variants side-by-side so visitors see both a keynote aesthetic and a paper-doc variant at once. Container queries, CSS Grid, zero dependencies, copy-paste ready.

20 CSS Blog Layouts preview

20 CSS Blog Layouts

20 hand-coded CSS blog and editorial layouts for magazine homepages, news sites, personal archives, newsletter back-issues, recipe and podcast blogs, developer tutorials, and long-form journalism. Covers a magazine homepage with hero plus editor-picks rail, a news homepage with breaking-news ticker, blog archives with sticky year separators, Substack-style issue-numbered archives, recipe card grids with prep-time badges, podcast episode lists with waveforms, long-form articles with scroll-driven reading progress, drop caps and floated pull quotes via first-letter, Medium-style 65ch centred reader layouts, dev tutorials with a sticky code panel beside prose, interview transcripts with alternating speakers, case-study pages with stat counters, video blogs with an episode rail, full-bleed photo essays, news articles with sticky related-stories sidebars, documentation pages with prev/next chapter nav, a standalone blog post card, a scroll-snap category filter bar, an inline newsletter callout that breaks out of the prose column, and a horizontal featured-post rail. 12 are pure CSS with zero JavaScript. Every layout is scoped under a .bl-NN prefix for no-collision pasting, guards prefers-reduced-motion, and ports unchanged to React, Vue, Svelte, Astro, Next.js and Tailwind.

Search CodeFronts

Loading…