You Might Also Like
Blog Post Card Grid — Free HTML CSS Responsive Blog Preview Snippet
Blog Post Card Grid · Cards · Plain HTML, CSS & JS · Live preview
What's included
Features
About this UI Snippet
Blog Post Card Grid — HTML & CSS Blog Preview Cards

A blog listing page or "latest posts" section needs cards that scan quickly: a visual anchor, a category, a headline, a short excerpt, and who wrote it and when. Getting the density and hierarchy of that combination right is most of what makes a blog grid feel professional rather than cluttered.
This snippet builds that card pattern in plain HTML and CSS, using gradient placeholders instead of real cover images so it works immediately with zero image assets.
How the cover placeholders work
Each .cover div is just a fixed-height block with an inline background: linear-gradient(...) — no image request, no loading state to manage, no broken-image fallback needed. Because each gradient is set independently per card, the grid still reads as visually varied even without photography. Swapping in a real image later means replacing the div with an <img> (or setting background-image to a photo URL) sized to the same fixed height with object-fit: cover or background-size: cover.
How the layout hierarchy works
Inside .post-body, the order is deliberate: the category .tag comes first as a small pill (helping readers instantly filter by topic while scanning), then the headline in a slightly larger, high-contrast <h3>, then a muted excerpt paragraph, and finally the .post-meta row combining a mini avatar, author name, a middle-dot separator, and the date — all in a smaller, lower-contrast type size since it's the least important information for someone deciding whether to click.
How the responsive grid works
Like other card grids in this pattern, grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)) handles every screen width automatically — three columns on desktop, one or two on tablet, a single column on mobile — with zero media queries.
The hover affordance
Each .post-card has cursor: pointer and lifts with a shadow on :hover, signaling the entire card is clickable even before you wrap it in an anchor tag — a common real-world pattern is making the whole card a link while keeping the semantic <article> element for each post.
Build with AI
Build, Understand, Optimize, and Extend It With AI
Give this snippet's HTML and CSS to an AI coding assistant like Claude and ask it to explain the reasoning behind the specific visual hierarchy used here — why the category tag sits above the headline, why the excerpt is deliberately muted compared to the title, and why the author/date meta row uses the smallest, lowest-contrast text of all — so you can apply the same hierarchy principles consistently to other content card patterns on your site. It's also a great snippet to extend with the assistant's help: ask it to generate the template function that maps your specific static site generator's frontmatter (Jekyll, Hugo, Astro, Next.js MDX) or your headless CMS's post schema onto this exact card markup, so the grid can be rendered dynamically from your real content.
Prompt to recreate it
Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:
Build a responsive grid of blog post preview cards in plain HTML and CSS — no JavaScript required for the static version, no external image service.
Requirements:
- A CSS grid container using repeat(auto-fit, minmax(<min-width>, 1fr)) for grid-template-columns so the layout reflows from multiple columns on desktop down to a single column on mobile with no media queries.
- Each card is a semantic <article> element containing, in this order: a fixed-height cover placeholder using an inline CSS gradient (no image file), a small category tag styled as a pill, a headline, a short excerpt paragraph, and a meta row combining a small circular initials avatar, the author's name, a separator, and a relative or short-form date.
- Deliberately differentiate the visual weight of each piece of text: the headline should have the highest contrast and largest size among the body text, the excerpt should be visibly more muted, and the meta row should be the smallest and most muted text on the card.
- Each card's cover gradient and avatar color must be set independently so the grid shows visual variety across multiple posts.
- Add a hover state that lifts the card and deepens its shadow, and set cursor: pointer, signaling the whole card is clickable even before it is wrapped in a link.
- The markup for a single card must be simple enough to trivially generate from a CMS collection, static site generator's frontmatter, or API response via a small template function.Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.
Step by step
How to Use
- 1Load the snippetClick "Blog Post Card Grid" in the sidebar Library tab to see three post cards with gradient covers laid out in a grid.
- 2Resize the previewSwitch device previews to see the grid reflow from three columns down to one with no additional CSS.
- 3Add a postIn the HTML panel, copy an existing <article class="post-card"> block and update its gradient, tag, title, excerpt, and meta row.
- 4Swap in real cover imagesReplace a .cover div's inline gradient with a background-image pointing at a real photo, or convert it to an <img> tag with object-fit: cover.
- 5Make the whole card clickableWrap each .post-card in an anchor tag (or add an absolutely-positioned "stretched link" overlay) pointing at the full post URL.
- 6Export in your formatClick "HTML" for a standalone file, "JSX" for React, or "Tailwind" for React + Tailwind CSS.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
Gradients require no image file, never show a broken-image icon while content is being built out, and load instantly with zero network requests — making them a practical placeholder for prototypes or posts that don't have final photography yet.
Replace the .cover div's inline background gradient with background-image: url(...) and background-size: cover, or convert it to an <img> tag with object-fit: cover sized to fill the same fixed height.
The container uses grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)), which automatically fits as many 240px-or-wider columns as the available width allows and stretches them evenly, producing fewer columns on narrower viewports with no explicit breakpoints.
Wrap the whole .post-card markup in an anchor tag, or use the "stretched link" technique — position an absolutely-positioned, fully-covering anchor with an empty accessible label inside the card while keeping the visible heading text as a separate, styled element.
Yes. Add another span inside .post-meta after the date, separated by another .dot span, following the same pattern used for the author name and date.
Not by default — it's a styled span. Convert the .tag element to an anchor pointing at a category archive URL if you want readers to filter the blog by that topic directly from the card.
Adjust the minmax(240px, 1fr) minimum width in the CSS panel — increasing it produces fewer, wider columns per row, and decreasing it allows more columns to fit before wrapping.
Yes. Write a small template function that maps each post's frontmatter or CMS fields (title, excerpt, category, author, date, cover image) onto this exact card markup, then loop over your full posts collection to render the grid.