Dennis
Dennis

Reputation: 233

CSS transition cutting off early

I'm having an issue with my CSS transitions being cut off early and I'm not sure why it's happening. I think it has something to do with another transition on a child element because if I remove the code that makes the child elements transition, the container's transition is fine.

The code is kind of long and I'm using a library called Baraja that's supposed to allow me to transition between elements as if they were cards.

This is the structure of the relevant HTML:

<ul id="cards" class="baraja-container">
  <li id="usa-germany" class="card">
    <div id="room-info">
      <h1 id="room-name">USA vs. Germany</h1>
      <p class="room-description">
        Live game discussion with Berkeley alumni. Let's go America!
      </p>
    </div>

    <div id="thumbnails-container">
      <div id="thumb-0" class="thumb">
        <div id="message-0" class="message-popup first">
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
        </div>
      </div>
      <div id="thumb-1" class="thumb">
        <div id="message-1" class="message-popup top">
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
        </div>
      </div>
      <div id="thumb-2" class="thumb">
        <div id="message-2" class="message-popup">
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
        </div>
      </div>
      <div id="thumb-3" class="thumb">
        <div id="message-3" class="message-popup">
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
        </div>
      </div>
      <div id="thumb-4" class="thumb">
        <div id="message-4" class="message-popup top right">
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
        </div>
      </div>
      <div id="thumb-5" class="thumb">
        <div id="message-5" class="message-popup top right">
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
        </div>
      </div>
    </div>
  </li>


  <li class="card">
    <div id="room-info">
      <h1 id="room-name">CET @ Cal</h1>
      <p class="room-description">
        Discussion around Cal's Center for Entreneurship and Technology
      </p>
    </div>

    <div id="thumbnails-container">
      <div id="thumb-0" class="thumb">

        <div id="message-0" class="message-popup first">
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
        </div>
      </div>
      <div id="thumb-1" class="thumb">
        <div id="message-1" class="message-popup top">
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
        </div>
      </div>
      <div id="thumb-2"  class="thumb">
        <div id="message-2" class="message-popup">
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
        </div>
      </div>
      <div id="thumb-3" class="thumb">
        <div id="message-3" class="message-popup right">
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
        </div>
      </div>
      <div id="thumb-4" class="thumb">
        <div id="message-4" class="message-popup top right">
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
        </div>
      </div>
      <div id="thumb-5" class="thumb">
        <div id="message-5" class="message-popup top right">
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
        </div>
      </div>
    </div>
  </li>


  <li class="card">
    <div id="room-info">
      <h1 id="room-name">Yoga Masters</h1>
      <p class="room-description">
        Masters of Yoga may gathers here to discuss their art and practice techniques
      </p>
    </div>

    <div id="thumbnails-container">
      <div id="thumb-0" class="thumb">

        <div id="message-0" class="message-popup first">
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
        </div>
      </div>
      <div id="thumb-1" class="thumb">
        <div id="message-1" class="message-popup top">
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
        </div>
      </div>
      <div id="thumb-2"  class="thumb">
        <div id="message-2" class="message-popup">
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
        </div>
      </div>
      <div id="thumb-3" class="thumb">
        <div id="message-3" class="message-popup right">
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
        </div>
      </div>
      <div id="thumb-4" class="thumb">
        <div id="message-4" class="message-popup top right">
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
        </div>
      </div>
      <div id="thumb-5" class="thumb">
        <div id="message-5" class="message-popup top right">
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
          <span class="dot">&bull;</span>
        </div>
      </div>
    </div>
  </li>
</ul>

Here's the relevant CSS:

  #cards {
    width: 100%;
    height: 260px;
    overflow: visible;
    margin: 0;
  }

  .card {
    padding: 30px 20px;
    border: 1px solid #CCC;
    border-radius: 4px;
    background: #F5F5F5;

    h1 {
      margin-top: 0;
    }
  }

