Snippets / UI Components /

Horizontal Card

Card layout where image/media sits on the left and content on the right using CSS Grid.

Card image

Card Title

A brief description of the content goes here to give context.

March 2026 • 5 min read

Widely Supported
ui layout no-js

Quick implementation

.horizontal-card {
  display: grid;
  grid-template-columns: 12rem 1fr;
  gap: 1.5rem;
  background: var(--card);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: all 0.2s ease;
}

.horizontal-card:hover {
  box-shadow: 0 1rem 2rem oklch(0 0 0 / 0.15);
  transform: translateY(-4px);
}

.horizontal-card__image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.horizontal-card__content {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 1.5rem 1.5rem 1.5rem 0;
  gap: 0.75rem;
}

.horizontal-card__title {
  font-size: 1.1rem;
  font-weight: 700;
  margin: 0;
}

.horizontal-card__description {
  font-size: 0.9rem;
  color: var(--muted);
  margin: 0;
}

@media (max-width: 640px) {
  .horizontal-card {
    grid-template-columns: 1fr;
  }

  .horizontal-card__image {
    height: 10rem;
  }

  .horizontal-card__content {
    padding: 1.5rem;
  }
}

Prompt this to your LLM

Includes role, constraints, two framework variants, and edge cases to handle.

You are a senior frontend engineer specializing in responsive layout design and card components.

Your goal: Create a horizontal card component with image on the left and content on the right—using CSS Grid for layout that gracefully adapts to mobile and tablet viewports.

Technical constraints:
1. Use CSS Grid with two columns: fixed width image column (12rem) and flexible content column (1fr)
2. Gap between columns should be consistent (1.5rem)
3. Image should maintain aspect ratio and fill its container (object-fit: cover)
4. Content should be vertically centered using flex with justify-content: center
5. On mobile (< 640px), card should stack vertically (single column grid)
6. Border-radius should be applied to card, not image (overflow: hidden handles corners)
7. Hover state includes shadow lift and subtle transform
8. Must be accessible with semantic HTML (article > img + div structure)

Vanilla implementation:
- Create .horizontal-card with CSS Grid layout
- Use BEM naming: __image, __content, __title, __description
- Implement media query for mobile stacking
- Add :hover state with box-shadow and transform
- Ensure image alt text and semantic elements

React implementation:
- Create Card component accepting image, title, description, and meta props
- Use CSS Modules or styled-components for responsive grid
- Support onClick handler for navigation
- Handle image loading with lazy loading and placeholder
- Create CardImage, CardContent, CardTitle, CardMeta as sub-components

Edge cases to handle:
1. Missing image: provide placeholder background or hide image section
2. Long titles: use text-overflow: ellipsis and line-clamping
3. Different image aspect ratios: object-fit: cover ensures consistency
4. Touch devices: :active state instead of :hover for feedback
5. Landscape vs portrait images: object-fit handles both
6. Small viewports (< 400px): further adjust padding and font sizes

Why this matters in 2026

The horizontal card is the workhorse of modern web design. It appears everywhere: blog post previews, product listings, article recommendations, and search results. The left-image, right-content layout is intuitive and leverages Western reading patterns (left-to-right). Users instantly understand the hierarchy: image attracts attention, content provides context.

In 2026, responsive design is non-negotiable. A horizontal card that gracefully stacks on mobile wins over a card that breaks at 320px width. CSS Grid makes this trivial: one media query flips from two columns to one. This is modern, performant layout design.

The logic

The horizontal card uses display: grid; grid-template-columns: 12rem 1fr to create a two-column layout. The image column is fixed at 12rem (192px), and the content column fills remaining space with 1fr. The gap of 1.5rem provides breathing room between sections. The object-fit: cover ensures images fill their container while maintaining aspect ratio, preventing distortion.

The content section uses flexbox with justify-content: center to vertically center text, which looks polished and balanced. On mobile (640px and below), the media query switches to grid-template-columns: 1fr, making the card stack vertically. The image gets a fixed height (10rem) on mobile to prevent it from being too tall. The hover state includes a box-shadow and transform: translateY(-4px) for subtle elevation.

Accessibility & performance

Accessibility: The card should use semantic HTML: <article> for the card container, <img> with descriptive alt text, <h3> for title (not div with font-weight: bold). The content hierarchy should flow logically: title, description, metadata. For clickable cards, wrap everything in an <a> with the title as the link text.

Performance: The CSS Grid layout is GPU-accelerated and causes zero layout thrashing. Images should be lazy-loaded on production: <img loading="lazy">. Use modern image formats (WebP with fallback) and appropriate sizing. The hover transform is GPU-accelerated and has minimal cost. The box-shadow is more expensive; consider using filter: drop-shadow() for better performance on mobile.