Equalizing Card Heights with Variable Content Using CSS Flexbox
Varying text lengths in grid layouts frequently cause vertical misalignment. Instead of applying rigid heights or JavaScript calculations, CSS Flexbox provides a native solution to equalize card dimensions while anchoring action elements to the bottom.
The layout relies on a flex container that wraps its children, with each card configured as a vertical flex column. By allowing the main content area to grow and occupy available space, all cards in a row automatically match the height of the tallest item.
.card-container {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
}
.card-item {
flex: 1 1 300px;
max-width: 340px;
display: flex;
flex-direction: column;
padding: 1.5rem;
border: 1px solid #e2e8f0;
border-radius: 0.5rem;
box-sizing: border-box;
background-color: #ffffff;
}
.card-header {
display: flex;
align-items: center;
gap: 0.75rem;
}
.card-header img {
width: 2.5rem;
height: 2.5rem;
border-radius: 0.25rem;
object-fit: cover;
}
.card-title {
margin: 0;
font-size: 1.125rem;
font-weight: 600;
color: #1a202c;
}
.card-meta {
font-size: 0.75rem;
color: #718096;
margin-top: 0.25rem;
}
.card-description {
flex: 1 0 auto;
margin: 1rem 0;
line-height: 1.5;
color: #4a5568;
overflow-y: auto;
max-height: 8rem;
}
.card-footer {
display: flex;
justify-content: space-between;
align-items: center;
flex: 0 0 auto;
padding-top: 0.5rem;
border-top: 1px solid #edf2f7;
}
.action-btn {
padding: 0.5rem 1rem;
background-color: #3182ce;
color: #ffffff;
border: none;
border-radius: 0.25rem;
cursor: pointer;
font-size: 0.875rem;
}
<div class="card-container">
<article class="card-item">
<div class="card-header">
<img src="/assets/icons/platform-a.svg" alt="Platform A">
<div>
<h3 class="card-title">Platform A</h3>
<div class="card-meta">Official Plugin • v2.1</div>
</div>
</div>
<p class="card-description">
A lightweight solution for small businesses. Ideal for quick deployment and standard e-commerce workflows.
</p>
<div class="card-footer">
<span class="card-meta">Dev: CoreTeam</span>
<button class="action-btn" data-id="plat-a">Install</button>
</div>
</article>
<article class="card-item">
<div class="card-header">
<img src="/assets/icons/platform-b.svg" alt="Platform B">
<div>
<h3 class="card-title">Platform B</h3>
<div class="card-meta">Custom Script • v4.0</div>
</div>
</div>
<p class="card-description">
An enterprise-grade SaaS ecosystem featuring advanced inventory synchronization, multi-channel distribution, and automated marketing tools. Designed for high-volume merchants requiring scalable infrastructure and comprehensive analytics dashboards.
</p>
<div class="card-footer">
<span class="card-meta">Dev: EnterpriseSoft</span>
<button class="action-btn" data-id="plat-b">Install</button>
</div>
</article>
</div>
The alignment mechanism depends on three specific flexbox configurations:
- Vertical Column Layout: Each card (
.card-item) usesdisplay: flexandflex-direction: column. This establishes a vertical formatting context where child elements stack and can be sized relative to the container's height. - Dynamic Content Expansion: The description block (
.card-description) receivesflex: 1 0 auto. Theflex-grow: 1value forces this element to consume all remaining vertical space within the card. Since flex containers in a row naturally stretch to match the tallest sibling, the expanding description pushes subsequent elements downward, creating uniform card heights. - Fixed Footer Positioning: Interactive elements and metadata at the bottom (
.card-footer) are assignedflex: 0 0 auto. This prevents them from stretching or shrinking, ensuring they remain anchored to the bottom edge regardless of how much the description expands. If text exceeds the definedmax-height, theoverflow-y: autoproperty enables internal scrolling without breaking the layout.