Same Columns Height

Yeah I know, I can do it with min-height, or perhaps a table-layout… It's what you think, but you are not totally right if you do so. But before talking about right and wrong, let’s define our needs.

Defining the columns behavior

I worked with several designers. You know them, they want to create perfect blocks with right divisions, well measured columns, buttons to the bottom, gorgeous images or icons to illustrate a marketing wording…
Let's define our needs as following:

  • Columns should have same visual height by taking the biggest one,
  • Columns could have same width, but can also be flexible,
  • I want an image at the top, then a title, then a little text and a button/link
  • The link have to be at the bottom-end of the column, no matter the text size above,
  • Use a minimal markup and CSS, only CSS, no JS

Let's code this

First at all, you need to build a basic HTML markup. I propose to you this one, but feel free to adapt or improve regarding your real needs.

HTML

<section>
	<h1>Same Column Height</h1>
	<div class="flex">
		<div class="col">
				
			<a href="#">
				<img src="image.jpg" width="" height="" alt="Some sample words">
			</a>

			<h2>A little title</h2>
			<p>Lorem ipsum dolor sit […]</p>
				
			<a class="btn" href="#">Read more</a>

		</div>

		<div class="col">
				
			<a href="#">
				<img src="image.jpg" width="" height="" alt="Some sample words">
			</a>

			<h2>A little title</h2>
			<p>Lorem ipsum dolor sit amet […]</p>
				
			<a class="btn" href="#">Read more</a>

		</div>

		<div class="col">
				
			<a href="#">
				<img src="image.jpg" width="" height="" alt="Some sample words">
			</a>

			<h2>A little title</h2>
			<p>Lorem ipsum dolor sit amet, consectetur […]</p>
				
			<a class="btn" href="#">Read more</a>

		</div>
	</div>
</section>

Now some styles to make the magic works.

CSS

To be clear: today, your website has to be responsive. That's why the CSS code I'll propose you is mobile first responsive.

/**
 * Make images responsive
 */
.flex .col img {
	width: 100%;
	height: auto;
}

/**
 * Make .flex children same
 * height using display flex.
 * Justify property prepares
 * cols for being centered.
 */
.flex {
	display: flex;
	justify-content: center;
	width: 960px;
	max-width: 100%;
	margin: auto;
}

/**
 * Make cols flexible to
 * auto push button at the
 * col bottom.
 */
.flex .col {
	display: flex;
	flex-direction: column;
	flex: 1 1 300px;
	/* 
	In the order, equal to
	flex-grow: 1;
	flex-shrink: 1;
	flex-basis: 300px;
	*/
	margin: 1em;
}

/**
 * Margin-top auto pushes
 * button to bottom.
 * Align self makes button
 * stuck to the left.
 */
.flex .col .btn {
	align-self: flex-start;
	margin-top: auto;
}

/**
 * Under 900px wrap cols
 */
@media (max-width: 900px) {
	.flex {
		flex-wrap: wrap;
	}
}

In that precise case, I allowed images to be very big, larger than their physical width in intermediate screen sizes. (iPad mini in portrait, or something…)
If you need to keep a real good feeling about images, grab a solution among size and srcset attributes, or simply decide to replace flex: 1 1 300px; by flex: 0 1 300px; that allows cols being smaller but not bigger than 300 pixels wide.

I hope these comments will help you understand this very short code.Yeah, as you can see, it's pretty easy to do it work.

Sure, there are many other ways to make the same thing differently. Feel free to adapt it and make your own code.