UI.MD

Media Card

A linked card led by its image. The image dissolves into the page at its foot and the title rides the fade, with an optional meta line under it. For a post, a project or a release in a feed or a row.

Installation

$
npx shadcn@latest add https://ui.mattdowney.com/r/media-card.json

Usage

import { MediaCard } from "@/components/ui/media-card"

Examples

Default

One card leading with its image. Pass your router's link through render and your framework's image in its fill mode through media.

A row

pinToFoot lines the badges up when titles wrap to different lengths. The shape changes per breakpoint through --media-card-ratio, so the title's pull-up follows it.

API Reference

PropTypeDefaultDescription
media*ReactNode-The image. A plain <img> is stretched to cover; a framework image should use its fill mode.
title*ReactNode-The title, clamped to three lines and pulled up over the faded foot of the image.
descriptionReactNode-A line of copy under the title, 4px below it. Copy goes here, not in meta.
metaReactNode-A line under the title and description, 16px below them. Most often a Badge.
aspect"landscape" | "portrait" | "square" | "wide""landscape"The image's shape: 3:2, 3:4, 1:1 or 16:9. For a shape that changes per breakpoint, set --media-card-ratio (a number, width over height) in className.
fadenumber0.5How much of the image's height dissolves into the page, from 0 to 1. The blur and the title's pull-up scale with it; 0 turns both off.
titleSize"sm" | "md" | "lg""md"Title type: text-lg, text-xl or text-3xl. Use lg for a lead card on its own.
level2 | 3 | 4 | 5 | 63Heading level of the title.
pinToFootbooleanfalsePins the title and meta to the card's foot, so the meta lines up across a row. The card must stretch to the row's height.
outlinebooleantrueThe image's 1px hairline edge, which keeps a dark image's shape on a dark page. Turn it off for large, dark images, where the fade already separates image from page and the edge reads as a frame left open at the foot.
renderReactElement<a />The link element, for a router's link: render={<Link href="/posts/one" />}.
media*ReactNodeThe image. A plain <img> is stretched to cover; a framework image should use its fill mode.
title*ReactNodeThe title, clamped to three lines and pulled up over the faded foot of the image.
descriptionReactNodeA line of copy under the title, 4px below it. Copy goes here, not in meta.
metaReactNodeA line under the title and description, 16px below them. Most often a Badge.
aspect"landscape" | "portrait" | "square" | "wide" = "landscape"The image's shape: 3:2, 3:4, 1:1 or 16:9. For a shape that changes per breakpoint, set --media-card-ratio (a number, width over height) in className.
fadenumber = 0.5How much of the image's height dissolves into the page, from 0 to 1. The blur and the title's pull-up scale with it; 0 turns both off.
titleSize"sm" | "md" | "lg" = "md"Title type: text-lg, text-xl or text-3xl. Use lg for a lead card on its own.
level2 | 3 | 4 | 5 | 6 = 3Heading level of the title.
pinToFootboolean = falsePins the title and meta to the card's foot, so the meta lines up across a row. The card must stretch to the row's height.
outlineboolean = trueThe image's 1px hairline edge, which keeps a dark image's shape on a dark page. Turn it off for large, dark images, where the fade already separates image from page and the edge reads as a frame left open at the foot.
renderReactElement = <a />The link element, for a router's link: render={<Link href="/posts/one" />}.