25

I have a very basic piece of HTML with the objective of animating from display: none; to display: block with opacity changing from 0 to 1.

I'm using Chrome browser, which uses the -webkit prefixes as preference and did a -webkit-keyframes transition set to make the animation possible. However, it does not work and just changes the display without fading.

I have a JSFiddle here.

<html>
    <head>
        <style type="text/css">
            #myDiv
                {
                display: none;
                opacity: 0;
                padding: 5px;
                color: #600;
                background-color: #CEC;
                -webkit-transition: 350ms display-none-transition;
                }

            #parent:hover>#myDiv
                {
                opacity: 1;
                display: block;
                }

            #parent
                {
                background-color: #000;
                color: #FFF;
                width: 500px;
                height: 500px;
                padding: 5px;
                }

            @-webkit-keyframes display-none-transition
                {
                0% {
                    display: none; 
                    opacity: 0;
                    }

                1% 
                    {
                    display: block; 
                    opacity: 0;
                    }

                100% 
                    {
                    display: block; 
                    opacity: 1;
                    }
                }
        </style>
        <body>
            <div id="parent">
                Hover on me...
                <div id="myDiv">
                    Hello!
                </div>
            </div>
        </body>
    </head>
</html>
rpy
  • 3,953
  • 2
  • 20
  • 31
user3476093
  • 704
  • 2
  • 6
  • 11

9 Answers9

40

The display doesn't work with CSS transition or animation.

Use opacity, visibility or z-index. You can combine all them.

Try to use visibility: visible in place display: block and visibility: hidden in place display: none.

And finally, combine z-index: -1 and z-index: 100 for example.

Good work ;)

Cezar Luiz
  • 523
  • 3
  • 6
23

If you are using @keyframes you should use -webkit-animation instead of -webkit-transition. Here is the doc for @keyframes animation: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_animations.

See code snippet below:

.parent {
  background-color: #000;
  color: #fff;
  width: 500px;
  height: 500px;
  padding: 5px;
}
.myDiv {
  display: none;
  opacity: 0;
  padding: 5px;
  color: #600;
  background-color: #cec;
}
.parent:hover .myDiv {
  display: block;
  opacity: 1;
  /* "both" tells the browser to use the above opacity
  at the end of the animation (best practice) */
  -webkit-animation: display-none-transition 1s both;
  animation: display-none-transition 1s both;
}
@-webkit-keyframes display-none-transition {
  0% {
    opacity: 0;
  }
}
@keyframes display-none-transition {
  0% {
    opacity: 0;
  }
}
<div class="parent">
  Hover on me...
  <div class="myDiv">Hello!</div>
</div>

2016 UPDATED ANSWER

To reflect today's best practices, I would use a transition instead of an animation. Here is the updated code:

.parent {
  background-color: #000;
  color: #fff;
  width: 500px;
  height: 500px;
  padding: 5px;
}
.myDiv {
  opacity: 0;
  padding: 5px;
  color: #600;
  background-color: #cec;
  -webkit-transition: opacity 1s;
  transition: opacity 1s;
}
.parent:hover .myDiv {
  opacity: 1;
}
<div class="parent">
  Hover on me...
  <div class="myDiv">Hello!</div>
</div>
Pipo
  • 978
  • 6
  • 19
  • 3
    The display property isn't animatable. You can remove it from the keyframe animation with the same result. – web-tiki Oct 15 '15 at 10:01
  • this saved my day... I was using transition and @keyframes, and that was my problem... thank you! – KnF Nov 20 '15 at 07:57
16

You can not animate display property. You can try with visibility: hidden to visibility: visible

Jonatas Walker
  • 13,583
  • 5
  • 53
  • 82
Salmen Bejaoui
  • 865
  • 1
  • 8
  • 22
  • No you can do it with display property: by switshing between `display:none;` and `display:block;` . – cнŝdk Oct 28 '14 at 11:51
  • 8
    No you can't , the display property is not animatable https://developer.mozilla.org/en-US/docs/Web/CSS/display – Salmen Bejaoui Oct 28 '14 at 11:53
  • Theorically it's not desgned to do it but you can do it, see [the answer in this exmaple](http://stackoverflow.com/questions/21070101/show-hide-div-using-javascript). – cнŝdk Oct 28 '14 at 11:59
6

