Using CSS “display: table-cell” for columns
I’ve been using display: table-cell
and display: table
in CSS for a couple of different projects recently and have been impressed by the results. The styling is used to make elements, such as <div>
tags behave like <table>
and <td>
tags. Ideally we strive to separate semantic mark-up and presentation, so <table>
tags should be reserved for data that’s structured in a table format, and if you just want a grid layout that behaves a bit like a table, use <div>
tags with display: table-cell
instead. display: table-*
options are supported in any recent browser, and from IE8 onwards.
How to use “display: table-cell”
Given the following HTML:
<div class="container"> <div class="column">Column 1</div> <div class="column">Column 2</div> <div class="column">Column 3</div> </div>
we can apply the following CSS:
.container { display: table; } .column { display: table-cell; }
to give us a grid layout (I’m also adding a border to make the output a little clearer):
If we want multiple rows we can also include display: table-row
:
<div class="container"> <div class="row"> <div class="column">Column 1</div> <div class="column">Column 2</div> <div class="column">Column 3</div> </div> <div class="row"> <div class="column">Column 1</div> <div class="column">Column 2</div> <div class="column">Column 3</div> </div> </div>
.container { display: table; } .row { display: table-row; } .column { display: table-cell; }
This is basically the equivalent of using the <table>
, <tr>
and <td>
tags:
<table> <tr> <td>Column 1</td> <td>Column 2</td> <td>Column 3</td> </tr> <tr> <td>Column 1</td> <td>Column 2</td> <td>Column 3</td> </tr> </table>
Column 1 | Column 2 | Column 3 |
Column 1 | Column 2 | Column 3 |
Floated Grid Layouts
Most grid layouts are produced by using float: left
on <div>
tags. So, a more common way to produce the same result for the same HTML would be to use:
.container { display: block; } .column { display: block; float: left; }
This approach tends to work quite well, particularly when using with explicit widths for the columns. However, there are some situations where a table layout can provide better results.
Proportional width columns
Expanding the width of the element to fill the available space in proportion to the size of the content. We can set the width on the display: table
element to 100%:
<div class="container"> <div class="column">Column 1.</div> <div class="column">Column 2 is a bit longer.</div> <div class="column">Column 3 is longer with lots of text in it.</div> </div>
.container { display: table; width: 100%; } .column { display: table-cell; }
When floating elements it’s easy to specify a fixed width, or percentage width, but not proportional widths to fill the available space.
Columns fit length of text:
Columns fit percentage widths:
Consistent height columns
Columns expand to match the height of the largest column in the row. The height is defined by the content and not an explicit fixed height.
<div class="container"> <div class="column">Column 1.</div> <div class="column">Column 2 is a bit longer.</div> <div class="column">Column 3 is longer with lots of text in it.</div> </div>
.container { display: table; } .column { display: table-cell; width: 100px; }
This is particularly useful when there is background, or border on each column and you want them to line up nicely at the bottom. Floated columns will have a ragged bottom.
A common workaround for floated elements is to set a min-height
value. This works if the length of the longest content is always roughly the same, but isn’t a viable solution if the length of the content varies significantly.
Other uses
Using display: table-cell
can also be useful for vertically aligning HTML.
What other use cases do you have for display: table-cell
?