Cards

The card is Bootstrap 4's flexible content container — it replaced Bootstrap 3's three separate panel, thumbnail, and well components with one unified box. TrailMap's whole trail-listing page is built out of cards, so this lesson goes deeper than most: every card part, header/footer, and the two multi-card layout helpers.

1. Anatomy of a Card

A card is a .card wrapper, almost always holding a .card-body for padded content. Inside the body, .card-title styles a heading-like element and .card-text styles a paragraph with the correct bottom margin.

<div class="card" style="width: 18rem;">
  <div class="card-body">
    <h5 class="card-title">Card title</h5>
    <h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
    <p class="card-text">Some quick example text to build on the card title.</p>
    <a href="#" class="card-link">Card link</a>
  </div>
</div>

2. Images: .card-img-top

An image placed directly inside .card (as a sibling before .card-body, not nested inside it) with .card-img-top stretches full-width and gets rounded top corners that match the card.

<div class="card" style="width: 18rem;">
  <img src="trail-photo.jpg" class="card-img-top" alt="Trail photo">
  <div class="card-body">
    <h5 class="card-title">Ridgeline Loop</h5>
    <p class="card-text">A steady climb with sweeping valley views near the summit.</p>
  </div>
</div>

3. Header and Footer: .card-header / .card-footer

.card-header and .card-footer add a visually separated strip above or below .card-body, useful for a title bar or a timestamp/metadata line.

<div class="card">
  <div class="card-header">Featured Trail</div>
  <div class="card-body">
    <h5 class="card-title">Sunset Ridge Trail</h5>
    <p class="card-text">Best hiked in the last two hours before dusk.</p>
  </div>
  <div class="card-footer text-muted">Updated 3 days ago</div>
</div>

4. Multiple Cards: .card-group and .card-deck

.card-group attaches a row of cards edge to edge with shared borders, like a single connected strip. .card-deck instead lays cards out as separate boxes of equal height with consistent gutters between them — closer to a grid of independent cards.

<!-- card-group: edge-to-edge, shared borders -->
<div class="card-group">
  <div class="card">
    <div class="card-body">
      <h5 class="card-title">Sunset Ridge</h5>
      <p class="card-text">3.2 mi · Easy</p>
    </div>
  </div>
  <div class="card">
    <div class="card-body">
      <h5 class="card-title">Ridgeline Loop</h5>
      <p class="card-text">4.8 mi · Hard</p>
    </div>
  </div>
</div>

<!-- card-deck: equal height, spaced apart -->
<div class="card-deck">
  <div class="card">
    <div class="card-body">
      <h5 class="card-title">Sunset Ridge</h5>
      <p class="card-text">A short intro line that is a bit longer here.</p>
    </div>
  </div>
  <div class="card">
    <div class="card-body">
      <h5 class="card-title">Ridgeline Loop</h5>
      <p class="card-text">Short intro line.</p>
    </div>
  </div>
</div>
.card-deck is a genuine Bootstrap-4-only feature. Bootstrap 5 removed .card-deck entirely — its equal-height, evenly-gapped layout is now built with the regular grid plus the gap utility instead (e.g. row row-cols-3 g-4). If you're maintaining a Bootstrap 4 codebase, .card-deck is still the correct, supported way to do this; there is no equivalent single class to reach for if you ever port the markup forward.

5. Worked Example: The TrailMap Trail Card

This is the actual card TrailMap repeats across its trail-listing page: a top photo, a title with an inline difficulty badge, a truncated one-line description, a footer with distance and rating, and a full-width action button.

<div class="card" style="width: 20rem;">
  <img src="ridgeline-loop.jpg" class="card-img-top" alt="Ridgeline Loop trail">
  <div class="card-body">
    <h5 class="card-title text-truncate">
      Ridgeline Loop
      <span class="badge badge-danger">Hard</span>
    </h5>
    <p class="card-text text-truncate">
      A steady climb with sweeping valley views near the summit.
    </p>
    <a href="#" class="btn btn-primary btn-block">View Trail</a>
  </div>
  <div class="card-footer text-muted">
    4.8 mi · ★ 4.6 (112 reviews)
  </div>
</div>
Next up: that footer mentioned reviews — head to List Groups to see how TrailMap lists individual recent reviews underneath a trail's detail page.