0

I have build a result page for a calculation. It's basically a CSS-grid in a DIV. The grid has three columns. In each column there are tiles (divs) which contain tables (which show the results).

In JavaScript I calculate the result tables and assign them to the tables. There is an outermost div where I set display to "table".

Here is the problem: Some browsers on some computers present a long empty page. At the very end I can see a bit of tables, the rest is clipped.

This may happen at the beginning where build the page or when I replace a table by a newly calculated table.

For now I found an unsatisfying work around: Before any assignments to div.innerHtml I set display of the outermost div to none. After the assignments I set it back to table after a setTimeout of 0.5 sec. Then the page is built properly.

It looks like that after the assignments some time is needed to build the internal DOM structure but I don't know any event to wait for.

Here is the essence of the html structure:

<div style="display: table">
  <div style="display: grid; grid-template-areas: 'left center right';">
    <div style="grid-area: left">
      <div id="result_table0"></div>
      <div id="result_table1"></div>
    </div>
    <div style="grid-area: center">
      <div id="result_table2"></div>
      <div id="result_table3"></div>
    </div>
    <div style="grid-area: right">
      <div id="result_table4"></div>
      <div id="result_table5"></div>
    </div>
  </div>
</div>

The Javascript assignments of the tables looks similar like that:

// calculation of the table
let my_result_table = '<table><tr><td>xxx</td><td>yyy</td></tr></table>';

// assignment to the div
document.getElementById('result_table0').innerHTML = my_result_table;

Any ideas what's going wrong here?

Flo
  • 19
  • 6
  • is there a need for display table? if you use that then it's in effect turning that tag into a table tag so anything but a display table-row child will cause issues – Pete Nov 15 '22 at 16:23
  • 1
    `innerHtml` doesn’t exist. You mean [`innerHTML`](//developer.mozilla.org/en/docs/Web/API/Element/innerHTML). Is your ` – Sebastian Simon Nov 15 '22 at 16:24
  • 1
    Also id attribute values must be **unique**. There can be only one "result_table0". – Pointy Nov 15 '22 at 16:26
  • My understanding of `display: table` css is that it is used in conjunction with `display: table-row` and `display: table-cell` for child and grand-child elements respectively. You seem to be combining `display: table` with `grid` display items and I'm not sure this approach will work reliably. I would either define a grid for the table and its immediate descendents (equivalent to table rows) or stick with `table`, `table-row` and `table-data` for the outer div and its descendents. – Dave Pritlove Nov 15 '22 at 19:38
  • My mistake in this post: I corrected the ids. Plus innerHTML. – Flo Nov 15 '22 at 20:42
  • I found display: table useful because it made everything inside as small as necessary. display: block uses the whole page width. I made this decision long time ago and have never questioned it. Now I realized that this strange effect is not happening when I use display: block. So the problem is solved and I have to deal with the width issue in a different way. – Flo Nov 15 '22 at 21:18

2 Answers2

1

Some pointers on using css display: table/table-row/table-cell or display: grid to render table-like structures in html

I've prepared some examples in the following snippet to show how css table and grid can be used.

display: table can be applied to an outer container, its children elements (typically intended as 'rows' in a normal <table><tr><td>... structure) are given the style attribute display: table-row. In turn the children of the rows (grandchildren of the table, analagous to td elements in regular table parlance) are given the style attribute display: table-cells.

In some examples below, I show how the normal hierarchy can be changed, for example to display 'rows' side by side or 'cells' above-and-below each other.

I also include a simple effective grid styling where cells can be sized very easily with short simple grid-templates.

Generally speaking, use one or the other as the table options style the element they are attached to while grid specifies how child items will be placed. Grid has an added advantage of allowing every placed item to be set to different display types, allowing a grid item to be a grid container, a flex-box or whatever best suits styling of that item. Grid is also very easy to size if column and row templates are included for the grid container.

/* rules for table div, its children (rows) and its granchildren (cells)*/

.table {
  display: table;
}
.table>div {
  display: table-row;
}
.table>div>div {
  display: table-cell;
}


div {
  border: 1px solid black;
  min-width:30px;
  min-height:10px
}

h2 {
  font-size: 18px;
  margin-top: 50px;
  margin-bottom: 0;
}
<h2>table, table-row, table-cell values of style display attribute </h2>
<p>1) divs formatted using display: [table/table-row/table-cell] set using inline style attributes </p>
<div style="display: table;">
    <div style="display: table-row;">
      <div style="display: table-cell;">1</div>
      <div style="display: table-cell;">2</div>
    </div>
    <div style="display: table-row;">
      <div style="display: table-cell;">3</div>
      <div style="display: table-cell;">4</div>
    </div>
    <div style="display: table-row;">
      <div style="display: table-cell;">5</div>
      <div style="display: table-cell;">6</div>
    </div>    
</div>