Just use position: fixed and drop the z-index: -5 at the end of the @keyframe animation (you can do any negative index....

CSS:

@keyframes fadeOut {
  0% { opacity: 1

  }
  99% {
    opacity: 0;
    z-index: 1;
  }
  100%{
    opacity: 0;
    display:none;
    position: fixed;
    z-index: -5;
  }
}
Zlerp
  • 467
  • 7
  • 16
3

It's been tricky, it's been nasty, but here it is...

enter image description here

  • FadeOut (opacity) first
  • then truly hide (meaning: not covering up or catching any clicks, getting height: 0,...)
    • display: <whatever> is indeed no option.
    • But animating scaleY is. Or translate to far-far-away or the old classic: animating max-height (from a specific high px value) down to 0px…

For an earlier version of this snippet with some more general info on „back and forth animation on class toggle“ (and preventing that animation upon initial page load look here.

const div = document.querySelector('.target')

function toggleTarget() {
  div.classList.add('active');
  div.classList.toggle('play');
}
/* REF https://stackoverflow.com/a/49575979 */
/* REF https://stackoverflow.com/questions/26607330/css-display-none-and-opacity-animation-with-keyframes-not-working/64857102#64857102 */
body, html { /* eye candy */
  background: #444; display: flex; min-height: 100vh; align-items: center; justify-content: center;
}
button { font-size: 4em; border-radius: 20px; margin-left: 60px;}

div { /* eye candy */
  width: 200px; height: 100px; border-radius: 20px;
  background: green; display: flex; align-items: center; justify-content: center;
  font-family: sans-serif; font-size: 2em; color: white; text-align: center;
  text-shadow: 0px 2px 4px rgba(0,0,0,.6);
  
}

/* using this extra .active class prevents that there is an animation already on loading */
.active {
  animation: fadeAndHideBack 1s linear forwards;
}

.play {  
  opacity: 0;
  /* learning curve: setting background "awaits" animation finish,
     setting scale prematurely jumps to it, then doing animation from there */

  animation: fadeAndHide 1s linear forwards;
}


@keyframes fadeAndHide {
  0% { opacity: 1; }
  99.9% { opacity: 0; max-height: 100px; }
  100% { opacity: 0; max-height: 0; }
}

@keyframes fadeAndHideBack {
  0% { opacity: 0; max-height: 0; }
  0.1% { opacity: 0; max-height: 100px; }
  100% { opacity: 1; }
}
<div class="target"></div>
<button onclick="toggleTarget()">
  Toggle
</button>
Frank N
  • 9,625
  • 4
  • 80
  • 110
2

You can use Javascript to change both the display properties and animation. You can't put display in @keyframes.

Start with the element display:none. Then simultaneously add display:block and animation:* classes.

Here's a working example with animation in/out.

sweeds
  • 539
  • 6
  • 18
1

add this css ;

.fade:not(.show) {
    opacity: 1;
}

this work for me..

0

How about this example: jsfiddle The issue was needing to use an animation rather than transition with keyframes

@-webkit-keyframes fadeAnimation {
    0% {
        opacity: 0;
    }
    25% {
        opacity: 0.25;
    }
    50% {
        opacity: 0.5;
    }
    100% {
        opacity: 1;
    }
}
#myDiv {
    opacity: 0;
    padding: 5px;
    color: #600;
    background-color: #CEC;
}
#parent {
    background-color: #000;
    color: #FFF;
    width: 500px;
    height: 500px;
    padding: 5px;
}
#parent:hover #myDiv {
    -webkit-animation: fadeAnimation 6s;
}
svnm
  • 22,878
  • 21
  • 90
  • 105
0

You can't animate the display property. You can animate the visibility property. But visibility is not the same as display, as it will not remove the div element completely from the DOM (the property, visibility:collapse, can remove an element from the DOM, if the element is a table. This is an exception). You can instead animate CSS properties height and width. For instance, the below code will animate the square-block out.

function myAnimation(){
 var square= document.getElementById('square');
  if(square.getAttribute("class")==='square'){
    square.classList.add('animation');
  }else{
    square.classList.remove('animation');
  }
}
.square {
    background-color:blue;
    transform: translate(0, 0);
    width: 100px;
    height: 100px;
    opacity: 1;
    transition: all 0.5s ease-out;
}
.square.animation {
    transform: translate(-260px, -260px);
    width: 0;
    height: 0;
    opacity: 0;
    transition: all 0.5s ease-in;
}
<html>
 <body>
  <div class="square" id="square"></div>
  <br/>
  <button onclick="myAnimation()">Animate</button> 
 </body>
</html>

FYI, I have used CSS transitions to animate the div. Hope this was useful.