Media card
Texto sobre una imagen con un velo oscuro, para que se lea sobre cualquier foto.

A quiet place to work
Studio retreat · 3 days in the valley
Instalación
$ pnpm dlx shadcn@latest add @ssntl/media-cardUso
import { MediaCard, MediaCardContent, MediaCardImage } from "@/components/ui/media-card"
<MediaCard>
<MediaCardImage src="/retiro.webp" alt="" />
<MediaCardContent>
<p className="text-heading">Un lugar tranquilo para trabajar</p>
<p className="text-caption text-muted-foreground">Retiro de estudio · 3 días</p>
</MediaCardContent>
</MediaCard>- El texto sobre imágenes nunca depende de la foto: el contenido va sobre un velo negro que se desvanece hacia arriba.
- El contenido cambia al tema oscuro, así el texto y el texto atenuado quedan claros sobre cualquier imagen.
- Las imágenes decorativas llevan alt=""; describe la foto solo cuando aporta información.
- Deja el texto abajo, donde el velo es más oscuro; nunca sobre una cara o el sujeto.
Código
import * as React from "react"
import { cn } from "@/lib/utils"
// Text over an image only reads when it doesn't depend on the image. The
// content sits on a scrim, a gradient from black that fades out upwards, and
// switches to the dark theme so its text and muted text stay light on any
// picture, bright or busy. A 1px pure black (white in dark) outline at 10%
// gives the image a consistent edge on any surface.
function MediaCard({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="media-card"
className={cn(
"relative isolate grid min-h-80 content-end overflow-hidden rounded-lg bg-muted outline -outline-offset-1 outline-black/10 dark:outline-white/10",
className
)}
{...props}
/>
)
}
function MediaCardImage({
className,
alt = "",
...props
}: React.ComponentProps<"img">) {
return (
// eslint-disable-next-line @next/next/no-img-element
<img
data-slot="media-card-image"
alt={alt}
className={cn("absolute inset-0 -z-10 size-full object-cover", className)}
{...props}
/>
)
}
function MediaCardContent({
className,
...props
}: React.ComponentProps<"div">) {
return (
<div
data-slot="media-card-content"
data-theme="dark"
className={cn(
"grid gap-1 bg-linear-to-t from-black/80 via-black/50 to-transparent p-6 pt-24 text-foreground",
className
)}
{...props}
/>
)
}
export { MediaCard, MediaCardContent, MediaCardImage }