My web GUI's layout is partially driven by CSS tables. This is mainly because I want the "cells" to have the same height under all situations without any massive headaches surrounding alignment. Overall, this approach has been very successful.
However, I do have a problem whereby the right-hand cell in the table can sometimes take a moment to render, causing the left-hand cell to briefly have 100% of the page width. This causes a noticeable "flicker" effect which, although minor, is kind of annoying. And I've decided to fix it.
Here is a vague representation of how my page works:
#tbl { display: table; width: 200px; border: 1px solid black; }
#tbl-row { display: table-row; }
#tbl-col1,
#tbl-col2 { display: table-cell; }
#tbl-col1 { width: 50px; background-color: red; }
#tbl-col2 { background-color: blue; }
<div id="tbl">
<div id="tbl-row">
<div id="tbl-col1">LHS</div>
<div id="tbl-col2">RHS</div>
</div>
</div>
All's well and good until you use your developer tools to give #tbl-col2
a display: none
directive, [I hope accurately] simulating the state of the browser's rendering engine in the moments between #tbl-col1
having been rendered, and #tbl-col2
being rendered.
Notice that #tbl-col1
immediately takes up 100% of the width of the table, despite the width I've given it. I sort of understand why this is happening: after all, I've asked the browser to make the div
s behave like tables. Still, it's undesirable here.
I tried to fix this by inserting a "spacer", hoping that without a width
it would expand to fill all the space on the right-hand side until such time as the right-hand side got rendered:
#tbl { display: table; width: 200px; border: 1px solid black; }
#tbl-row { display: table-row; }
#tbl-col1,
#tbl-spc,
#tbl-col2 { display: table-cell; }
#tbl-col1 { width: 50px; background-color: red; }
#tbl-col2 { width: 150px; background-color: blue; }
<div id="tbl">
<div id="tbl-row">
<div id="tbl-col1">LHS</div>
<div id="tbl-spc"></div>
<div id="tbl-col2">RHS</div>
</div>
</div>
As you can see by again hiding #tbl-col2
, it made not a blind bit of difference: #tbl-col1
still took the whole width of the table, rather than the 50px I allowed it.
Assuming I'd rather fix this than abandon the CSS Tables layout altogether, what can I do?
Or am I going to have to replace the layout or, even worse, take a JavaScript approach to resolving the FoUC?
What I like to do in similar cases (for example html emails) is to pre-define column widths using empty cells this way:
.tbl {
display: table;
width: 200px;
border: 1px solid black;
color: #fff;
}
.tbl-row {
display: table-row;
}
.tbl-cell {
display: table-cell;
}
.tbl-col1 {
width: 50px;
background-color: red;
}
.tbl-col2 {
background-color: blue;
}
<h3>Pre-define columns width by adding additional row</h3>
<div class="tbl">
<div class="tbl-row tbl-format">
<div class="tbl-cell tbl-col1"></div>
<div class="tbl-cell tbl-col2"></div>
</div>
<div class="tbl-row">
<div class="tbl-cell tbl-col1">LHS</div>
<div class="tbl-cell tbl-col2">RHS</div>
</div>
</div>
That formatting column is invisible if there is no content inside cells, but still it tells browser the way table should be formatted.