.thumb {
  width: 40px;
  height: 40px;
  display: inline-block;
  border-radius: 20px;
  border: 2px solid #9A9A9A;
  position: relative;
  background: #EEE;
  cursor: pointer;
  margin-right: 10px;

  &:last-of-type {
    margin-right: 0;
  }

  background-size: 100% 100%;

  #message-0 {
    background: #E26A6A;

    &::before {
      border-bottom: 7px solid #E26A6A;
    }
  }

  #message-1 {
    background: #EB9532;
    &::before {
      border-top: 7px solid #EB9532;
    }
  }

  #message-2 {
    background: #66CC99;

    &::before {
      border-bottom: 7px solid #66CC99;
    }
  }

  #message-3 {
    background: #3498DB;

    &::before {
      border-bottom: 7px solid #3498DB;
    }
  }

  #message-4 {
    background: #67809F;

    &::before {
      border-top: 7px solid #67809F;
    }
  }

  #message-5 {
    background: #95A5A6;

    &::before {
      border-top: 7px solid #95A5A6;
    }
  }

  .message-popup {
    display: block;
    position: absolute;
    z-index: 9000;
    top: 37px;
    left: 7px;
    background: #DDD;
    border: 1px solid #CCC;
    color: white;
    transform: scale(0);
    -webkit-transform: scale(0);
    transform-origin: 10px -12px;
    padding: 5px 5px;
    width: 40px;
    text-align: center;
    border-radius: 3px;
    font-size: 13px;

    transition-property: all;
    transition-duration: 0.4s;
    transition-timing-function: cubic-bezier(0.34, 1.2, 0.7, 1);

    letter-spacing: -1px;

    &::before {
      content: "";
      width: 0;
      height: 0;
      border-left: 7px solid transparent;
      border-right: 7px solid transparent;
      background: transparent;
      position: absolute;
      top: -5px;
      left: 3px;
    }

    &.show {
      transform: scale(1);
      -webkit-transform: scale(1);
    }

    &.right {
      right: 7px;
      left: auto;
      transform-origin: 30px -12px;

      &::before {
        left: auto;
        right: 3px;
      }
    }

    &.top {
      top: -27px;
      transform-origin: 10px 39px;

      &.right {
        transform-origin: 30px 39px;
      }

      &::before {
        top: 25px;
      }
    }

    .dot {
      transition-property: transform, -webkit-transform;
      transition-duration: 0.45s;
      transition-timing-function: ease-in-out;
    }
  }
}

And here's the JavaScript code that drives it:

var animateDots = function(dots, i, numDots) {
  var currDot = $(dots[i]);
  currDot.css('transform', 'translateY(-4px)');
  currDot.css('-webkit-transform', 'translateY(-4px)');

  currDot.one("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function() {
    $(this).css('transform', 'translateY(0)');
    $(this).css('-webkit-transform', 'translateY(0)');
  });
};

var showPopup = function(popup) {
  // Shows the popup passed in and animates its dots
  if (popup.hasClass('show')) {
    return;
  }

  // 'show' popup
  popup.addClass('show');

  // start transition on dots
  var dots = popup.find('.dot'),
      i = 0,
      numDots = dots.length;

  if (dots) {
    animateDots(dots, i, numDots);
    i = (i + 1) % numDots;

    popup[0].dotInterval = setInterval(function() {
      animateDots(dots, i, numDots);
      i = (i + 1) % numDots;
    }, 350);
  }
};


$(function() {

  // return;
  var baraja = $('#cards').baraja();

  $('#next').on('click', function(e) {
    e.preventDefault();

    // stop current transitions
    if (popupInterval) {
      clearInterval(popupInterval);
    }

    baraja.next();
  });

  $('#close').on('click', function(e) {
    e.preventDefault();

    baraja.close();
  });

  var popupInterval = setInterval(function() {
    var popups = $('#usa-germany .message-popup'),
        numPopups = popups.length,
        rand = Math.floor(Math.random() * numPopups),
        popup = $(popups[rand]);

    while (popup.hasClass('show')) {
      rand = Math.floor(Math.random() * numPopups);
      popup = $(popups[rand]);
    }

    showPopup(popup);

    setTimeout(function() {
      // Schedule the popup to hide
      popup.removeClass('show');

      popup.one("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function() {
        var popup = $(this);
        clearInterval(popup[0].dotInterval);
      });
    }, 3600);
  }, 2000);
});

It was difficult to get everything set up on a JSFiddle or similar but basically the .message-popup divs go from scale(0) to scale(1) and then the span.dot's inside each transition up and then back down over time. The card transitions are fine if there aren't any other transitions going on inside of it. Are you not supposed to have CSS transitions inside of other CSS transitions? How do I get around this? Or is it an issue with setInterval/setTimeout?

Upvotes: 3

Views: 1388

Answers (1)

Dennis
Dennis

Reputation: 233

The Baraja library listens for the transitionend event on the parent element which gets bubbled up from the children's transitionend events. To stop this, in the callback to the transitionend event, call stopPropagation() on the event passed in like so:

$el.on('transitionend', function(e) {
    e.stopPropagation();
    // do stuff
});

Relevant for whenever you want to chain transitions on children transitions as well as for those on the children's parent element

Upvotes: 1

Related Questions