How to transition CSS display + opacity properties

CssCss Transitions

Css Problem Overview


I have got a problem with a CSS3 animation.

.child {
    opacity: 0;
    display: none;

    -webkit-transition: opacity 0.5s ease-in-out;
    -moz-transition: opacity 0.5s ease-in-out;
    transition: opacity 0.5s ease-in-out;
}

.parent:hover .child {
    opacity: 0.9;
    display: block;
}

This code only works if I remove the change of display.

I want to change the display just after the hover but the opacity should be changed using the transition.

Css Solutions


Solution 1 - Css

Based on Michaels answer this is the actual CSS code to use

.parent:hover .child
{
	display: block;

    -webkit-animation: fadeInFromNone 0.5s ease-out;
    -moz-animation: fadeInFromNone 0.5s ease-out;
    -o-animation: fadeInFromNone 0.5s ease-out;
    animation: fadeInFromNone 0.5s ease-out;
}

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

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

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

@-moz-keyframes fadeInFromNone {
    0% {
        display: none;
        opacity: 0;
    }

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

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

@-o-keyframes fadeInFromNone {
    0% {
        display: none;
        opacity: 0;
    }

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

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

@keyframes fadeInFromNone {
    0% {
        display: none;
        opacity: 0;
    }

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

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

Solution 2 - Css

If possible - use visibility instead of display

For instance:

.child {
	visibility: hidden;
	opacity: 0;
	transition: opacity 0.3s, visibility 0.3s;
}

.parent:hover .child {
	visibility: visible;
	opacity: 1;
	transition: opacity 0.3s, visibility 0.3s;
}

Solution 3 - Css

You can do with CSS animations:

0% display:none ; opacity: 0;
1% display: block ; opacity: 0;
100% display: block ; opacity: 1;

Solution 4 - Css

This workaround works:

  1. define a “keyframe”:

     @-webkit-keyframes fadeIn { 
       0% { opacity: 0; }
       20% { opacity: 0; }
       40% { opacity: 0.3; }
       60% { opacity: 0.5; }
       80% { opacity: 0.9; }
       100% { opacity: 1; }
     }
    
     @keyframes fadeIn {
       0% { opacity: 0; }
       20% { opacity: 0; }
       40% { opacity: 0.3; }
       60% { opacity: 0.5; }
       80% { opacity: 0.9; }
       100% { opacity: 1; }
     }
    
  2. Use this “keyframe” on “hover”:

     div a span { 
       display: none;
     }
    
     div a:hover span {
       display: block;
    
       -webkit-animation-name: fadeIn;
       -webkit-animation-duration: 1s;
       animation-name: fadeIn;
       animation-duration: 1s;
     }
    

Solution 5 - Css

I used this to achieve it. They fade on hover but take no space when hidden, perfect!

.child {
    height: 0px;
    opacity: 0;
    visibility: hidden;
    transition: all .5s ease-in-out;
}

.parent:hover .child {
    height: auto;
    opacity: 1;
    visibility: visible;
}

Solution 6 - Css

There is another good method to get this done by using pointer-events:

.child {
    opacity: 0;
    pointer-events: none;

    -webkit-transition: opacity 0.5s ease-in-out;
    -moz-transition: opacity 0.5s ease-in-out;
    transition: opacity 0.5s ease-in-out;
}

.parent:hover .child {
    opacity: 0.9;
    pointer-events: all;
}

Unfortunately, this is not supported in IE10 and below.

Solution 7 - Css

I changed a bit but the result is beautiful.

.child {
    width: 0px;
    height: 0px;
    opacity: 0;
}

.parent:hover child {
    width: 150px;
    height: 300px;
    opacity: .9;
}

Thank you to everyone.

Solution 8 - Css

I had the same problem. I tried using animations instead of transitions - as suggested by @MichaelMullany and @Chris - but it only worked for webkit browsers even if I copy-pasted with "-moz" and "-o" prefixes.

I was able to get around the problem by using visibility instead of display. This works for me because my child element is position: absolute, so document flow isn't being affected. It might work for others too.

This is what the original code would look like using my solution:

.child {
    position: absolute;
    opacity: 0;
    visibility: hidden;
    
    -webkit-transition: opacity 0.5s ease-in-out;
    -moz-transition: opacity 0.5s ease-in-out;
    transition: opacity 0.5s ease-in-out;
}

.parent:hover .child {
    position: relative;
    opacity: 0.9;
    visibility: visible;
}

Solution 9 - Css

To have animation on both ways onHoverIn/Out I did this solution. Hope it will help to someone

@keyframes fadeOutFromBlock {
  0% {
    position: relative;
    opacity: 1;
    transform: translateX(0);
  }
  
  90% {
    position: relative;
    opacity: 0;
    transform: translateX(0);
  }
  
  100% {
    position: absolute;
    opacity: 0;
    transform: translateX(-999px);
  }
}

@keyframes fadeInFromNone {
  0% {
    position: absolute;
    opacity: 0;
    transform: translateX(-999px);
  }

  1% {
    position: relative;
    opacity: 0;
    transform: translateX(0);
  }

  100% {
    position: relative;
    opacity: 1;
    transform: translateX(0);
  }
}

.drafts-content {
  position: relative;
  opacity: 1;
  transform: translateX(0);
  animation: fadeInFromNone 1s ease-in;
  will-change: opacity, transform;

  &.hide-drafts {
    position: absolute;
    opacity: 0;
    transform: translateX(-999px);
    animation: fadeOutFromBlock 0.5s ease-out;
    will-change: opacity, transform;
  }
}

Solution 10 - Css

On absolute or fixed elements you could also use z-index:

.item {
    position: absolute;
    z-index: -100;
}

.item:hover {
    z-index: 100;
}

Other elements should have a z-index between -100 and 100 now.

Solution 11 - Css

I know, this is not really a solution for your question, because you ask for > display + opacity

My approach solves a more general question, but maybe this was the background problem that should be solved by using display in combination with opacity.

My desire was to get the Element out of the way when it is not visible. This solution does exactly that: It moves the element out of the away, and this can be used for transition:

.child {
  left: -2000px;
  opacity: 0;
  visibility: hidden;
  transition: left 0s 0.8s, visibility 0s 0.8s, opacity 0.8s;
}

.parent:hover .child {
  left: 0;
  opacity: 1;
  visibility: visible;
  transition: left 0s, visibility 0s, opacity 0.8s;
}

This code does not contain any browser prefixes or backward compatibility hacks. It just illustrates the concept how the element is moved away as it is not needed any more.

The interesting part are the two different transition definitions. When the mouse-pointer is hovering the .parent element the .child element needs to be put in place immediately and then the opacity will be changed:

transition: left 0s, visibility 0s, opacity 0.8s;

When there is no hover, or the mouse-pointer was moved off the element, one has to wait until the opacity change has finished before the element can be moved off screen:

transition: left 0s 0.8s, visibility 0s 0.8s, opacity 0.8s;

Moving the object away will be a viable alternative in a case where setting display:none would not break the layout.

I hope I hit the nail on the head for this question although I did not answer it.

Solution 12 - Css

If you are triggering the change with JS, let's say on click, there is a nice workaround.

You see, the problem happens because the animation is ignored on display:none element but browser applies all the changes at once and the element is never display:block while not animated at the same time.

The trick is to ask the browser to render the frame after changing the visibility but before triggering the animation.

Here is a JQuery example:

    $('.child').css({"display":"block"});
    //now ask the browser what is the value of the display property
    $('.child').css("display"); //this will trigger the browser to apply the change. this costs one frame render
    //now a change to opacity will trigger the animation
    $('.child').css("opacity":100);

Solution 13 - Css

One thing that I did was set the initial state's margin to be something like "margin-left: -9999px" so it does not appear on the screen, and then reset "margin-left: 0" on the hover state. Keep it "display: block" in that case. Did the trick for me :)

Edit: Save the state and not revert to previous hover state? Ok here we need JS:

<style>
.hovered { 
    /* hover styles here */
}
</style>

<script type="text/javascript">
$('.link').hover(function() {
   var $link = $(this);
   if (!$link.hasclass('hovered')) { // check to see if the class was already given
        $(this).addClass('hovered');
   } 
});
</script>

Solution 14 - Css

HOW TO ANIMATE OPACITY WITH CSS:
this is my code:
the CSS code

.item {   
    height:200px;
    width:200px;
    background:red;
    opacity:0;
    transition: opacity 1s ease-in-out;
}

.item:hover {
    opacity: 1;
}
code {
    background: linear-gradient(to right,#fce4ed,#ffe8cc);
}

<div class="item">

</div>
<p><code> move mouse over top of this text</code></p>

or check this demo file

> function vote(){
> var vote = getElementById("yourOpinion")
> if(this.workWithYou):
> vote += 1 };
lol

Solution 15 - Css

display: is not transitionable. You'll probably need to use jQuery to do what you want to do.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlexis DelrieuView Question on Stackoverflow
Solution 1 - CssChrisView Answer on Stackoverflow
Solution 2 - Csstomas.satinskyView Answer on Stackoverflow
Solution 3 - CssMichael MullanyView Answer on Stackoverflow
Solution 4 - CssHermann SchwarzView Answer on Stackoverflow
Solution 5 - CssfelixhirschfeldView Answer on Stackoverflow
Solution 6 - CssRafaelKrView Answer on Stackoverflow
Solution 7 - CssAlexis DelrieuView Answer on Stackoverflow
Solution 8 - CssDaveView Answer on Stackoverflow
Solution 9 - CssNicholasView Answer on Stackoverflow
Solution 10 - CssLuca SteebView Answer on Stackoverflow
Solution 11 - CssHannes MorgensternView Answer on Stackoverflow
Solution 12 - Cssdaniel.sedlacekView Answer on Stackoverflow
Solution 13 - CssJoshuaView Answer on Stackoverflow
Solution 14 - CsszakizakibzrView Answer on Stackoverflow
Solution 15 - CssMadara's GhostView Answer on Stackoverflow