Reputation: 1730
I have built an HTML table which intermediate rows are hidden with CSS using visibility:collapse
Only the first and last rows of the table are visible by default.
In this table, there is a column on the right that was set using rowspan. This column can contain multiple lines of text.
My problem is that the whole content put in this column seems to be truncated if its height is bigger than the combined height of the table rows that are displayed by default (the first one and the last one).
.hide {
visibility: collapse
}
body {
padding: 2rem;
}
<table border="1">
<tr>
<td>A1</td>
<td>A2</td>
<td rowspan="3">Text 1<br>Text 2<br>Text 3<br>Text 4<br>Text 5<br>Text 6</td>
</tr>
<tr class="hide">
<td>B1</td>
<td>B2</td>
</tr>
<tr>
<td>C1</td>
<td>C2</td>
</tr>
</table>
What should I change in the CSS to get all the lines of "Text" of the rowspan cell displayed instead of being truncated? JavaScript cannot be used.
Upvotes: 6
Views: 1693
Reputation: 81
.hide {
position: absolute;
left: -999em;
}
body {
padding: 2rem;
}
<table border="1">
<tr>
<td>A1</td>
<td>A2</td>
<td rowspan="3">Text 1<br>Text 2<br>Text 3<br>Text 4<br>Text 5<br>Text 6</td>
</tr>
<tr class="hide">
<td>B1</td>
<td>B2</td>
</tr>
<tr>
<td>C1</td>
<td>C2</td>
</tr>
</table>
display: none;
Element is removed from the normal flow and hidden; the space it occupied is collapsed.
Content is ignored by screen readers.
So, if you want to hide it but make it visible for screen readers you can use the above code in my opinion.
Upvotes: 2
Reputation: 5281
Digging into this problem it became clear that the problem description and the way the <td rowspan="3">
is constructed in the example puts everyone off track. Including me...
The answer, after some utter frustrating hours, is actually quite simple:
the OP is trying to force 6 rows of text into a 3 rows space because of the 5 <br>
s. There is just not room enough for the content, so the cell overflows. The rowspan should not read 3
, but 6
!
Once the room issue has been revealed, one solution is to create more table rows to accommodate for the 6 rows and make arrangements for using a scrollbar, while clipping the overflowing cell when there are less than 6 rows available in the table.
On page table: The Table element: Displaying large tables in small spaces MDN defines a table as table { display: block; overflow: auto }
and introduces tbody { white-space: nowrap }
to enable scrolling of table content.
I created some commented code showing the original and solution 1 with simple toggles for class .hide
and additional rows.
Do I like it? No, far from, but this is how the table mechanism appears to work. I don't think it is a bug, just something we need to work around...
UPDATE
In reply to @MaxiGui's fair point below, me not honoring the OPs "What should I change in the CSS to get all the lines of "Text" of the rowspan cell displayed instead of being truncated" question, I added another solution.
Added solution 2 shows the OP original code, but simply toggles class .hide
between display: none
/table-row
instead of visibility: collapse
/visible
.
Because if all size properties of an element have to be set to 0
(zero, nullified) to mimick display: none
, it is far less complicated to use the display
property instead of visibility
to hide a table row.
FYI, the OP did not explicitely mention the requirement to retain visibility
...
/* original code */
body { padding: 2rem }
.hide { visibility: collapse }
/* solution 1 */
.solution {
display: inline-block;
overflow: auto; /* to show scrollbars when required */
}
/*
MDN excerpt
(https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table#displaying_large_tables_in_small_spaces)
When looking at these styles you'll notice that table's display property
has been set to block. While this allows scrolling, the table loses some
of its integrity, and table cells try to become as small as possible.
To mitigate this issue white-space has been set to nowrap on the <tbody>.
*/
.solution tbody { white-space: nowrap }
.solution td {
overflow: hidden; /* clips excess content */
vertical-align: top; /* moves content to top of cell */
}
#tgl-line ~ .solution {
min-width: calc(6.75rem + 17px); /* create some room for content and scrollbar */
/* just for demo, change to max-width when .solution { display: block } */
}
#tgl-line:checked ~ table .hide { visibility: visible } /* both tables */
#tgl-line:checked ~ .solution { min-width: 6.75rem } /* solution only */
#tgl-rows ~ .solution .rows { display: none } /* additional rows hidden */
#tgl-rows:checked ~ .solution .rows { display: table-row } /* in view... */
/* solution 2 */
.hide-d { display: none } /* alt classname for solution 2 */
#tgl-line:checked ~ table .hide-d { display: table-row }
/* eye-candy */
h2 { margin-top: 4rem }
<input id ="tgl-line" type="checkbox">
<label for="tgl-line">toggle .hide (all examples)</label>
<h2>original: toggle 'visibility' (rowspan=3)</h2>
<table border="1">
<tr>
<td>A1</td>
<td>A2</td>
<td rowspan="3">Text 1<br>Text 2<br>Text 3<br>Text 4<br>Text 5<br>Text 6</td>
</tr>
<tr class="hide">
<td>B1</td>
<td>B2</td>
</tr>
<tr>
<td>C1</td>
<td>C2</td>
</tr>
</table>
<h2>solution 1: toggle 'visibility' (rowspan=6)</h2>
<input id ="tgl-rows" type="checkbox">
<label for="tgl-rows">toggle rows</label>
<br><br>
<table class="solution" border="1">
<tbody>
<tr>
<td>A1</td>
<td>A2</td>
<td rowspan="6" class="special">Text 1<br>Text 2<br>Text 3<br>Text 4<br>Text 5<br>Text 6</td>
</tr>
<tr class="hide">
<td>B1</td>
<td>B2</td>
</tr>
<tr>
<td>C1</td>
<td>C2</td>
</tr>
<tr class="rows">
<td>D1</td>
<td>D2</td>
</tr>
<tr class="rows">
<td>E1</td>
<td>E2</td>
</tr>
<tr class="rows">
<td>F1</td>
<td>F2</td>
</tr>
</tbody>
</table>
<h2>solution 2: toggle 'display' (rowspan=3)</h2>
<table border="1">
<tr>
<td>A1</td>
<td>A2</td>
<td rowspan="3">Text 1<br>Text 2<br>Text 3<br>Text 4<br>Text 5<br>Text 6</td>
</tr>
<tr class="hide-d">
<td>B1</td>
<td>B2</td>
</tr>
<tr>
<td>C1</td>
<td>C2</td>
</tr>
</table>
.
Upvotes: 3
Reputation: 438
You can scroll your table data, Look at the following code:
.hide {
visibility: collapse
}
body {
padding: 2rem;
}
.table-data {
overflow-y: auto;
}
.table-data::-webkit-scrollbar {
display: none;
}
<table border="1">
<tr>
<td>A1</td>
<td>A2</td>
<td rowspan="3" class="table-data">Text 1<br>Text 2<br>Text 3<br>Text 4<br>Text 5<br>Text 6</td>
</tr>
<tr class="hide">
<td>B1</td>
<td>B2</td>
</tr>
<tr>
<td>C1</td>
<td>C2</td>
</tr>
</table>
Upvotes: 0
Reputation: 133
Hello if you need display your content properly, you should to add a class and make this class width: auto; overflow: auto; height: auto; I recommend to you apply this ->
.hide {
visibility: collapse
}
body {
padding: 2rem;
}
.meta {
width: auto;
overflow: auto;
height: auto;
}
<table border="1">
<tr>
<td>A1</td>
<td>A2</td>
<td class="meta" rowspan="3">Text 1<br>Text 2<br>Text 3<br>Text 4<br>Text 5<br>Text 6</td>
</tr>
<tr class="hide">
<td>B1</td>
<td>B2</td>
</tr>
<tr>
<td>C1</td>
<td>C2</td>
</tr>
</table>
but it would depend what you are trying to do.
Upvotes: 0
Reputation: 21
You can use position: absolute
and top: -1000000px
By using this code you can achieve your required output.
.hide {
position: absolute;
top: -100000px;
}
body {
padding: 2rem;
}
<table border="1">
<tr>
<td>A1</td>
<td>A2</td>
<td rowspan="3">Text 1<br>Text 2<br>Text 3<br>Text 4<br>Text 5<br>Text 6<br>Text 7<br>Text 8<br>Text 9</td>
</tr>
<tr class="hide">
<td>B1</td>
<td>B2</td>
</tr>
<tr>
<td>C1</td>
<td>C2</td>
</tr>
</table>
I hope this will resolve your issue.
Upvotes: 0
Reputation: 6358
If you really need, you can always add line-height: 0;
to .hide
as below:
.hide {
visibility: collapse;
line-height: 0;
}
This solution has been given here: CSS: "visibility: collapse" still takes up space
I would still recommend to apply the visibility:collapse
on the td
as it would let more space to the rowspan
cell as you can see the diff between the 2 tables.
I still prefer the use of display:none;
but it would depend what you are trying to do.
#hide .hide {
visibility: collapse;
line-height: 0;
}
body {
padding: 2rem;
}
/* SECOND table - collapse on td */
#td-hide .hide > td{
visibility: collapse;
line-height: 0;
height:0;
border: 0;
padding:0;
margin:0;
}
.container{
display:flex;
}
.container > div{
margin:0 auto;
}
<div class="container">
<div>
<h3>visibility: collapse on tr</h3>
<table id="hide" border="1">
<tr>
<td>A1</td>
<td>A2</td>
<td rowspan="3">Text 1<br>Text 2<br>Text 3<br>Text 4<br>Text 5<br>Text 6</td>
</tr>
<tr class="hide">
<td>B1</td>
<td>B2</td>
</tr>
<tr>
<td>C1</td>
<td>C2</td>
</tr>
</table>
</div>
<!-- Second table with collapse on td -->
<div>
<h3>visibility: collapse on td</h3>
<table id="td-hide" border="1">
<tr>
<td>A1</td>
<td>A2</td>
<td rowspan="3">Text 1<br>Text 2<br>Text 3<br>Text 4<br>Text 5<br>Text 6</td>
</tr>
<tr class="hide">
<td>B1</td>
<td>B2</td>
</tr>
<tr>
<td>C1</td>
<td>C2</td>
</tr>
</table>
</div>
</div>
Upvotes: 1
Reputation: 61
I think it's better to use display:none;
or visibility:hidden;
.
Or use overflow:auto;
on TD, but then you will get a scrollbar jsfiddle
About visibility:collapse;
check out this post from css-tricks
.hide{
/* Using this, will mess up everything */
/* visibility:collapse; */
/* Using this, will give you something where the middle row is hidden */
/* visibility:hidden; */
/* display none works the best */
display: none;
}
<table border="1">
<tbody>
<tr>
<td>A1</td>
<td>A2</td>
<td rowspan="3">Text 1<br>Text 2<br>Text 3<br>Text 4<br>Text 5<br>Text 6</td>
</tr>
<tr class="hide">
<td>B1</td>
<td>B2</td>
</tr>
<tr>
<td>C1</td>
<td>C2</td>
</tr>
</tbody>
</table>
Upvotes: 6