Now combine what you learned in one realistic piece: a product card with a corner badge and a caption sitting on top of the image.
<style>
body { font-family: system-ui, sans-serif; background: #f4ece6; margin: 0; padding: 16px; }
.card { position: relative; width: 260px; background: #fff; border-radius: 10px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,.15); }
.photo { height: 150px; background: linear-gradient(135deg, #1a5276, #d94a00); }
.badge { position: absolute; top: 10px; left: 10px; background: #fff; color: #d94a00; font-weight: 700; font-size: 12px; padding: 3px 10px; border-radius: 999px; }
.caption { position: absolute; left: 0; right: 0; top: 106px; padding: 8px 12px; color: #fff; background: rgba(0,0,0,.45); }
.body { padding: 12px; }
</style>
<div class="card">
<div class="photo"></div>
<span class="badge">New</span>
<div class="caption">The Slow Garden</div>
<div class="body">A gentle novel about a neighbourhood allotment. <strong>$14</strong></div>
</div>
What is positioned, and why
.cardisposition: relative. It is the anchor for the badge and caption..badgeisposition: absolutewithtopandleft, so it sits in the top-left corner of the card..captionisabsoluteand stretches across the image withleft: 0; right: 0, placed over its lower part withtop.overflow: hiddenon the card clips the image to the rounded corners.
Try changing things
- Move the badge to the top-right by using
right: 10pxinstead ofleft: 10px. - Change the caption’s
topto0. Where does it go? - Add
position: sticky; top: 0;to a header element in a taller page and scroll.
Exercise: add a close button
Add a small round × button to the top-right corner of the card, 8px from each edge.
Show a possible solution
.close { position: absolute; top: 8px; right: 8px; width: 24px; height: 24px; border-radius: 50%; border: 0; background: #fff; cursor: pointer; }
Add <button class="close" aria-label="Close">×</button> inside the card. The accessible label matters because the button has no text.