Pure CSS animation visibility with delay

Solution 1:

You are correct in thinking that display is not animatable. It won't work, and you shouldn't bother including it in keyframe animations.

visibility is technically animatable, but in a round about way. You need to hold the property for as long as needed, then snap to the new value. visibility doesn't tween between keyframes, it just steps harshly.

.ele {
  width: 60px;
  height: 60px;
  
  background-color: #ff6699;
  animation: 1s fadeIn;
  animation-fill-mode: forwards;
  
  visibility: hidden;
}

.ele:hover {
  background-color: #123;
}

@keyframes fadeIn {
  99% {
    visibility: hidden;
  }
  100% {
    visibility: visible;
  }
}
<div class="ele"></div>

If you want to fade, you use opacity. If you include a delay, you'll need visibility as well, to stop the user from interacting with the element while it's not visible.

.ele {
  width: 60px;
  height: 60px;
  
  background-color: #ff6699;
  animation: 1s fadeIn;
  animation-fill-mode: forwards;
  
  visibility: hidden;
}

.ele:hover {
  background-color: #123;
}

@keyframes fadeIn {
  0% {
    opacity: 0;
  }
  100% {
    visibility: visible;
    opacity: 1;
  }
}
<div class="ele"></div>

Both examples use animation-fill-mode, which can hold an element's visual state after an animation ends.

Solution 2:

Use animation-delay:

div {
    width: 100px;
    height: 100px;
    background: red;
    opacity: 0;

    animation: fadeIn 3s;
    animation-delay: 5s;
    animation-fill-mode: forwards;
}

@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

Fiddle

Solution 3:

You can play with delay prop of animation, just set visibility:visible after a delay, demo:

@keyframes delayedShow {
  to {
    visibility: visible;
  }
}

.delayedShow{
  visibility: hidden;
  animation: 0s linear 2.3s forwards delayedShow ;
}
So, Where are you?

<div class="delayedShow">
  Hey, I'm here!
</div>