Encodera

Thanks for reading!

Donate to the site — we work hard for you.

How to make a card

Short answer

An image, text and a button in a block with rounding and a shadow:

<style>
  .card { width: 220px; border-radius: 12px; overflow: hidden; background: white; box-shadow: 0 2px 10px rgb(0 0 0 / 15%); }
  .card img { display: block; width: 100%; aspect-ratio: 16 / 10; object-fit: cover; }
  .card .body { padding: 12px; }
  .card h3 { margin: 0 0 6px; font-size: 18px; }
  .card p { margin: 0 0 12px; color: dimgray; font-size: 14px; }
</style>
 
<article class="card">
  <img src="/media/photo-400x250.jpg" alt="Lake in the mountains">
  <div class="body"><h3>Alpine Lakes Tour</h3><p>Five days of hiking and fresh air.</p><button>From $299</button></div>
</article>

overflow: hidden clips the image corners to the card's rounding, and object-fit: cover fits photos of any proportions to the same height.

To make the whole card clickable, stretch the link's pseudo-element over all of it:

<style>
  .c { position: relative; width: 220px; padding: 12px; border: 1px solid gainsboro; border-radius: 12px; }
  .c a::after { content: ""; position: absolute; inset: 0; }
  .c:hover { border-color: royalblue; }
</style>
 
<div class="c"><h3 style="margin: 0;"><a href="https://example.com">Read the guide</a></h3><p style="margin: 6px 0 0;">Ten tips for beginners.</p></div>

This keeps only the heading as the link, so a screen reader reads short clear text instead of the whole card.

Common mistake

People wrap the whole card, button included, in an a. A button inside a link is invalid markup, and clicking it behaves unpredictably. Use the stretched ::after trick.

Functions used in this recipe

  • <article> — A self-contained piece that makes sense on its own: an article, a post, a review, a product card.
  • border-radius — Rounds the corners of an element.
  • box-shadow — A shadow around the element's box.
  • object-fit — How the picture of an `<img>` or `<video>` fits into the element's box.

Thanks for reading!

Donate to the site — we work hard for you.