'Why is my CSS animation transition not working

The transition should take 2.5 seconds, however the elements are being styled immediately instead.

#members {
  display: flex;
  flex-wrap: wrap;
}

.member-card {
  background: grey;
  width: 150px;
  height: 150px;
  margin: 5px;
  
  opacity: 0;
  transition: all 2.5s ease;
  transform: translateY(50px);
  display: inline-block;
}

.member-card.fade {
  opacity: 1;
  transform: translateY(0px);
  background: orange;
}
<div id="members">
    <div class="member-card fade"></div>
    <div class="member-card fade"></div>
    <div class="member-card fade"></div>
    <div class="member-card fade"></div>
    <div class="member-card fade"></div>
    <div class="member-card fade"></div>
    <div class="member-card fade"></div>
</div>


Solution 1:[1]

To further extend on my comment, the reason why the transition is not firing is because there is no intermediate state when the page the rendered/painted, that the .fade class is not present. Therefore the browser "shortcircuits" to the final state. If you want an entry transition, you can try one of the two tricks:

Option A: Use CSS animation

Define a fade-in animation for your element. Remember to use animation-fill-mode: forwards to ensure that the final animation state is persisted.

#members {
  display: flex;
  flex-wrap: wrap;
}

.member-card {
  width: 150px;
  height: 150px;
  margin: 5px;
  display: inline-block;
  animation: 2.5s ease-in forwards fadeIn;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(50px);
    background: grey;
  }
  to {
    opacity: 1;
    transform: translateY(0px);
    background: orange;
  }
}
<div id="members">
  <div class="member-card fade"></div>
  <div class="member-card fade"></div>
  <div class="member-card fade"></div>
  <div class="member-card fade"></div>
  <div class="member-card fade"></div>
  <div class="member-card fade"></div>
  <div class="member-card fade"></div>
</div>

Option B: Use JS to add the fade class after paint

Alternatively you can also use JS to add the fade class. The trick is to add the class "fade" after the first paint. This can be done by using either window.setTimeout(..., 0) or using window.requestAnimationFrame. I prefer the latter because it explicitly waits for the next repaint:

// Use requestAnimationFrame to wait for first paint
window.requestAnimationFrame(() => {
  document.querySelectorAll('.member-card').forEach(el => {
    el.classList.add('fade');
  });
});
#members {
  display: flex;
  flex-wrap: wrap;
}

.member-card {
  background: grey;
  width: 150px;
  height: 150px;
  margin: 5px;
  opacity: 0;
  transition: all 2.5s ease;
  transform: translateY(50px);
  display: inline-block;
}

.member-card.fade {
  opacity: 1;
  transform: translateY(0px);
  background: orange;
}
<div id="members">
  <div class="member-card"></div>
  <div class="member-card"></div>
  <div class="member-card"></div>
  <div class="member-card"></div>
  <div class="member-card"></div>
  <div class="member-card"></div>
  <div class="member-card"></div>
</div>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Terry