10

I know the effect can be easily achieved with jQuery hide(). The goal here is to do it with pure CSS instead. The fade-out result must have display:none so the element takes up zero space on the page layout (so visibility:hidden isn't an option).

I got success on made a fade-in effect with pure CSS on the display:none object using a piece of animation instead of transition, but I couldn't make it work on fade-out without to use the javascript setTimeout method.

Here's what I got so far:

function aaa(){
document.getElementById("b").style.display = "inline-block";  
}

function bbb(){
setTimeout(function(){ document.getElementById("b").style.display = "none"; }, 1000);   
}
#b {
  display: none;
  opacity: 0;
  -webkit-transition: all 1s; /* Safari */
  transition: all 1s;
  background: skyblue;
}

#a:hover ~ #b {
  opacity: 1;
  -webkit-animation: animate 1s; /* Chrome, Safari, Opera */ 
  animation: animate 1s;
}

@keyframes animate {
    0%   {opacity: 0;}
    100% {opacity: 1;}
}

div {
  width: 58px;
  height: 58px;
  vertical-align: middle;
  border: 1px solid black;
  line-height: 58px;
  text-align: center;
}

#a {
  background: tomato;  
}

#c {
  background: greenyellow;  
}
<div id=a onmouseenter="aaa()" onmouseleave="bbb()">OVER</div>
<div id=b>B</div>
<div id=c>C</div>

Is it possible to reach this same result using zero javascript?

codepen DEMO

L777
  • 7,719
  • 3
  • 38
  • 63

3 Answers3

9

As you can't animate display: none with CSS only, here is an alternative using height

#b {
  height:0;
  transition: 1s;
  overflow: hidden;
  background: skyblue;
}

#a:hover ~ #b {
  height: 58px;
}

div {
  width: 58px;
  height: 58px;
  vertical-align: middle;
  border: 1px solid black;
  line-height: 58px;
  text-align: center;
}

#a {
  background: tomato;  
}

#c {
  background: greenyellow;  
}
<div id=a>OVER</div>
<div id=b>B</div>
<div id=c>C</div>

If you need height: auto, you can use max-height like this

#b {
  max-height:0;
  padding: 0px 0;
  transition: 0.5s ease-in-out;
  overflow: hidden;
  background: skyblue;
}

#a:hover ~ #b {
  max-height: 150px;
  padding: 20px 0;
  transition: 0.8s ease-in-out;
}

div {
  width: 58px;
  height: auto;
  padding: 20px 0;
  vertical-align: middle;
  border: 1px solid black;
  text-align: center;
}

#a {
  background: tomato;  
}

#c {
  background: greenyellow;  
}
<div id=a>OVER</div>
<div id=b>B</div>
<div id=c>C</div>
Asons
  • 84,923
  • 12
  • 110
  • 165
4

As LGSon presented on the comments (and later on an answer), an alternative to display:none is height:0 combined with overflow:hidden.

So I did use this method together with opacity values on keyframes/transition to reproduce the fade-in/fade-out effects of the OP snippet, but without any javascript.

transition-timing-function: cubic-bezier was used to perform a quick jump to height:0

#b {
  overflow: hidden;
  height: 0;
  opacity: 0;
  -webkit-transition: opacity 1s, height 1s cubic-bezier(1,0,1,0); /* Safari */
  transition: opacity 1s, height 1s cubic-bezier(1,0,1,0);
  background: skyblue;
}

#a:hover ~ #b {
  opacity: 1;
  height: 60px;
  -webkit-animation: animate 1s; /* Chrome, Safari, Opera */ 
  animation: animate 1s;
  height: 60px;
}

@keyframes animate {
    0%   {opacity: 0;
  height: 60px;}
    100% { opacity: 1;
  height: 60px;}
}

div {
  width: 58px;
  height: 58px;
  vertical-align: middle;
  outline: 1px solid black;
  line-height: 60px;
  text-align: center;  
}

#a {
  background: tomato;  
}

#c {
  background: greenyellow;  
}
<div id=a>OVER</div>
<div id=b>B</div>
<div id=c>C</div>
Community
  • 1
  • 1
L777
  • 7,719
  • 3
  • 38
  • 63
  • 1
    Here is a few tricks to avoid it from running on load: http://stackoverflow.com/questions/27938900/how-to-prevent-css-keyframe-animation-to-run-on-page-load – Asons Mar 26 '16 at 01:57
  • @LGSon Updated with info from your link (use transition instead of keyframes to avoid the play on page load) combined with `transition-timing-function: cubic-bezier` and now it is just perfect. Thank you very much, this answer is half yours. – L777 Mar 26 '16 at 03:01
  • 1
    handy tool used to quick find the bezier numbers: [**link**](http://cubic-bezier.com/) – L777 Mar 26 '16 at 03:16
1

Unfortunately, the answer is 'no'. You can use opacity to animate fade in/out using css only, but changing display has no transition.

If your div contains only text, you may be able to do this using font-size.

If there are inner divs or images with specific dimensions, you will need to explicitly cater for these by transitioning their width/height within the div being hidden, bit that means knowing what is in the html when creating your css.

Steve Harris
  • 5,014
  • 1
  • 10
  • 25