Here's a clever solution that involves adjusting the maxWidth property of a table cell dynamically to change its size. While shrinking naturally works better than growing, this method is effective. To enhance the growing process universally, consider cloning the div and tracking its growth as it animates, then applying that width to the table cell. Check out the jsfiddle link below for this modified version.
<div id="info">Ready...</div>
<table style="width:100%;">
<tr>
<td id="tdID" style="width:1px;">
<div id="animator" style="width:100%; overflow:hidden; transition:2s linear width;">
<div style="background-color:red;">
111
</div>
</div>
</td>
<td>1111111111111111</td>
<td>11111111</td>
<td style="width:1px;">11111111</td>
</tr>
</table>
<button id="btn">Animate
</button>
<script>
var animator = document.getElementById("animator");
var tcell = document.getElementById("tdID");
var info = document.getElementById("info");
var t_start;
var max_width;
function shrink() {
var d = new Date();
var t = d.getTime();
tcell.style.maxWidth = animator.offsetWidth + "px";
if(t - t_start < 2000)
setTimeout(shrink,50);
else
info.innerHTML = "done";
}
function grow() {
var d = new Date();
var t = d.getTime();
var pcnt = (t-t_start) / 1000;
if(pcnt<1) {
tcell.style.maxWidth = (max_width*pcnt) + "px";
setTimeout(grow,50);
}
else {
tcell.style.maxWidth = max_width + "px";
info.innerHTML = "done.";
}
}
function Animate(){
var d = new Date();
t_start = d.getTime();
info.innerHTML = "start...";
if(animator.style.width === "100%") {
animator.style.transition = "2s linear width";
max_width = animator.offsetWidth;
animator.style.width = "0px";
setTimeout(shrink,50);
} else {
animator.style.transition = "0s linear width";
animator.style.width = "100%";
setTimeout(grow,50);
}
}
document.getElementById("btn").addEventListener("click", Animate);
https://jsfiddle.net/FrancisMacDougall/g2c5kcx9/