8

I would like to have a simple color transition on an HTML element.

The problem that I am trying to solve is that I need to have the first part of the transition happen faster and the second part slower.

So, I am after a quick blink (fade-in) and a slower revert (fade-out).

I have achieved this with the following solution, but it does not look correct to me. It does not look correct in the sense that I ended up with nested event handlers and the code is too convoluted. However, it demonstrates exactly what I am trying to achieve.

Is there a way to set this kind of a variableCSSTransition in a smarter way?

function updateCard (cardObj) {
    // Handle card color.
    let cardBlinkColor = 'rgb(11, 83, 69)';

    // Store current background.
    let cardIdleColor = cardObj.style.background;
    // Asign fade-in properties.
    cardObj.classList.add('fadeIn');
    cardObj.style.background = cardBlinkColor;
    cardObj.addEventListener('transitionend', function(event) {
        //console.log('(IN) Done!, propertyName:', event.propertyName, 'elapsedTime:', event.elapsedTime);
        cardObj.classList.remove('fadeIn');
        cardObj.classList.add('fadeOut');
        cardObj.style.background = cardIdleColor;
        cardObj.addEventListener('transitionend', function(event) {
            //console.log('(OUT) Done!, propertyName:', event.propertyName, 'elapsedTime:', event.elapsedTime);
            cardObj.classList.remove('fadeOut');
        }, true);
    }, true);
}

const z = document.getElementsByClassName('card-container');
const card = z[0];

// Emulate client/server sequence.
setInterval(function() {
  updateCard(card);
}, 3000);
body {
  background-color: rgb(0, 39, 59) !important;
}

.table {
  /*border: 3px solid DeepSkyBlue;*/
  /*table-layout: fixed;*/
  width: 610px;
}

.table .main-row {
  border: 4px solid rgb(0, 49, 74);
  background-color: rgb(0, 39, 59);
}

.table .card-container {
  border: 1px solid rgb(0, 70, 106);
  background-color: rgb(2, 33, 46);
  width: 10em;
  margin: auto;
  table-layout: fixed;
  padding: 4px 4px;
}

.table .ticker {
  color: rgb(159, 235, 252);
}

.table .icon {
  color: rgb(252, 205, 159);
}

.table .card-container.fadeIn {
  /* transition */
  transition: background-color 0.1s ease-in;
}

.table .card-container.fadeOut {
  /* transition */
  transition: background-color 1s ease-out;
}
<!DOCTYPE html>
<html>

  <head>
    <title>CSS Transition Test</title>
  </head>

  <body>
    <div class="container" align="center">
      <table class="table">
        <tr>
          <td class="main-row" align="center">
            <table>
              <td class="card-container" id="foo">
                <table class="card-table">
                  <tr>
                    <td class="card-cell-left icon">+</td>
                    <td class="card-cell-right ticker">Test</td>
                  </tr>
                </table>
              </td>
            </table>
          </td>
        </tr>
      </table>
    </div>
  </body>

</html>

2 Answers 2

1

You can do this without using a separate class. Use CSS @keyframes:

body {
  background-color: rgb(0, 39, 59) !important;
}

.table {
  /*border: 3px solid DeepSkyBlue;*/
  /*table-layout: fixed;*/
  width: 610px;
}

.table .main-row {
  border: 4px solid rgb(0, 49, 74);
  background-color: rgb(0, 39, 59);
}

.table .card-container {
  border: 1px solid rgb(0, 70, 106);
  background-color: rgb(2, 33, 46);
  width: 10em;
  margin: auto;
  table-layout: fixed;
  padding: 4px 4px;
  animation: fade 3s infinite;
}

.table .ticker {
  color: rgb(159, 235, 252);
}

.table .icon {
  color: rgb(252, 205, 159);
}

@keyframes fade {
  0%   { background-color: rgb(2, 33, 46); }
  63.333%  { background-color: rgb(2, 33, 46); }
  66.667%  { background-color: rgb(11, 83, 69); }
  100% { background-color: rgb(2, 33, 46); }
}
<div class="container" align="center">
  <table class="table">
    <tr>
      <td class="main-row" align="center">
        <table>
          <td class="card-container" id="foo">
            <table class="card-table">
              <tr>
                <td class="card-cell-left icon">+</td>
                <td class="card-cell-right ticker">Test</td>
              </tr>
            </table>
          </td>
        </table>
      </td>
    </tr>
  </table>
</div>

The timing may differ a little. You can control the timing by manipulating the transition duration of the class and the stops (given in percentages) of the animation.

EDIT: I have modified the animation such that it exactly matches the one you made in JavaScript. The animation durations were calculated as follows:

Fade in duration = 0.1 seconds

Fade out duration = 1 seconds

Total transition duration = 3 seconds

Delay at the start = time interval - fade in - fade out = 3 - 0.1 - 1 = 1.9 seconds

Delay percentage = 1.9 ÷ 3 × 100 = 63.333 seconds

Fade in percentage = 0.1 ÷ 3 × 100 = 3.333 seconds

And the rest of the animation is a fade out.

Sign up to request clarification or add additional context in comments.

7 Comments

Yes. Thanks. I need them to be consecutive events: first fade-in, then fade-out immediately, chained together. That is why I am trying to track the end-of-transition event, so I can trigger the second transition immediately once the first one is done.
Thank you very much. This is a very interesting solution but I am trying to get this controlled by a function. Thus, was the updateCard() function in my question. Any ideas about how can I control the blinking through a function, so it only happens when the function is called.
I think I got a solution working here. Although I guess your solution relies on setTimeout() to tap into the animation and out of it as it loops for infinity: jsfiddle.net/cryptoeraser/v38egobx/35
You got it better then mine ;)
Could you please have a look at this final fiddle: jsfiddle.net/cryptoeraser/f3kdj9n0 I have linked the animation duration (in the css) to the js blink duration through a global css variable so that they stay in sync. If you think this is a viable solution based on your answer, I would happily accept your answer. Thanks.
|
0

You can try to add transition-delay as a 4th parameter of transition property:

.table .card-container.fadeOut {
    transition: background-color 1s ease-out 1s;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.