Reputation: 9610
I have a number of tables that have many rows. I want to initially only show the first three table rows. When a user clicks the Show/Hide link, then all hidden rows will be toggled. I have achieved this so far with CSS3 and JavaScript (see Fiddle).
CSS (only show three rows by default):
.hide tr:nth-child(n+4) {
display:none;
}
JavaScript (toggle above class to show all rows):
function ShowHide() {
var tables = document.getElementsByClassName('foo');
for(i=0; i<tables.length; i++) {
tables[i].classList.toggle("hide");
}
}
Is it possible to use the transition
functionality of CSS3 to make the rows appear slowly, rather than instantly? For example, fade in/out over 2 seconds?
I know this can be done easily in JQuery, but I'm looking for a pure CSS solution.
Upvotes: 2
Views: 2859
Reputation: 4050
best way to do this is indeed to play with height and opacity. But you can't set height on table elements (tr/td)
so here is an example on how to do it with only CSS
#expand {
/* hide the checkbox */
display: none
}
label {
/* style as a button (you can't use button inside label with for attribute) */
padding: 2px 5px;
border: 1px solid rgba(0,0,0,.2);
border-radius: 5px;
font-size: .7rem;
cursor: pointer;
}
table {
border-spacing: 0;
border-collapse: collapse;
}
table tr:nth-child(n+4)>td {
padding: 0;
}
table tr:nth-child(n+4)>td>div {
opacity: 0;
max-height: 0;
transition: all 250ms ease-in;
}
#expand:checked + table tr:nth-child(n+4)>td {
padding: 1px;
/* default */
}
#expand:checked + table tr:nth-child(n+4)>td>div {
opacity: 1;
/* try to use something just slightly above the true height */
max-height: 20px;
overflow: hidden;
transition-timing-function: ease-out;
}
<input type="checkbox" id="expand"/>
<table id="table">
<tbody>
<tr>
<td>
<div>Row 1</div>
</td>
</tr>
<tr>
<td>
<div>Row 2</div>
</td>
</tr>
<tr>
<td>
<div>Row 3</div>
</td>
</tr>
<tr>
<td>
<div>Row 4</div>
</td>
</tr>
<tr>
<td>
<div>Row 5</div>
</td>
</tr>
<tr>
<td>
<div>Row 6</div>
</td>
</tr>
<tr>
<td>
<div>Row 7</div>
</td>
</tr>
<tr>
<td>
<div>Row 8</div>
</td>
</tr>
<tr>
<td>
<div>Row 9</div>
</td>
</tr>
<tr>
<td>
<div>Row 10</div>
</td>
</tr>
</tbody>
</table>
<br/>
<label for="expand">Toggle</label>
Similar trick to hide columns:
#expand {
/* hide the checkbox */
display: none
}
label {
/* style as a button (you can't use button inside label with for attribute) */
padding: 2px 5px;
border: 1px solid rgba(0, 0, 0, .2);
border-radius: 5px;
font-size: .7rem;
cursor: pointer;
}
table {
border-spacing: 0;
border-collapse: collapse;
}
tr>*:nth-child(n+2)>div {
opacity: 0;
max-width: 0;
overflow: hidden;
white-space: nowrap;
transition: all 250ms ease-in;
}
#expand:checked+table tr>*:nth-child(n+2)>div {
max-width: 100%;
opacity: 1;
transition-timing-function: ease-out;
}
<input type="checkbox" id="expand" />
<table id="table">
<thead>
<tr>
<th>Column1</th>
<th>
<div>Column2</div>
</th>
<th>
<div>Column3</div>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div>Cell 1-1</div>
</td>
<td>
<div>Cell 1-2</div>
</td>
<td>
<div>Cell 1-3</div>
</td>
</tr>
<tr>
<td>
<div>Cell 2-1</div>
</td>
<td>
<div>Cell 2-2</div>
</td>
<td>
<div>Cell 2-3</div>
</td>
</tr>
<tr>
<td>
<div>Cell 3-1</div>
</td>
<td>
<div>Cell 3-2</div>
</td>
<td>
<div>Cell 3-3</div>
</td>
</tr>
</tbody>
</table>
<br/>
<label for="expand">Toggle</label>
Upvotes: 4
Reputation: 8589
Implementation of my 'you can use opacity to simulate a fading' comment based on your Fiddle code.
var theButton = document.getElementById("bar");
theButton.onclick = ShowHide;
function ShowHide() {
var tables = document.getElementsByClassName('foo');
for(i=0; i<tables.length; i++) {
tables[i].classList.toggle("hide");
}
}
td { border-bottom:1px solid #ccc; }
.foo tr:nth-child(n+4) {
display: block;
opacity: 1;
transition: opacity 2s ease-in-out;
}
.foo.hide tr:nth-child(n+4) {
opacity: 0;
transition: opacity 2s ease-in-out;
}
.foo.gone tr:nth-child(n+4) {
display: none;
}
<p>
<input type="button" id="bar" value="Show/Hide" />
</p>
<h2>Table 1</h2>
<table class="foo hide">
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
</table>
<h2>Table 2</h2>
<table class="foo hide">
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
</table>
Optionally you can include transitionstarts and transitionend events on the tables to toggle the .gone
class after the transition finishes to toggle their display property. That way you can retain things like positioning, since elements with opacity 0 will still take up room on the page.
Upvotes: 0