📣Postmark has been acquired by ActiveCampaign
x

Controlling CSS transition with TransitionEnd event

Recently while redesigning one of Beanstalk’s pages I had an interesting problem to solve. I had a few blocks which I wanted to highlight as a result of user’s action. The most natural way to do this is with CSS transitions:

.box-to-illuminate {
  background-color: yellow;
  transition: background 500ms ease;
}
.box-to-illuminate.illuminate {
  background-color: red;
}

And a bit of JavaScript:

$('.box-to-illuminate').click(function () {
  $(this).addClass('illuminate');
});

The problem is that class illuminate would be kept on the block, so the next time a user performs an action it won’t be highlighted. This can be fixed by adding an timeout (check out Fiddle):

$('.box-to-illuminate').click(function () {
  var self = $(this),
      timeout;

  self.addClass('illuminate');

  timeout = window.setTimeout(function () {
    self.removeClass('illuminate');
  }, 500);
});

What I didn’t like about this solution is that now transition duration must be specified both in CSS and JS. This makes both of them less maintainable and more prone to errors, which is something I’m trying to avoid.

Turns out a new event called transitionend was introduced in CSS3. It is fired at the completion of the transition and is already supported (sometimes with prefixes) by many browsers, with a notable exception of Internet Explorer 9 and below. I wasn’t really concerned about IE and gave it a try:

$('.box-to-illuminate').click(function () {
  $(this)
    .addClass('illuminate')
    .bind('webkitTransitionEnd oTransitionEnd transitionend', function () {
        $(this).removeClass('illuminate');
    }
  );
});

Works like a charm! Now transition styles are completely separated from a trigger and code is much more maintainable.