Skip to content

AspectCard

SM · 950B gzip budget

Card that maintains a fixed aspect ratio for media content.

Category
Media & layout
Budget
sm, single-purpose control
External runtime
React / React DOM only
axe fixtureSSR rendersource scanbundle budget

Preview

Live fixture
Preview locale
Image

Content

Try the component here. Locale-aware formatting and direction follow the selected language; example content and labels are not automatically translated. Overlay demos use interactive launchers.

Install

npx shadcn@latest add https://gear5-ui.vercel.app/r/aspect-card.json

Copies the source into your project.

New here? Set up Tailwind and import aliases first →

Source & props

Edit on GitHub ↗

Prop types and inline documentation are included below. This is repository source; the installer rewrites shared imports for your project.

"use client";

import React from "react";

export interface AspectCardProps {
  image: React.ReactNode;
  children: React.ReactNode;
  imageRatio?: number;
  className?: string;
  cardClassName?: string;
  imageClassName?: string;
  contentClassName?: string;
  ariaLabel?: string;
}

export function AspectCard({
  image,
  children,
  imageRatio = 16 / 9,
  className = "",
  cardClassName = "",
  imageClassName = "",
  contentClassName = "",
  ariaLabel,
}: AspectCardProps) {
  return (
    <article
      aria-label={ariaLabel}
      className={`${cardClassName} ${className}`}
      style={{
        border: "1px solid var(--color-border, #e5e7eb)",
        borderRadius: "0.5rem",
        overflow: "hidden",
        background: "var(--color-bg, #fff)",
      }}
    >
      <div
        className={imageClassName}
        style={{
          position: "relative",
          width: "100%",
          paddingBottom: `${(1 / imageRatio) * 100}%`,
          overflow: "hidden",
        }}
      >
        <div
          style={{
            position: "absolute",
            inset: 0,
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
          }}
        >
          {image}
        </div>
      </div>
      <div
        className={contentClassName}
        style={{ padding: "1rem" }}
      >
        {children}
      </div>
    </article>
  );
}

What CI checks

Quality contract
  • Bundled, minified and gzipped against its tier budget
  • Audited by axe in the state previewed above
  • Rendered through react-dom/server with no browser globals
  • Scanned for network calls, dangerous sinks, and unguarded animation