Update 2021: This post is extremely out-dated. You might want to goole “CSS FlexBox” or “CSS Grid” instead of reading it ;)

If you have done anything with CSS yet, you probably know the following problem: You want to vertically align some parts of your page, but you do not know the total height of the group. That is, you do not know the height of the largest element. This article shows you how to solve this problem. The approach shown here works in Chrome, Firefox and IE9, I have not tested other browsers.

First, change the box sizing to border-box. Because for me, CSS makes much more sense when box-sizing is border-box.

* { 
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
}

What doesn't work

Ok, say you’ve tried the following:

<div style="width: 450;">
	<div style="height: 20px; width: 50px; float: left;"></div>
	<div style="height: 40px; width: 150px; float: left;"></div>
	<div style="height: 100px; width: 80px; float: left;"></div>
	<div style="height: 60px; width: 120px; float: left;"></div>
</div>

Then you’ve tried to add vertical-align: middle; in various places (at least that’s what I’ve tried for some time). It does not work:

Usign tables... without using tables

What does work: Use tables. But you don’t want to use tables in your HTML code. Luckily, you can tell a div to behave like a table:

<div style="display: table-row; width: 450;">
	<div style="display: table-cell;">
		<div style="height: 20px; width: 50px;"></div>
	</div>
	<div style="display: table-cell;">
		<div style="height: 40px; width: 150px;"></div>
	</div>
	<div style="display: table-cell;">
		<div style="height: 100px; width: 80px;"></div>
	</div>
	<div style="display: table-cell;">
		<div style="height: 60px; width: 120px;"></div>
	</div>
</div>

Now, this works. At least it “kinda” works: The divs are aligned at the bottom.

So, what happened here? I have told the outer div to behave like a table row. Then I have wrapped the inner divs (the ones who paint the border and the background) in another div. This wrapping div behaves like a table cell, so it aligns its contents at the bottom.

This new div now can align its contents vertically: I can use vertical-align just like I can use it on a table cell:

<div style="display: table-row; width: 450;">
	<div style="display: table-cell; vertical-align: middle;">
		<div style="height: 20px;width: 50px;"></div>
	</div>
	<div style="display: table-cell; vertical-align: middle;">
		<div style="height: 40px;width: 150px;"></div>
	</div>
	<div style="display: table-cell; vertical-align: middle;">
		<div style="height: 100px; width: 80px;"></div>
	</div>
	<div style="display: table-cell; vertical-align: middle;">
		<div style="height: 60px; width: 120px;"></div>
	</div>
</div>

You can even use different alignments in every cell:

<div style="display: table-row; width: 450;">
	<div style="display: table-cell; vertical-align: middle;">
		<div style="height: 20px; width: 50px;"></div>
	</div>
	<div style="display: table-cell; vertical-align: top;">
		<div style="height: 40px; width: 150px;"></div>
	</div>
	<div style="display: table-cell; vertical-align: middle;">
		<div style="height: 100px; width: 80px;"></div>
	</div>
	<div style="display: table-cell; vertical-align: bottom;">
		<div style="height: 60px; width: 120px;"></div>
	</div>
</div>

This is rendered as:

So, how is this better?

I use divs, but I tell them to behave like tables. You might ask: Why is this better then using tables in the first place?

The approach outlined here clearly separates design and structure. All the design is done in CSS, the structure is provided by simple HTML divs. You can - and should move the CSS to a different file. Then you’ll have pure CSS in one file, and pure HTML in another.

Tables, OTOH, provide a structure for tabular data. Using them as a design element is an abuse of tables. The design and the structure would not be clearly separated anymore. But you already knew that ;)

You might also be interested in...