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.
  • IRONEAGLE

    Very helpfull. Thanks a lot!!

  • Antti202

    Really useful!

  • Joshua Vedder

    That really helped me a lot. However, this way, as is the same with all tables is that i cannot group content by columns, you must do rows first. I am wanting to have 3 divs, that are the columns, each with multiple sections in it. but I really want to use the columns as the container not the rows. and have each of the sections the same height as their counterparts. Hmm…

    Doing this so it’s semantically correct rather than having to group by row.

    Any ideas? I thought your solution was great, but I just can’t manage to make something do this.

  • Hi Joshua. As far as I know, the cells need to be given rows first, so I don’t think it’s possible to do what you want using a table layout. A float: left; approach could work if fixed widths and heights could be used.

  • Joshua Vedder

    Thanks for the reply. I tried using floats, but as you say, it works if fixed heights are used. I was hoping more a fluid layout, but of course there is no CSS for “make me the same height as him”, at least not without JavaScript. So I don’t know, maybe I could use JS and fall back on to either fixed height or table method. At the moment I am just using the columns as containers of the same height (as you showed) and leaving the inside to sort itself out.

  • just about to use it on my project, thanks bro

  • Rui

    You can try setting the overflow property of the container to hidden.

    .container{
    overflow: hidden;
    }

    Should make floated blocks within the container appear fixed height.

  • Mattias

    This works perfectly……. if you use text! If you have an DIV inside the “Proportional width columns” it will not work. Having tried multiply solutions, there seem to be no easy win…

  • Dorival Cardozo

    dont works 🙁

  • A simple online tool to convert html table into div elements is HTML-Cleaner ( http://www.html-cleaner.com )
    Just check the box in cleaning settings.

  • djnforce9

    Just learned how to do this recently and it is proving to be one of the most useful techniques I have come across (especially for creating mobile-friendly sites).

  • teamug.net

    Good when using tags, as table rows can not be wrapped with them.

  • You have written nice article on display: table-cell we are
    Dubai base web Design Company

  • useful .

  • Luke

    Yeah, seems even Bootstrap’s fluid percentage row-cells don’t play nicely with consistent height display=table. http://stackoverflow.com/questions/30388921

    Something for JS unfortunately?

  • Mattias, please can you post a basic example to clarify the problem?

  • Madhavan Kumar

    great work…

  • Gary Law

    This works with chrome but does not seem to work with firefox or IE.

  • Tom

    it’s working … thank you

  • Lukasz

    Works well! Thanks.

This site uses cookies. Find out more about cookies.