How to Animate Toggling of Table Rows

How to animate toggling of table rows?

As table row/cell don't respect a height smaller than its content we need to use an inner div, we can't animate display and we can't animate a height set to auto, so I here show a solution using max-height.

The trick is to give max-height a value high enough to enable the highest content.

$('button').on('click', function() {

$('tr:nth-child(2)').toggleClass('active');

});
table {

border-collapse: collapse;

}

tr {

background: #eee;

border-bottom: 1px solid #fff;

}

tr, td {

padding: 0;

}

tr td div {

max-height: 0;

padding: 0 10px;

box-sizing: border-box;

overflow: hidden;

transition: max-height 0.3s, padding 0.3s;

}

tr.active td div {

max-height: 100px;

padding: 10px 10px;

transition: max-height 0.6s, padding 0.6s;

}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>

<button type="button">Toggle</button>

<table>

<tbody>

<tr class="active">

<td><div>Row 1</div></td>

<td><div>...</div></td>

<td><div>...</div></td>

</tr>

<tr>

<td><div>Row 2</div></td>

<td><div>...</div></td>

<td><div>...</div></td>

</tr>

<tr class="active">

<td><div>Row 3</div></td>

<td><div>...</div></td>

<td><div>...</div></td>

</tr>

</tbody>

</table>

Using CSS transition and class toggle to show/hide table rows

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>

Collapse entire table on click with animation

You don't really need to do it with keyframe animation.

You could do it just by adding a transition rule to the table element, like this:

table {
height: 100%;
display: block;
overflow: hidden;
transition: height 2s ease-in;
}

.collapsed {
height: 40px;
}

What this does, is tell the browser to transition the height of the table from 100% to 40px and vice cersa over a duration of 2s with an ease-in function

For more info you can read the entry about the transition property at MDN

Cheers

UPDATE:

In your current setup I suppose the parent of the table element does not have a strictly defined height.

The way the percentage based height works is like this: The element gets the 100% of its parent height.

However when you do not specify a height for the parent, be it in px, em, rem, vh or what have you, the child with height: 100% is like having height: auto. Reference

And here is the actual problem: You cannot transition from auto to any other value, like %, px etc.

You can only transition from one defined value (!== auto) to any other defined value. e.g. from px to rem, etc

And this is why your transition is not working.

See this fiddle
I made. Play with the #cont element's height and see what happens.

So, in short: You will either have to give a strict height to your table, or, if you want to keep it percentage based, give a strict height to its parent element.

Vue - how to animate table row change

You could either look at transitioning the state as @craig_h suggests or perhaps just set up a regular javascript event that watches for animation end.

To utilise the second method you could add a new param changed: false to each rows data, then set this to true when it is changed. This could then add a class to the row of 'changed'. Then have your CSS fire an animation when the row has the 'changed' class. Now all you need to do is listen for the 'animationend' event on that row and reset the changed param to false. Something like:

html - row element

<table>
<tr
ref="rows"
:class="{ changed: row.changed }"
v-for="(row, index) in rows">
<td><input v-model="row.title" type="text"></td>
<td>
<button @click="saveRowEdits(index)">save</button>
</td>
...

component

data () {
return {
rows: [
{ title: 'foo', changed: false },
{ title: 'bar', changed: false },
],
...
}
},
methods: {
saveRowEdits (index) {

// get the rows DOM el
const row = this.$refs.rows[index]

// watch for animationend
const callback = () => {
row.removeEventListener("animationend", callback);
this.rows[index].changed = false
}

row.addEventListener("animationend", callback, false)

// update param
this.rows[index].changed = true

},
...

CSS

row.changed {
animation: changed-row 1s ...

How can I animate a table row with a single column that spans multiple columns?

Nevermind. I figured it out. It has to do with the display CSS property. Angular's ngShow directive applies display: none to the element when it hides it. This property would make the collapse animation not work at all. To get around that I applied display: block !important to the animation selectors (I've done this many times in the past so I didn't think twice about it). Table rows are not displayed with display: block, they need to be set to display: table-row !important.

Once I changed my animation rules to this:

.animate-slide-down.ng-hide-add,
.animate-slide-down.ng-hide-remove.ng-hide-remove-active {
transition: 1s ease-out all;
transform: scale(1);
transform-origin: right;
line-height: 1.42857;
display: table-row !important;
}

.animate-slide-down.ng-hide-remove,
.animate-slide-down.ng-hide-add.ng-hide-add-active {
transition: 1s ease-out all;
transform: scale(0);
transform-origin: left;
line-height: 0;
display: table-row !important;
}

That solved the issue :)

Sample Image

Make an animation for collapsing tr with Bootstrap

The answer that was given wasn't actually providing the correct solution. It was a solution, but when you need to keep the tr and td elements this solution is more complete

The fact is that there is no way in bootstrap to animate tr td elements.
What you can do is instead of toggling the tr or td is create a div or span element in which you are going to add all of your content and then there animate the element.

As you can see it looks the same as if you had an actual table

<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />

<script src="https://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript" ></script>

<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" type="text/javascript" ></script>

<table class="table">

<tr class="content-row" id="content_1">

<td><a id="more_1" class="more" role="button" data-toggle="collapse" href="#additional_row1" aria-expanded="false" aria-controls="collapseExample">More</a>

</td>

</tr>

<tr>

<td class="additional-row-td">

<div class="collapse additional-row" id="additional_row1">Content</div>

</td>

</tr>

</table>

How to Use slideDown (or show) function on a table row?

Animations are not supported on table rows.

From "Learning jQuery" by Chaffer and Swedberg


Table rows present particular
obstacles to animation, since browsers
use different values (table-row and
block) for their visible display
property. The .hide() and .show()
methods, without animation, are always
safe to use with table rows. As of
jQuery version 1.1.3, .fadeIn() and
.fadeOut() can be used as well.


You can wrap your td contents in a div and use the slideDown on that. You need to decide if the animation is worth the extra markup.



Related Topics



Leave a reply



Submit