Search code examples
csscss-animations

Pure CSS animation visibility with delay


I am trying to implement some animation onLoad without Javascript. JS is easy, CSS is ... not.

I have a div which should be on display: none; and should be display: block; after 3 secondes. Lots of resources told me animate does not work with display, but should with visibility (which I use often in my transition).

Right know I have this terrible javascript function :

<script type="text/javascript">
    $(document).ready(function(){
        $(".js_only").hide();
        setTimeout(function () {
            $(".js_only").show();
        }, 3000);
    });
</script>

I tried some animation in CSS but no result ... nothing seems to work.

I have few animation in my page, but just struggling with the display: none; on animation.

@-moz-keyframes showEffect {
    0% { display: none; visibility: hidden; }
    100% { display: block; visibility: block;  }

}
@-webkit-keyframes showEffect {
    0% { display: none; visibility: hidden; }
    100% { display: block; visibility: block;  }

}
@keyframes showEffect {
    0% { display: none; visibility: hidden; }
    100% { display: block; visibility: block;  }
}

.css_only {
    -moz-animation-name: showEffect;
    -moz-animation-iteration-count: 1;
    -moz-animation-timing-function: ease-in;
    -moz-animation-duration: 2.3s;

    -webkit-animation-name: showEffect;
    -webkit-animation-iteration-count: 1;
    -webkit-animation-timing-function: ease-in;
    -webkit-animation-duration: 2.3s;

    animation-name: showEffect;
    animation-iteration-count: 1;
    animation-timing-function: ease-in;
    animation-duration: 2.3s;
}

It is important as hidden, this element does not take space at all. I created a JSFiddle to make quite tests.

My main concerne is SEO ... I don't think the JS option is really nice for that which is why I would like a pure CSS alternative. Also interested to test those animations and see where are those limits (Am I seeing one right now ?). Kinda having fun on such challenge.

Thanks for reading, hope someone has an answer.


Solution

  • 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.