Categories:

Creating an Equal Height Pricing Table using CSS Flexbox

Author: Guest Post by Jon Muller | Feb 4th, 2018

In my opinion, pricing tables are the most succinct and effective way to quickly capture and convey to potential customers your services and the benefits at a glance. Recently I was looking at a good pricing table for my site, and realized the problem with almost all of them- they are not responsive vertically. By that I mean each column within the pricing table has its own height based on the amount of content inside. I need an equal height pricing table where all the columns share a same height without resorting to tables. My solution? CSS Flexbox.

Here's an example of the equal height pricing table I'll show you how to create using CSS Flexbox. Notice how each column's height is identical to its peers, even though they all have different rows of content. Furthermore, the last LI where the call to action button is embedded in is always bottom aligned:

In a nutshell, here are the two critical CSS rules that went into creating an equal height pricing table:

The HTML Markup

Let me start with the HTML markup, which I wanted to be as clean and lean as possible. To that end I simply use a UL list for each individual pricing table, with all of them wrapped in a DIV container:

<div class="pricingdiv">
	<ul class="theplan">
		<li class="title"><b>2nd Place</b><br />Herman Miler</li>
		<li><b>Weight:</b> 55 lbs</li>
		<li><b>Max Weight:</b> 330 lbs</li>
		<li><a class="pricebutton" href="#"><span class="icon-tag"></span> Check Out</a></li>
	</ul>
	<ul class="theplan">
		<li class="title"><b>1st Place</b><br />Argomax Chair</li>
		<li><b>Material:</b> Nylon w/ Breathable Glass Fiber</li>
		<li><b>Head Rest:</b> Yes</li>
		"
		"
		<li><a class="pricebutton" href="#"><span class="icon-tag"></span> Check Out</a></li>
	</ul>
	<ul class="theplan">
		<li class="title"><b>3rd Place</b><br />Eurotech Mesh</li>
		<li class="ethighlight"><b>Dimensions:</b> 24.8W x 47.3H</li>
		"
		<li><a class="pricebutton" href=""><span class="icon-tag"></span> Check Out</a></li>
	</ul>
</div>

As you can see, each UL.theplan element contains different number of LI entries. The goal is to make each UL the same height, and where each pricing plan's last LI entry lines up at the very bottom.

The easiest way I've found to do that? Use CSS flexbox and set each UL to flex-direction:column so they expand vertically to match the longest flex child's height. I'll explain in more detail below.

The CSS

Here is the CSS for the equal height pricing table. I've removed the unimportant bits so you can focus on the important stuff:

.pricingdiv{
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
}

.pricingdiv ul.theplan{
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	width: 260px; /* width of each table */
	margin-right: 20px; /* spacing between tables */
	margin-bottom: 1em;
	border: 1px solid gray;
	transition: all .5s;
}

.pricingdiv ul.theplan:hover{ /* when mouse hover over pricing table */
	transform: scale(1.05);
	transition: all .5s;
	z-index: 100;
	box-shadow: 0 0 10px gray;
}

.pricingdiv ul.theplan:last-of-type{ /* remove right margin in very last table */
	margin-right: 0;
}

/*very last LI within each pricing UL */
.pricingdiv ul.theplan li:last-of-type{
	text-align: center;
	margin-top: auto; /*align last LI (price botton li) to the very bottom of UL */
}  


@media only screen and (max-width: 600px) {
	.pricingdiv ul.theplan{
		border-radius: 0;
		width: 100%;
		margin-right: 0;
	}

	.pricingdiv ul.theplan:hover{
		transform: none;
		box-shadow: none;
	}
	
	.pricingdiv a.pricebutton{
		display: block;
	}
}

I start out by setting the parent DIV container to display:flex, and allow the flex children to wrap and be centered horizontally, using flex-wrap: wrap and justify-content: center. All of the children UL elements are considered flex children.

For each pricing table, which consist of a UL element, I set flex-direction:column. By default flex children play on the horizontal axis. By setting direction:column, I force all of the default behaviour of flex children to occur on the vertical plane, including the golden prize- equal height flex children by default.

Bottom Aligning the last LI within each UL Pricing Table

So all the individual pricing tables within the DIV are now the same height, but there's still one important refinement needed to make everything look polished. I want the call to action button, which is contained in the very last LI of  each UL, to be aligned to the very bottom of the table.

To do this involves 2 steps. First, I set each UL pricing table to a flexbox container itself as well (display: flex). Once that's done, I can use the margin property to align a specific child element differently from its peers, such as left or right aligned for horizontal flex children, or in this case of vertical flex children, top or bottom.

To get the very last LI element to be bottom aligned, the magic ingredient to add is margin-top: auto inside those elements:

.pricingdiv ul.theplan li:last-of-type{
	text-align: center;
	margin-top: auto; /*align last LI (price botton li) to the very bottom of UL */
}

If you're not familiar with this technique of using the margin property to align a specific flex child differently from the other children, check out this very helpful section on aligning CSS flex children elements.

Conclusion

As you can see, CSS Flexbox makes creating elements that are equal height, responsive, and even centered on the page a piece of cake. It helped me tackle most of the issues I have with many CSS pricing tables I've seen. I hope you find the techniques I've gone over helpful.

Author Bio: This post was contributed by Jon Muller at Ergonomic Trends, where he writes about and reviews the latest ergonomic products such as office chairs, standing desks, and split keyboards for better health and productivity.