<code snip>: Equalizing Card Content Heights for Different Title Lengths

Sherpa Design Co.
Jun 11, 2018 · 2 min read
A properly aligned card grid (with a little help from Javascript).

The Problem

Web design cards are a great way to present collections of information (such as blog posts) in a more organized, digestible format.

Unfortunately, the content they contain is often variable—headlines or excerpts of different lengths can leave awkward amounts of white space and make your cards visually inconsistent. No bueno!

The Solution

I’m a big proponent of hacking things with pure CSS whenever possible, but I’ve been running into this issue for years, and I finally gave up because I’m tired of looking at uneven cards!

UPDATE: Thanks to @jpuchevictoria, I now know there is a pure CSS solution. The card element needs to be set to display: flex and the card content element needs to be set to flex-grow: 1. Simple!

Surprisingly, this one is pretty easy to solve with Javascript. You can follow along below or check out the JSFiddle.

I started by adding three cards that each contain a image placeholder, title, and author footer.

Html Markup

<div id=’grid’><div class=’card’>
<div class=’media’> </div>
<div class=’content’>
<h3>This post title is a normal length and looks ok</h3>
<p>by The Author</p>
</div>
</div>
... more cards

CSS Styles

The content element is given display:flex and justify-content: space-between to spread the title and author elements to opposite ends.

This doesn’t work out of the box because content doesn’t have a fixed height—that’s where Javascript comes in.

.content {
padding: 20px;
display:flex;
justify-content: space-between;
flex-direction: column;
box-sizing: border-box;
}
... other styles

Javascript Code

We essentially need to accomplish three tasks:

  1. Find the tallest content element
  2. Set each content element to that value
  3. Wipe the height style once the cards are all on their own lines (mobile)

The first part of the JSFiddle script adds a resize Event Listener to the window and executes the initial adjustment.

The cards at index 0 and 1 are compared to determine whether the cards are in more than one column (they don’t need to be adjusted on mobile devices where there’s just 1 column).

if (oneTop == twoTop) {

The line below reduces the card content elements into a constant containing the largest height. Note: you have to use the spread operator to convert the NodeList into a true array before using reduce.

const largest = [...$cards].reduce((largestHeight,$card) => {

Finally, we take the largest content element height and apply it to each card’s content element. This allows Flexbox to work properly—pinning the title to the top of the card content and the author to the bottom.

$card.querySelector('.content').style.height = largest + 'px';

Mission accomplished!

Wrap Up

Let me know how this solution works for you. I’d love to hear ideas for improvement, as well.

Cheers!

—Andrew, Sherpa Design Co.

Sherpa Design Co.

Written by

Andrew Folts is a freelance web designer and developer who helps small businesses share unique products, services, and stories through Hard-Working Websites.™

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade