How do transitions work when fading in and out using css classes and javascript

I am trying to find out how transitions work. I am trying to make a thumbs up appear using a fade in fade out transition for a recycling simulator program, however, I do not know how understand how transitions work.
Here is a snippet of my html

<div class="thumbs-up-bg">
    <i  class="fas fa-thumbs-up" id="thumbs-up"></i>
</div>

<div class="thumbs-down-bg">
    <i class="fas fa-thumbs-down" id="thumbs-down"></i>
</div>

Here is the CSS

.thumbs-up-bg {
  position: absolute;
  visibility: hidden;
  background-color: green;
  display: inline-block;
  border-radius: 50%;
  width: 60px;
  height: 60px;
  text-align: center;
  opacity: 0;
  transition: opacity 0.1s ease-in-out;
}

#thumbs-up-bg.visible {
  opacity: 1;
}

#thumbs-up {
  font-size: 50px;
  color: white;
}

.thumbs-down-bg {
  position: absolute;
  visibility: hidden;
  background-color: red;
  display: inline-block;
  border-radius: 50%;
  width: 60px;
  height: 60px;
  text-align: center;
  opacity: 0;
  transition: opacity 0.1s ease-in-out;
}

#thumbs-down {
  font-size: 50px;
  color: white;
}

.visible {
  visibility: visible;
  opacity: 1;
  transition: opacity 2s linear;
}

.hidden {
  opacity: 0;
  transition: visibility 5s, opacity 2s linear;
}

Are transitions supposed to be set on the selector that is going to be changed? Is there a simpler way to complete this task?

Here is the Javascript

if (drop === trashDropZone){
    if(!isRecyclable(draggable)){
        alert("Success, it is garbage");
        thumbsUp.classList.toggle("visible");
        setTimeout(() =>{
        thumbsUp.classList.toggle("visible");
        thumbsUp.classList.toggle("hidden"); 
     }, 1000);
     makeInvisible(draggable);
     } else{
     //show thumbs down
     alert("Thumbs down");
     thumbsDown.classList.toggle("visible");
     setTimeout(() =>{
     thumbsDown.classList.toggle("visible");
     thumbsDown.classList.toggle("hidden"); 
     }, 1000);