How to Make Equal Height Columns in CSS
This recipe explains how flexbox makes columns equal height automatically by default, solving a problem that used to require table layouts or JavaScript measuring.
The classic problem
Before flexbox, floated or inline-block columns each sized themselves to their own content - a column with an extra sentence of text ended up visibly taller than its neighbors, breaking any shared background, border, or button row. The old fixes were awkward: display: table and display: table-cell borrowed the table layout algorithm just to get matching heights, and some sites used JavaScript to measure the tallest column and set that height on the rest by hand, which broke the moment the window resized or the content changed.
Flexbox solves it by default
Flex items stretch to match the tallest item along the cross axis automatically - this is the initial value of align-items, called stretch. That means putting display: flex on a row of columns is often enough by itself; you do not need to write align-items: stretch, because it is already the default. If you ever want columns to keep their own natural height instead, override it explicitly with align-items: flex-start.
Example
<!DOCTYPE html>
<html>
<head>
<style>
.row {
display: flex;
gap: 16px;
padding: 24px;
font-family: sans-serif;
}
.col {
flex: 1;
background: #f3f4f6;
padding: 16px;
border-radius: 8px;
}
</style>
</head>
<body>
<div class='row'>
<div class='col'>
<h3>Short</h3>
<p>One line of text.</p>
</div>
<div class='col'>
<h3>Medium</h3>
<p>A couple of sentences that take up more vertical space than the short column.</p>
</div>
<div class='col'>
<h3>Long</h3>
<p>This column has the most content of all three, with several extra lines describing the item in detail, yet every column still ends at the exact same height.</p>
</div>
</div>
</body>
</html>Pinning content to the bottom of each card
Equal-height columns unlock a second trick: making a card's footer or button line up across every card even when the body text is a different length. Make each card itself a flex column (flex-direction: column), give the description flex: 1 so it grows to fill the leftover space, and add margin-top: auto to the button - margin-top: auto on a flex child consumes all remaining free space above it, shoving the button to the very bottom edge.
Example
<!DOCTYPE html>
<html>
<head>
<style>
.row { display: flex; gap: 16px; font-family: sans-serif; }
.card {
flex: 1;
display: flex;
flex-direction: column;
background: white;
border: 1px solid #e5e7eb;
border-radius: 8px;
padding: 16px;
}
.card p { flex: 1; }
.card button {
margin-top: auto;
align-self: flex-start;
padding: 8px 14px;
}
</style>
</head>
<body>
<div class='row'>
<div class='card'>
<h3>Basic</h3>
<p>Short description.</p>
<button>Choose</button>
</div>
<div class='card'>
<h3>Pro</h3>
<p>A longer description with more detail about what this plan includes, pushing the button down.</p>
<button>Choose</button>
</div>
</div>
</body>
</html>The grid alternative
CSS Grid stretches items by the same logic - align-items: stretch is also grid's default value - so a simple grid-template-columns row gives you equal-height columns just as easily. Grid is the better choice when the columns are part of a larger, strictly aligned table-like layout rather than a single row.
Example
<!DOCTYPE html>
<html>
<head>
<style>
.grid-row {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
font-family: sans-serif;
}
.grid-row > div {
background: #f3f4f6;
padding: 16px;
border-radius: 8px;
}
</style>
</head>
<body>
<div class='grid-row'>
<div>Short column</div>
<div>Medium column with more text</div>
<div>Long column with the most text of the three, wrapping across several lines</div>
</div>
</body>
</html>Exercise: Layout
In a Flexbox container, what determines the direction of the main axis?
Frequently Asked Questions
- How do I make two divs the same height?
- Put them in a flex container. Flex items stretch to match the tallest sibling by default, so equal heights need no extra CSS at all. If you have overridden
align-items, set it back tostretch. - How do I make equal height columns in CSS grid?
- Grid items already stretch to fill their row. Define the columns with
grid-template-columnsand every cell in a row shares that row's height automatically, regardless of how much content each one holds.