Skip to content

Card

The Card component provides a versatile container for displaying related content. It uses semantic HTML and ensures proper heading structure and content organization. The component includes built-in support for Astro’s Image component, enabling optimized image loading and better performance out of the box.

  • Featured content sections
  • Product displays
  • Blog post previews
  • Service highlights
  • Team member profiles
  • Any grouped content that benefits from visual containment

This card component maintains proper heading structure and includes keyboard focus styles.

Try hovering and focusing on this card

Cards can be used for various content types and adapt to different layouts.

Click to navigate (opens in same tab)

Learn how to implement the Card component in your project, from basic usage to advanced configurations.

---
import { Card } from 'accessible-astro-components'
---
<Card
img="path/to/image.jpg"
url="/blog/post"
title="Card Title"
>
<p>This is the card content that can include any HTML.</p>
</Card>
---
import { Card } from 'accessible-astro-components'
---
<Card
img="path/to/image.jpg"
url="/blog/post"
title="Card Title"
footer="Card footer content"
>
<span slot="meta">
<Badge text="Science" variant="tip" />
<Badge text="Technology" variant="danger" />
</span>
<p>This is the card content that can include any HTML.</p>
</Card>
---
import { Card } from 'accessible-astro-components'
import localImage from '../assets/local-image.jpg'
---
<!-- Using local image -->
<Card
imageComponent={localImage}
url="/blog/post"
title="Card with Local Image"
>
<p>This card uses Astro's Image component with a local image.</p>
</Card>
<!-- Using remote image with dynamic import -->
<Card
imageComponent={(await import('https://example.com/remote-image.jpg')).default}
width={800}
height={600}
url="/blog/post"
title="Card with Remote Image"
>
<p>This card uses Astro's Image component with a remote image.</p>
</Card>

Configure the Card component using these available props to customize its behavior and appearance.

PropTypeDefaultDescription
urlstring'#'URL for the card’s link wrapper
imgstring'https://fakeimg.pl/640x360'Path to the card’s image
imageComponentImageMetadata | Promise<{ default: ImageMetadata }>undefinedOptional Astro Image component (supports both ImageMetadata and dynamic import)
imageAltstring''Alt text for the image
widthnumber640Width of the image (required for remote images)
heightnumber360Height of the image (required for remote images)
inferSizebooleanfalseWhether to infer the image size (for remote images)
titlestring'Default title'Title text for the card
classstring''Additional CSS classes to apply to the card
tagNamestring'h3'HTML tag name for the title
footerstring''Footer content for the card

Accessibility isn’t an afterthought - it’s built into the core of this component through semantic HTML elements and proper image handling. The Card component is built with accessibility in mind:

  • Uses semantic HTML structure with <article> element
  • Proper heading hierarchy with configurable levels (via tagName prop)
  • Images have appropriate alt text support (via imageAlt prop)
    • Empty alt text (alt="") is appropriate when the image is decorative and the key content is conveyed through title and description
    • Add meaningful alt text for informative images that aren’t described elsewhere in the card
  • Links are properly structured for keyboard navigation with clear focus states
  • Images have appropriate width and height attributes to prevent layout shifts
  • Works with Astro’s Image component for optimal loading and performance
  • Color contrast meets WCAG guidelines

Make the Card component your own with custom styling while maintaining its accessibility features.

/* Option 1: Using :global() in your style block */
<style>
:global(.card) {
border-radius: 0.5rem;
overflow: hidden;
background: light-dark(hsl(204 20% 94%), hsl(215 25% 15%));
color: light-dark(hsl(215 25% 27%), hsl(215 25% 89%));
}
:global(.card:hover) {
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);
}
:global(.card__image) {
aspect-ratio: 16/9;
object-fit: cover;
}
:global(.card__content) {
padding: 1rem;
}
:global(.card__title) {
margin-block-start: 0;
font-size: 1.25rem;
}
</style>
/* Option 2: Using is:global on the style tag */
<style is:global>
.card {
border-radius: 0.5rem;
overflow: hidden;
background: light-dark(hsl(204 20% 94%), hsl(215 25% 15%));
color: light-dark(hsl(215 25% 27%), hsl(215 25% 89%));
}
.card:hover {
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);
}
.card__image {
aspect-ratio: 16/9;
object-fit: cover;
}
.card__content {
padding: 1rem;
}
.card__title {
margin-block-start: 0;
font-size: 1.25rem;
}
</style>

See the Card component in action with this example demonstrating different variants and styling options.

This is an example of the Card component with an image, title, and custom content that demonstrates how the component handles different types of content while maintaining accessibility and visual appeal.

ScienceTechnology

This is an example of the Card component with an image, title, and custom content that shows how to use meta tags through the meta slot. The badges in the meta slot can be used to categorize or tag the card content.