According to the documentation we can use visibility: collapse
on a <col />
element to collapse or fold all associated columns.
But (in Chrome and Edge) I noticed that some elements remain visible, floating somewhere along the area that the collapsed columns would occupy.
I could narrow it down to elements with position: absolute
or position: relative
.
This seems to be a bug in Chrome and Edge (both show this behavior).
In Firefox no unexpectedly visible artifacts remain.
const toggle = () => {
const table = document.querySelector("#my-table");
table.classList.toggle("collapsed");
};
.table.collapsed .collapsible-column {
visibility: collapse;
}
.oops {
position: relative;
}
<table id="my-table" class="table">
<colgroup>
<col span="2" class="collapsible-column" />
<col span="2" class="static-column" />
</colgroup>
<thead>
<tr>
<th scope="col">col 1<br /><span class="oops">oops</span></th>
<th scope="col">col 2</th>
<th scope="col">col 3</th>
<th scope="col">col 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>cell 1,1</td><td>cell 2,1</td><td>cell 3,1</td><td>cell 4,1</td>
</tr>
<tr>
<td>cell 1,2</td>
<td>cell 2,2<br /><span class="oops">oops</span></td>
<td>cell 3,2</td>
<td>cell 4,2</td>
</tr>
</tbody>
</table>
<button onclick="toggle()">toggle columns</button>
Is this a known bug or limitation? Do you know any workarounds? How can I ensure to also hide those elements when the column is collapsed?
Addendum: hitherto discovered workarounds
content from table cells with
overflow: hidden
does not leak from collapsed columnsth, td { overflow: hidden; }
But this is only viable if all content is meant to always stay inside the cell boundaries, and quite useless for my use case which involves an absolute positioned dropdown that needs to draw outside the cell boundaries. We could enable visible overflow for as long as the cell is interacted with via
:hover
and:focus-within
but this is not a clean solution and not watertight: when the columns are collapsed while the focus is within a cell the respective content does still leak.th:focus-within, th:hover, td:focus-within, td:hover { overflow: visible; }
We could add
.collapsible-cell
classes to all cells that are part of collapsible coulmns and explicitly switch their content's visibility accordingly. But this approach defeats the purpose of the<col />
visibility feature, requires markup changes, and creates an explicit dependency between cell markup and colgroup definitions..table.collapsed .collapsible-cell > * { display: none; }
visibility: collapse;
only work on table elementon firefox it's look like element inside td element are implicitly considered as part of the table element
In chrome and edge it's not the case and the
position: relative
"break" this consideration and make .oops is not considered as a table elementone workaround can be to explicitly set .oops to position
table-row
ortable-cell
to let this behavior work on all browserIf you want to keep position: relative on chrome and edge browser you will have to use
display: none
that hide non table element