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):

Column 1
Column 2
Column 3

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;
}
Column 1
Column 2
Column 3

Column 1
Column 2
Column 3

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;
}
Column 1
Column 2
Column 3

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;
}
Column 1.
Column 2 is a bit longer.
Column 3 is longer with lots of text in it.

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:

Column 1.
Column 2 is a bit longer.
Column 3 is longer with lots of text in it.

Columns fit percentage widths:

Column 1.
Column 2 is a bit longer.
Column 3 is longer with lots of text in it.

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;
}
Column 1.
Column 2 is a bit longer.
Column 3 is longer with lots of text in it.

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.

Column 1.
Column 2 is a bit longer.
Column 3 is longer with lots of text in it.

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?

If you enjoyed this post, consider leaving a comment or subscribing to the RSS feed.
This site uses cookies. Find out more about cookies.