How (and why) to use CSS "display: table-cell"?
Asked Answered
O

5

75

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?

Ousel answered 24/3, 2015 at 9:56 Comment(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?Ousel
@Terry Whoops! thanks, you're totally right - I've edited the post to reflect this. I've also updated the JSFiddle.Ousel
possible duplicate of How create table only using <div> tag and CssKwasi
Read the self answering post for details on how to do this. That said, this question and several answers already exist. So make sure it's a question that no one has already asked first.Kwasi
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.Deafening
Thanks @Kwasi - 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 <table > 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.Ousel
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.Ousel
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 timeKwasi
I've just realised you can't because the other question is closed...#failKwasi
@Kwasi 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?Ousel
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-elementContrail
I'm not sure, I've written a meta post to try and get some clarification for youKwasi
Jim, if you're still around, I can reopen your question so you can move your answer into the answer section.Thrombosis
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.Kaput
Hey @BoltClock, could you reopen so that I can answer this truly fantastic question? ;-)Ousel
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 - ThanksOusel
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.Bunch
O
131

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.

Ousel answered 24/3, 2015 at 13:15 Comment(3)
FWIW, I wrote an earlier answer explaining the css table display styles, including use of table-column.Bunch
In terms of accessibility how is this different than an actual table?Impletion
Can you also include column headers?Meris
B
64

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>
Bathhouse answered 26/7, 2018 at 14:34 Comment(0)
F
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.

Fransis answered 10/10, 2018 at 22:51 Comment(12)
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.Foscalina
Could you provide an example of the type of case where display: table would be preferable?Fransis
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.Bunch
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/…Vogt
Sounds like a solution in search of a problem to me ;)Fransis
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 TablesHedvah
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 :)Fransis
This is very after the fact, but I just noticed I never really addressed "it is not recommended to use <table> 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.Fransis
How about using 'display: flex'? Like @Fransis 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.Torchbearer
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.Dunleavy
"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.Fransis
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).Chui
I
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.

Izy answered 24/3, 2015 at 13:19 Comment(1)
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.Dunleavy
P
5

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

Polaroid answered 6/8, 2022 at 9:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.