Skip to content

Blog

Blog Grid

Section header and a grid of post cards whose photos zoom on hover, optionally paged with Load more.

Layout and motion from the Nitip template — see it in context

Installation

$ npx shadcn@latest add https://framebrick.co/r/blocks/blog-grid.json

Usage

import { BlogGrid } from "@/components/blog-grid";

// Home: the latest three posts
<BlogGrid posts={posts} action={{ label: "All posts", href: "/blog" }} />

// Archive: every post, a page at a time
<BlogGrid title="Blog" action={undefined} posts={posts} pageSize={{ small: 4, large: 6 }} />

Props

PropTypeDefaultDescription
title / leadstring—Section heading (h2) and the large lead under the divider.
action{ label, href }All postsButton beside the title; pass undefined on an archive.
posts{ title, excerpt, href, image: { src, alt } }[]4 postsCards; each is one link with an h3 title.
pageSize{ small, large }—Paged mode: posts per page below and from 1024px, with a Load more button.
loadMoreLabelstringLoad moreText of the Load more button.
classNamestring—Classes for the <section>.
  • One column below 768px, two from 768px, three from 1024px. Without pageSize it shows three posts (four between 768 and 1023px, so the grid stays even).
  • With pageSize every post is in the HTML and the ones past the page are hidden; Load more adds a page and disappears when everything shows.
  • Photos zoom to 110% while the card is hovered or focused (zoom-card, 400ms, cubic-bezier(0.12, 0.23, 0.5, 1)). Excerpts clamp to two lines from 768px — at every width when paged.

AI prompt

Paste into v0, Lovable, Bolt or Claude to rebuild this block in your own project.

Create a React + Tailwind CSS block called BlogGrid (Next.js).
- <section className="py-(--section-y)">, container mx-auto max-w-(--container) px-(--gutter), column gap-12 / md:gap-16 / lg:gap-20.
- Header: a row with an h2 (font-heading text-h2 semibold tracking-tight) and an optional shadcn-style button, an <hr>, a lead
  (text-h3 font-medium) up to max-w-3xl aligned right.
- Grid: 1 / 2 (768px) / 3 (1024px) columns, gap-8 (md:gap-y-12). Card: one link (group) with a 320:187 photo in a rounded-lg frame
  that zooms to 1.1 while the card is hovered or focused (400ms, cubic-bezier(0.12,0.23,0.5,1)), an h3 (font-heading text-h3
  semibold) and a muted excerpt clamped to two lines from 768px.
- Default: show three posts, a fourth only between 768 and 1023px. Paged ({ small, large }): render every post, hide those past
  page × small below 1024px and page × large from 1024px, and show an outline "Load more" button (aria-controls the grid) that adds
  a page, hidden when nothing is left at that width.
- Only shadcn variables and block tokens; plain <img> with alt text.

Be the first to know

Get new templates and components first

One short email when we release a template or a free component. No spam — unsubscribe anytime.

We use your email only for Framebrick updates. Privacy policy