Horizontal Blog Card
An image and copy split side by side that stacks to image-over-text on small screens.
2 frameworksBeginner
A cover image over a category, title, excerpt and author row - the default post card for a grid.
<!-- A grid card repeats, so its heading is an <h3>. The whole card is one
link; nested links inside a card link are invalid and untabbable. -->
<a
href="#"
class="group flex w-full max-w-sm flex-col overflow-hidden rounded-xl border border-gray-200 bg-white transition-shadow hover:shadow-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 focus-visible:ring-offset-2 dark:border-gray-800 dark:bg-gray-900 dark:focus-visible:ring-blue-400 dark:focus-visible:ring-offset-gray-950"
>
<div class="aspect-[16/10] w-full overflow-hidden bg-gray-100 dark:bg-gray-800">
<img
src="/images/photo-1.jpg"
alt="Aerial view of a coastal city at dusk"
loading="lazy"
class="h-full w-full object-cover transition-transform duration-300 group-hover:scale-105 motion-reduce:transform-none"
/>
</div>
<div class="flex flex-1 flex-col p-5">
<span class="text-xs font-semibold uppercase tracking-wide text-blue-600 dark:text-blue-400">
Engineering
</span>
<h3 class="mt-2 text-lg font-semibold leading-snug text-gray-900 dark:text-gray-100">
Designing a token-first color system that scales
</h3>
<p class="mt-2 line-clamp-2 text-sm leading-relaxed text-gray-600 dark:text-gray-400">
How we moved every surface onto semantic tokens and deleted a thousand one-off hex values along the way.
</p>
<div class="mt-4 flex items-center gap-2 text-xs text-gray-500 dark:text-gray-500">
<span class="font-medium text-gray-700 dark:text-gray-300">Priya Nair</span>
<span aria-hidden="true">·</span>
<time datetime="2026-07-12">Jul 12, 2026</time>
</div>
</div>
</a>| Prop | Type | Default | Description |
|---|---|---|---|
titlerequired | string | - | Heading text for the card. |
excerpt | string | - | Short summary shown under the title. |
category | string | - | Category label shown above the title. |
href | string | '#' | Destination the card links to. |
coverSrc | string | - | Image URL for the cover image. |
imageAlt | string | '' | Alternative text for the image. Empty when the title already names it. |
authorName | string | - | Name of the post's author. |
date | string | - | Machine-readable publication date. |
className | string | - | Additional classes merged onto the root element. |
The whole card is a single link, so nothing inside it is a nested anchor. The heading is an `<h3>` because the card repeats in a grid where a section already owns the `<h2>`. The cover sits in an `aspect-[16/10]` box so the grid stays even before any photo decodes, and `line-clamp-2` keeps a long excerpt from breaking the row height.