<p>2) divs formatted using display: [table/table-row/table-cell] set using stylesheet css rules applied to class attribute of outer div and its descendents </p>
<div class="table">
    <div>
      <div>1</div>
      <div>2</div>
    </div>
    <div>
      <div>3</div>
      <div>4</div>
    </div>
    <div>
      <div>5</div>
      <div>6</div>
    </div>    
</div>


<h2>display: grid example: </h2>
<p>divs formatted using display: grid with optional cell sizing within the row and column templates.</p>
<div style="display: grid; grid-template-rows: 30px 50px 30px; width: 50%;">
    <div style="display: grid; grid-template-columns: 1fr 2fr;">
      <div>1</div>
      <div>2</div>
    </div>
    <div style="display: grid; grid-template-columns: 1fr 2fr;">
      <div>3</div>
      <div>4</div>
    </div>
    <div style="display: grid; grid-template-columns: 1fr 2fr;">
      <div>5</div>
      <div>6</div>
    </div>
    
</div>

<h2> display: table/table-cell to place 'rows' side-by-side</h2>
<p>This example uses display: table-cell for both the children and grand-children of the table. It allows the children (normally considered rows) to be placed side-by-side. table-cells make the div behave as an inline-block</p>
<div style="display: table">

    <div style="display: table-cell">
      <div style="display: table-cell">1</div>
      <div style="display: table-cell">2</div>
    </div>
    <div style="display: table-cell">
      <div style="display: table-cell">3</div>
      <div style="display: table-cell">4</div>
    </div>
    <div style="display: table-cell">
      <div style="display: table-cell">5</div>
      <div style="display: table-cell">6</div>
    </div>

</div>

<h2>putting table-rows inside  (some) table-cells</h2>
<p>This example applies table-cell to the children of the table (normally considered rows) to place them side-by side. The grandchildren with display set to table-cell are placed side-by-side within the side-by-side children except for the middle child which has its children styled as table-rows (forcing them onto separate lines). Table-rows gives an inline-block type display to divs.</p>

<div style="display: table">

    <div style="display: table-cell">
      <div style="display: table-cell">1</div>
      <div style="display: table-cell">2</div>
    </div>
    <div style="display: table-cell">
      <div style="display: table-row">3</div>
      <div style="display: table-row">4</div>
    </div>
    <div style="display: table-cell">
      <div style="display: table-cell">5</div>
      <div style="display: table-cell">6</div>
    </div>

</div>

<h2>above-and-below table-rows inside table-cells</h2>
<p>The final example treats the children (usually rows) as table-cells, displaying them side-by-side but its children are displayed as table-rows, causing them to stack on top of each other </p>
<div style="display: table">

    <div style="display: table-cell">
      <div style="display: table-row">1</div>
      <div style="display: table-row">2</div>
    </div>
    <div style="display: table-cell">
      <div style="display: table-row">3</div>
      <div style="display: table-row">4</div>
    </div>
    <div style="display: table-cell">
      <div style="display: table-row">5</div>
      <div style="display: table-row">6</div>
    </div>

</div>
Dave Pritlove
  • 2,601
  • 3
  • 15
  • 14
  • Great, now I know about display:table. I tried it and it worked in a way that the result was shown. However, my real application is not as homogenous as the example I stated. I basically need three columns, there are 2-3-3 tiles (for now, may change in future) in the columns, each tile is different in size. This somehow resulted in column 2 and 3 having a bit of a vertical offset. So I kept the grid and set the outermost div to display:flex which makes it as small as possible. That's perfect now. – Flo Nov 16 '22 at 10:22
  • I also tried to put the grid into three times wrapper: table -- table-row -- table-cell. But then I had the same problem with sometimes not having rendered the web page (i.e.: win10/Firefox while it's working mostly with GNU/Linux/Firefox). – Flo Nov 16 '22 at 10:24
  • How did you try specifying the grid inside the table-cell? `table-cell` is a `display` attribute value affecting the positioning of *the element is is applied to* wheras `grid` is a `display` attribute value affecting the positioning of *the contents of the element it is applied to*. So, the table element cannot have both `table-cell` and `grid` applied to its css `display` property. I would be inclined to use grid for most of the layout and try the table family on the inner-most table. – Dave Pritlove Nov 16 '22 at 13:29
  • I tried two things: .) `
    3 divs as three columns` which resulted in not getting rendered correctly. .) I omitted the first three divs and Instead of the
    I wrote the following: `
    x 3` where I got column 2 and 3 with a slight vertical offset which I couldn't explain.
    – Flo Nov 17 '22 at 16:14
  • Basically I did it the way you suggested. I left the grid outside (with a flex-div-wrapping to make it as small as possible) and then inside there are the tables (where I used the old style but I don't see a reason to change it to display: table).
    – Flo Nov 17 '22 at 16:18
  • ok, sounds like progress. Is it now rendering as you wanted? – Dave Pritlove Nov 17 '22 at 16:32
  • 1
    Yes, the problem seems to be solved. Many thanks! – Flo Nov 17 '22 at 22:35
0

Use display: flex (or block) instead of display: table .

Flo
  • 19
  • 6