CSS Transition Flyout

without setTimeout

by b9chris

HTML

<button id=button>Toggle</button>

<div id="box" class="hidden">Lorem<br/>Catsum</div>

SCSS

div.hidden {
  display: none;
}
#box {
  transition: height 1s, opacity 1s;
  
  background: #8cf;
  width: 100px;
  overflow: hidden;
  padding: 15px;
}



// Niceties - unimportant to example

#button {
  display: block;
  margin-bottom: 1em;
  cursor: pointer;
}

body {
  font: normal 10pt Verdana;
}

JavaScript

// Brass9 utilities  Library
$.fn.noTrnsn = function () {
    return this.each(function (i, tag) {
        tag.style.transition = 'none';
    });
};
$.fn.resumeTrnsn = function () {
    return this.each(function (i, tag) {
        tag.offsetHeight;    
        tag.style.transition = null;
    });
};
$.fn.wait = function (time, fn) {
    if (time)
        this.delay(time);
    if (!fn)
        return this;

    var _this = this;
    return this.queue(function (n) {
        fn.call(_this);
        n();
    });
};
// /Library

$('#button').on('click', function() {
    var tag = $('#box');
    if (tag.hasClass('hidden')) {
        // Open it
        // Measure it
        tag.stop().noTrnsn().removeClass('hidden').css({
            opacity: 0, height: 'auto'
        });
        var h = tag.height();
        tag.css({ height: 0 }).resumeTrnsn()
        // Animate it
        .css({ opacity: 1, height: h })
        .wait(1000, function() {
            tag.css({ height: 'auto' });
        });
    } else {
        // Close it
        // Measure it
        var h = tag.noTrnsn().height();
        tag.stop().css({ height: h })
        .resumeTrnsn()
        // Animate it
        .css({ opacity: 0, height: 0 })
        .wait(1000, function() {
            tag.addClass('hidden');
        });
    }
});