80

I have a site with a very active background (I'm talking 6 or so different z-indexes here 2 with animations). I wanted a <div> in the foreground that had content but wanted a "window" through to the background in it. Some problems I had:

  1. you can't "punch a hole" in a background, so...
  • I built a containing div, lets call it "srminfo"
  • Inside that I had a "top", "left", "window", "right" and "bottom"
  • the top, left, right, bottom all had opaque white backgrounds
  • while the srminfo and window divs had background:none;
  1. No matter how hard I tried, the "right" div wouldn't fill the space between the "top" and "bottom" divs, I tried a lot of different things. The reason it had to be dynamic is that the text in the "left" div was dynamic based on the background colour, which was itself generated randomly with JavaScript.

How is display: table; and all the other related CSS code like tables? And how can it be used?

3
  • possible duplicate of How create table only using <div> tag and Css Commented Mar 24, 2015 at 10:19
  • CSS table layout doesn't work in IE7 either. It's IE8+ only. And with Firefox 28+, position: relative works on "cells" as it works in Chrome, IE and others which is great when you've complex layouts :) Information about HTML tables (just remove things like colspan which are only for HTML tables and add needed CSS as display: something) on CSS-Tricks: css-tricks.com/fixing-tables-long-strings or css-tricks.com/complete-guide-table-element Commented Mar 24, 2015 at 11:45
  • 1
    Minor nitpick: IMHO the title of this question is a bit misleading. Its a Q&A, where one possible answer is "use CSS table-cell". But the actual "question" is some specific layout desire. With an appropriate title, this might have attracted other CSS-based solutions, that don't involve display: table. Commented Apr 30, 2019 at 23:34

5 Answers 5

138

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.

Sign up to request clarification or add additional context in comments.

3 Comments

In terms of accessibility how is this different than an actual table?
Can you also include column headers?
67

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>

Comments

10

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.

1 Comment

Good answer! I would add that you can construct a true, semantic data table using divs and aria roles, and then you would need to use these display values if you wanted it to lay out like a data table. It might sound crazy, but there are systems out there which generate only divs in the body(!) I personally have had the 'joy' of working with such systems, where these exotic display values suddenly become essential.
10

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.

14 Comments

I think there are instances where using display: table; and similar CSS declarations can be quite useful for achieving complex layouts; but I agree that the html table element is almost always the preferred option for tabular data. And even the layout uses for display: table; and friends are becoming much less necessary now that we have flexbox and CSS grids.
Could you provide an example of the type of case where display: table would be preferable?
What happens when you try to display the table on a small mobile device? A downside of relying on an HTML tag (table) for layout, is that it may interfere with responsive design. Just a thought - In practice I probably wouldn't use either HTML or CSS table elements in that case, so may not be a good example.
I believe <table> is considered as content/tabular data by screen readers. That's why it is not recommended to use <table> for layout, as layout is not tabular data. Is display: table also perceived as content? If not, then you could use them for layout guilt-free. edit: Someone tested this here; it seems to be inconsistent: 456bereastreet.com/archive/201110/…
display: table is not interpreted as content, and it is therefore not semantically 'wrong' to using it for purely presentational designs. The use case is when you need a tabular layout for content which is not a table of data. In most cases, flex or grid will give a better result for this use case today, but display: table (and related table values for display) have simply been around much longer and is (of course) they're the default used by user agents to lay out data tables. If you actually need a table full of data, always use an explicit semantic table.
|
1

How to use display: table?

You use display: table the same way as any other CSS display property. You apply it to a specific HTML element (e.g., div) using CSS, then apply display: table-row / display: table-cell to its respective children. It has been well described in another answer. I'll also include snippets in the example below.

Why (and when) to use display: table?

Other answer either don't respond to this part, or state that you actually shouldn't use display: table. I don't share this perspective.

The display: table style is an extremely useful tool for expressing simple tabular layout (as opposed to presenting actual tables, understood as a way for organizing information). It's underused and has some bad reputation only because the table element used to be extremely abused for doing layout in the old days of the Web.

In my opinion, display: table should (or at very least can) be used whenever one intends to build a simple tabular layout in HTML/CSS (as opposed to presenting a semantic table), because it's the simplest tool that achieves this goal.

Example of a good use of display: table

Imagine you want to build a web application featuring a quiz game. Your intended layout is supposed to look like this:

Quiz question with four colorful answer tiles organized in a 2x2 table

Let's assume that this is a mockup shown by a UI/UX designer.

These are just four tiles with answers to a quiz question that are organized in a 2 x 2 tabular layout for fun, and similarly their coloring doesn't have any meaning.

It looks like a tabular layout to me. It's a good use case for display: table. It's not the only way to realize this layout, but it's a very reasonable one.

The crucial part of the HTML:

<div class="quiz-button-section">
    <div class="quiz-button-row">
        <button class="quiz-button">New York</button>
        <button class="quiz-button">Paris</button>
    </div>
    <div class="quiz-button-row">
        <button class="quiz-button">London</button>
        <button class="quiz-button">Berlin</button>
    </div>
</div>

Respectively, CSS:

.quiz-button-section {
    display: table;
}

.quiz-button-row {
    display: table-row;
}

.quiz-button {
    display: table-cell;
}

You can also model this tabular layout both with display: flex and display: grid. I'd argue that it's simpler with display: table. flex / grid offer great power, none of which we need in this case.

This quiz example absolutely shouldn't be modeled using the table / tr / td tags, unles you mainly target Internet Explorer 6 (or earlier) and literally have no other choice.

Example of a bad use of display: table

Imagine you were asked to present this information on a website:

Front-end web developer course table

Let's assume that this is a mockup shown by a UI/UX designer.

It's a true table. The most recommended and semantically correct way is to use the most old-school table tag. It shouldn't be modelled by explicitly setting display: table on, let's say, a div element.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.