JSFiddle - React, Tailwind, and code Playground

by _sir

HTML

<h1>
 Table animations
</h1>
<h2>
Fade Example
</h2>
<p>
Immediate height snap, contents fade in. Requires no DOM manipulation.
</p>
<table id="t1">
<tr>
  <th>Name</th>
  <th>Word</th>
</tr>
<tr>
  <td>Anastasia</td>
  <td>Antidisestablishmentarianism</td>
</tr>
<tr>
  <td>Betty</td>
  <td>Balaclava</td>
</tr>
<tr>
  <td>Cassius</td>
  <td>Cello</td>
</tr>
<tr class="toggle hidden">
  <td>Dan</td>
  <td>Diplodocus</td>
</tr>
<tr class="toggle hidden">
  <td>Ester</td>
  <td>Extraneous</td>
</tr>
<tr class="">
  <td>Frank</td>
  <td>Food</td>
</tr>
</table>

<button id="b1">Toggle</button>

<h2>
 Animate Contents
</h2>
<p>
Slide in. Requires DOM changes to add divs or divs must be in the template. Still does not account for cell padding... working on animating CSS padding.
</p>
<table id="t2">
<tr>
  <th>Name</th>
  <th>Word</th>
</tr>
<tr>
  <td>Abel</td>
  <td>Antidisestablishmentarianism</td>
</tr>
<tr>
  <td>Betty</td>
  <td>Balaclava</td>
</tr>
<tr>
  <td>Cassius</td>
  <td>Cello</td>
</tr>
<tr class="toggle hidden">
  <td>Dan</td>
  <td>Diplodocus</td>
</tr>
<tr class="toggle hidden">
  <td>Ester</td>
  <td>Extraneous</td>
</tr>
<tr class="">
  <td>Frank</td>
  <td>Food</td>
</tr>
</table>

<button id="b2">Toggle</button>

CSS

table {
  border-collapse: collapse;
}

button { 
  padding: 1em 2em;
  margin: 1em;
}

th, td {
  padding: .25em .75em;
  border: 1px solid navy;
  -moz-transition: all .4s linear;
  -webkit-transition: all .4s linear;
  transition: all .4s linear;
}

tr.prehide th,
tr.prehide td,
tr.hidden th,
tr.hidden td {
  padding-top: 0;
  padding-bottom: 0;
}

.action { 
  background: maroon; 
  color: white;
}

.hidden { display: none !important; }

JavaScript

// Fade contents
$('#b1').on('click.toggle', function(e){
	$button = $(this).addClass('action');
  $('#t1').find('.toggle').each(function(e) {
  	var $row = $(this);
    if ($row.hasClass('hidden')) {
			$row.removeClass('hidden').hide().fadeIn(function(){
        $button.removeClass('action');
      });
    } else {
    	$row.fadeOut(function(){
      	$row.addClass('hidden');
        $button.removeClass('action');
      })
    }
  })
});

$('#b2').on('click.toggle', function(e) {
	var $button = $(this).addClass('action');
	var $rows = $('#t2').find('tr.toggle');
  var $cells = $rows.children('th,td');
  var $nofix = $cells.children('.cellAnim').parent();
  var $animDivs;
  
  // Add innerWrap to cells that don't have it.
  $cells.not($nofix).wrapInner('<div class="cellAnim" />');
  
  // Get the animate divs *after the wrapInner
  $animDivs = $cells.find('.cellAnim')
  
  if ($rows.filter('.hidden').length) {
  	
    // Turn off the hidden class
    // & add the zero-margin top/bottom "prehide"
    // TODO - prehide is a terrible name
    $rows
      .removeClass('hidden')
      .addClass('prehide');
    
    // Hide the data in the cells
    $animDivs.hide();
    
    // Remove the prehide class to start the CSS transition
    // Also start the 
    $rows.removeClass('prehide')
      .find('div.cellAnim')
      .slideDown(500, function(){
      $button.removeClass('action');
    });
    
    setTimeout(function(){
    },0)
  } else {
  	$rows
    	.addClass('prehide')
      .find('div.cellAnim')
      .slideUp(500, function(){
      	$rows.addClass('hidden').removeClass('prehide');
        $button.removeClass('action');
      });
  }
});