albert.walickihire me
← all solutions
css

How to make elements in a row the same height?

Make cards or columns in a row the same height with flexbox or grid, push their buttons to the bottom, and line up titles and text across cards with subgrid.

Put the elements in a flex container. Flex items in a row already stretch to the height of the tallest one, because align-items: stretch is the default:

.cards {
  display: flex;
  gap: 24px;
}

You don't need fixed heights or JavaScript. If the items still end up with different heights, something is overriding the stretch:

  • align-items on the container, or align-self on an item, is set to center, flex-start or a similar value.
  • The item has a fixed height, which stretching doesn't override.
  • The visible card isn't the flex item. If each card sits inside a wrapper, such as an <li>, the wrapper stretches but the card inside doesn't. Give the card height: 100%. That works because a stretched flex item counts as having a definite height.
  • With flex-wrap: wrap, each line stretches on its own, so cards on different lines can have different heights.

Grid

Grid items in the same row stretch the same way. Add grid-auto-rows: 1fr when every row should be as tall as the tallest row in the whole grid, not only the tallest item in its own row:

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  grid-auto-rows: 1fr;
  gap: 24px;
}

This is also the answer for layouts that wrap onto several lines, where flex can't match heights across lines.

Push the button to the bottom of the card

Equal-height cards still look uneven when some have less text, because the button lands at a different spot in each card. Make the card a flex column and give the button margin-top: auto, which takes all the free space above it:

<article class="card">
  <h3>Starter</h3>
  <p>For side projects and small sites.</p>
  <a class="card-button" href="/signup">Choose plan</a>
</article>
.card {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.card-button {
  margin-top: auto;
  align-self: flex-start;
}

align-self: flex-start stops the link from stretching across the full width of the card. Remove it if you want a full-width button.

Line up titles and text across cards with subgrid

Flex can't align the parts of different cards with each other. If one title wraps onto two lines, the text in that card starts lower than in the others. Subgrid fixes that: each card spans three rows of the parent grid and uses those rows for its own children, so the tallest title in the row sets the title height for every card.

<div class="plans">
  <article class="plan">
    <h3>Starter</h3>
    <p>For side projects and small sites.</p>
    <a href="/signup?plan=starter">Choose Starter</a>
  </article>
  <article class="plan">
    <h3>Team plan for growing companies</h3>
    <p>Everything in Starter, plus roles and shared billing.</p>
    <a href="/signup?plan=team">Choose Team</a>
  </article>
  <article class="plan">
    <h3>Enterprise</h3>
    <p>Single sign-on, audit logs and a dedicated contact.</p>
    <a href="/contact">Talk to us</a>
  </article>
</div>
.plans {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 24px;
}

.plan {
  display: grid;
  grid-row: span 3;
  grid-template-rows: subgrid;
  row-gap: 12px;
  padding: 24px;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
}

.plan h3,
.plan p {
  margin: 0;
}

.plan a {
  justify-self: start;
}

A few things to know:

  • The number in span 3 must match the number of children in each card. If you add a price, use span 4.
  • A subgrid uses the parent's gap by default. row-gap on the card overrides it for the space inside the card, while the parent's gap still separates the cards.
  • justify-self: start keeps the link from stretching across the card, the same job align-self did in the flex version.

Subgrid is supported in all major browsers (Can I Use), so there's no reason left for JavaScript that measures and equalizes heights.

more solutions
work with me

Got something that needs building?

Frontend builds, full-stack features in Django, design-system work. Available for work.

See my workGet in touch