69

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 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;
  2. 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?

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Jim
  • 2,243
  • 2
  • 13
  • 17
  • @N-A-T-H Also talking about posting answers: Should I have posted this as a question first and then posted the answer myself? Also - Where is the "answer section" and how can I move this there? – Jim Mar 24 '15 at 10:11
  • @Terry Whoops! thanks, you're totally right - I've edited the post to reflect this. I've also updated the JSFiddle. – Jim Mar 24 '15 at 10:17
  • possible duplicate of [How create table only using
    tag and Css](http://stackoverflow.com/questions/3053205/how-create-table-only-using-div-tag-and-css)
    – Liam Mar 24 '15 at 10:19
  • Read the [self answering post for details on how to do this](http://stackoverflow.com/help/self-answer). That said, this question and several answers already exist. So make sure it's a question that no one has already asked first. – Liam Mar 24 '15 at 10:22
  • 11
    I don't think this deserves downvotes. It should've simply been closed, and yet there's only one vote-to-close. Considering Jim is new here, that's quite harsh. (Therefore: +1) StackExchange as a whole is meant to ask questions, and to receive answers. You should always follow that format. If you want to answer your own question, you can - if you follow to proposed format: First ask the question, and then provide the answer in the answer section. But to be sure you are not asking something that's been asked before, use the search box in the upper right. – Bram Vanroy Mar 24 '15 at 10:24
  • 1
    Thanks @Liam - I'll check out the self answering post. I think I did find that question while I was trying to figure out the dispaly: table; code, but was thrown a bit by the (what I realise now is unnecessarily confusing code). The inclusion of the original code in my post may help others - but just give the word and I'll delete this post. Oh dear! Foiled! _If you have more than 15 reputation and already know the answer, click the checkbox that says "Answer your own question" at the bottom of the Ask Question page._ I guess it doesn't cater for us news.
    – Jim Mar 24 '15 at 10:28
  • 1
    Thanks @BramVanroy, I felt that way too, but willing to bow to the wishes of those that have been here longer than I. Also, I only put up the info once I had the answer. As I had a tough time getting the answer, I wanted to save others the hassle, and felt it silly posting "how do I do this?" when I already had the answer. – Jim Mar 24 '15 at 10:32
  • I would be tempted to add your answer to the linked question I flagged as a duplicate? The answer itself seems detailed and correct and is potentially better than the existing answers on the other question. It's just been posted incorrectly this time – Liam Mar 24 '15 at 10:56
  • I've just realised you can't because the other question is closed...#fail – Liam Mar 24 '15 at 10:58
  • 1
    @Liam So... should I cut the answer out, reword this to be a question, and then "Answer it" with the cut bit, or should I just leave it? – Jim Mar 24 '15 at 11:06
  • 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: https://css-tricks.com/fixing-tables-long-strings/ or https://css-tricks.com/complete-guide-table-element/ – FelipeAls Mar 24 '15 at 11:45
  • I'm not sure, I've written a [meta post to try and get some clarification for you](http://meta.stackoverflow.com/questions/288594/self-answering-question-posted-incorrectly-how-does-user-correct) – Liam Mar 24 '15 at 11:50
  • 1
    Jim, if you're still around, I can reopen your question so you can move your answer into the answer section. – BoltClock Mar 24 '15 at 12:42
  • Yeah, cut out the answer, turn the question into a question, then hit the flag link and select Other. Say you want this reopened so you can add the answer below. –  Mar 24 '15 at 12:55
  • Hey @BoltClock, could you reopen so that I can answer this truly fantastic question? ;-) – Jim Mar 24 '15 at 12:59
  • Thanks for your help guys, It's always so much fun when people collaborate to help the little guy (especially if it's the little guy that's also trying to help ;-) ). Also: OP is indeed [now happy](http://meta.stackoverflow.com/questions/288594/self-answering-question-posted-incorrectly-how-does-user-correct) - Thanks – Jim Mar 24 '15 at 13:15
  • 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`. – ToolmakerSteve Apr 30 '19 at 23:34

5 Answers5

126

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.

Mariusz Pawelski
  • 25,983
  • 11
  • 67
  • 80
Jim
  • 2,243
  • 2
  • 13
  • 17
62

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>
Dmitriy Sintsov
  • 3,821
  • 32
  • 20
12

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.

machineghost
  • 33,529
  • 30
  • 159
  • 234
  • 2
    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. – Nathan Arthur Nov 05 '18 at 15:34
  • 1
    Could you provide an example of the type of case where `display: table` *would* be preferable? – machineghost Nov 05 '18 at 21:50
  • 2
    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. – ToolmakerSteve Apr 30 '19 at 23:27
  • 3
    I believe `` is considered as content/tabular data by screen readers. That's why it is not recommended to use `
    ` 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: https://www.456bereastreet.com/archive/201110/using_displaytable_has_semantic_effects_in_some_screen_readers/
    – smerg Jul 24 '19 at 06:42
  • Sounds like a solution in search of a problem to me ;) – machineghost Jul 25 '19 at 01:41
  • Nowadays those like me that are forced to use Ionic framework, have to build the table with DIV's and Displays since this framework does not have Table element but list (ion-list) and items (ion-item). There is not much options, so you have to go back to the old good days of Tables – Rafael Munoz Oct 07 '19 at 08:26
  • If in Ionic you truly "have to build the table with DIV's", that sounds awful (and against how the web is supposed to work). I can't even imagine what that must do to screen readers, for instance, and I've never heard of any other framework needing to do that. **Maybe** they have a good reason, but if it's true it sounds to me like Ionic's devs just couldn't be arsed to properly use HTML, so they make everyone use one element, which (anywhere else) would be a terrible practice. But I never want to criticize a dev decision unless I know the details, so I'll try not to judge them :) – machineghost Oct 07 '19 at 15:53
  • 1
    This is very after the fact, but I just noticed I never really addressed "it is not recommended to use for layout, as layout is not tabular data." That is *very* true ... and it's **just about as bad** to use table `display` styles to "lay out" non-tabular content. The whole point of the idea is not "table tags are evil", it's "use the appropriate tool for the job". You should use floats, absolute positioning, etc. for layout. If you want a grid-like layout, use flexbox ... *not* actual tables *or* table styles.
    – machineghost Feb 08 '20 at 19:18
  • How about using 'display: flex'? Like @machineghost mentioned, flexbox is used more widely today and is more useful for more cases because it is more flexible for moving and rearranging the data in your table/grid. – Clare12345 May 04 '20 at 19:50
  • `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. – brennanyoung Jun 11 '20 at 08:58
  • "The use case is when you need a tabular layout for content which is not a table of data." - When is that use case exactly? I'm having a hard time imagining the conditions under which you'd need that. – machineghost Jun 11 '20 at 19:34
  • Now that we have `grid` and `flex`, it's time to revert to only using `float` for "floaty things" - drop caps, illustrated words, wrapping text around images etc - which was, as I understood it, the original intent. The de facto use of `float` for major layout directives seems like a hack, with hindsight. I'd argue that `display: table` is the expressive choice for boxy/columny layouts wherever `flex` and `grid` are not (well-)supported (such as some smart TVs, embedded systems etc). – Simon Dell Jul 13 '22 at 15:47
8

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.

The Spooniest
  • 2,863
  • 14
  • 14
  • 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. – brennanyoung Jun 11 '20 at 10:14
3

I don't have 10 years of web dev., but only a year or so and I have quickly came around a use case that does not work with table elements and work with and CSS table : forms. Forms and tables do not go well together. A form is not allowed to be a child of a table element. So, to comment previous comment : divs and CSS table are useful at least when you want forms into table. Jean-yves