How (and why) to use display: table-cell (CSS)

After days trying to find the answer, I finally found

display: table;

There was surprisingly very little information available online about how to actually getting it to work, even here, so on to the "How":

To use this fantastic piece of code, you need to think back to when tables were the only real way to structure HTML, namely the syntax. To get a table with 2 rows and 3 columns, you'd have to do the following:

<table>
    <tr>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <tr>
        <td></td>
        <td></td>
        <td></td>
    </tr>
</table>

Similarly to get CSS to do it, you'd use the following:

HTML

<div id="table">
    <div class="tr">
        <div class="td"></div>
        <div class="td"></div>
        <div class="td"></div>
    </div>
    <div class="tr">
        <div class="td"></div>
        <div class="td"></div>
        <div class="td"></div>
    </div>
</div>

CSS

#table{ 
    display: table; 
}
.tr{ 
    display: table-row; 
}
.td{ 
    display: table-cell; }

As you can see in the example below, the divs in the 3rd column have no content, yet are respecting the auto height set by the text in the first 2 columns. WIN!

#table {
    display: table;
    padding: 5px;
}
.tr {
    display: table-row;
    padding: 5px;
}
.td {
    display: table-cell;
    padding: 5px;
    width: 150px;
    border: #000000 solid 1px;
    margin: 5px;
}
<div id="table">
    <div class="tr">
        <div class="td">Row 1,
            <br />Column 1</div>
        <div class="td">Row 1, Column 2</div>
        <div class="td" style="background:#888888;"></div>
    </div>
    <div class="tr">
        <div class="td">Row 2,
            <br />Column 1</div>
        <div class="td">Row 2, Column 2</div>
        <div class="td" style="background:#888888;"></div>
    </div>
</div>

It's worth noting that display: table; does not work in IE6 or 7 (thanks, FelipeAls), so depending on your needs with regards to browser compatibility, this may not be the answer that you are seeking.


It's even easier to use parent > child selector relationship so the inner div do not need to have their css classes to be defined explicitly:

.display-table {
    display: table; 
}
.display-table > div { 
    display: table-row; 
}
.display-table > div > div { 
    display: table-cell;
    padding: 5px;
}
<div class="display-table">
    <div>
        <div>0, 0</div>
        <div>0, 1</div>
    </div>
    <div>
        <div>1, 0</div>
        <div>1, 1</div>
    </div>
</div>

How (and why) to use display: table-cell (CSS)

I just wanted to mention, since I don't think any of the other answers did directly, that the answer to "why" is: there is no good reason, and you should probably never do this.

In my over a decade of experience in web development, I can't think of a single time I would have been better served to have a bunch of <div>s with display styles than to just have table elements.

The only hypothetical I could come up with is if you have tabular data stored in some sort of non-HTML-table format (eg. a CSV file). In a very specific version of this case it might be easier to just add <div> tags around everything and then add descendent-based styles, instead of adding actual table tags.

But that's an extremely contrived example, and in all real cases I know of simply using table tags would be better.


The display:table family of CSS properties is mostly there so that HTML tables can be defined in terms of them. Because they're so intimately linked to a specific tag structure, they don't see much use beyond that.

If you were going to use these properties in your page, you would need a tag structure that closely mimicked that of tables, even though you weren't actually using the <table> family of tags. A minimal version would be a single container element (display:table), with direct children that can all be represented as rows (display:table-row), which themselves have direct children that can all be represented as cells (display:table-cell). There are other properties that let you mimic other tags in the table family, but they require analogous structures in the HTML. Without this, it's going to be very hard (if not impossible) to make good use of these properties.