52

I have been trying to use css to show a Hidden Div fade in whenever I hover its parent element.

So far all I have managed to do was to get the hidden div to show, but there are no easing transitions what so ever.

Here is my Code on JSfiddle http://jsfiddle.net/9dsGP/

Here is my Code:

HTML:

<div id="header">
<div id="button">This is a Button
    <div class="content">
    This is the Hidden Div
    </div>
</div>
</div>

CSS:

#header #button {width:200px; background:#eee}

#header #button:hover > .content {display:block; opacity:1;}

#header #button .content:hover { display:block;}

#header #button .content {

-webkit-transition: all .3s ease .15s;
-moz-transition: all .3s ease .15s;
-o-transition: all .3s ease .15s;
-ms-transition: all .3s ease .15s;
transition: all .3s ease .15s;

    opacity:0;
    clear: both;
    display: none;

    top: -1px;
    left:-160px;
    padding: 8px;
    min-height: 150px;
    border-top: 1px solid #EEEEEE;
    border-left: 1px solid #EEEEEE;
    border-right: 1px solid #EEEEEE;
    border-bottom: 1px solid #EEEEEE;
    -webkit-border-radius: 0px 7px 7px 7px;
    -moz-border-radius: 0px 7px 7px 7px;
    -khtml-border-radius: 0px 7px 7px 7px;
    border-radius: 0px 7px 7px 7px;
    -webkit-box-shadow: 0px 2px 2px #DDDDDD;
    -moz-box-shadow: 0px 2px 2px #DDDDDD;
    box-shadow: 0px 2px 2px #DDDDDD;
    background: #FFF;
}

Any clue as to what Im doing wrong? Just trying to get a smooth effect for the hidden content when I hover over the button. Thanks in advance!

Hashem Qolami
  • 97,268
  • 26
  • 150
  • 164
JCBiggar
  • 2,477
  • 3
  • 20
  • 33

7 Answers7

118

display:none; removes a block from the page as if it were never there. A block cannot be partially displayed; it’s either there or it’s not. The same is true for visibility; you can’t expect a block to be half hidden which, by definition, would be visible! Fortunately, you can use opacity for fading effects instead.
- reference

As an alternatiive CSS solution, you could play with opacity, height and padding properties to achieve the desirable effect:

#header #button:hover > .content {
    opacity:1;
    height: 150px;
    padding: 8px;    
}

#header #button .content {
    opacity:0;
    height: 0;
    padding: 0 8px;
    overflow: hidden;
    transition: all .3s ease .15s;
}

(Vendor prefixes omitted due to brevity.)

Here is a working demo. Also here is a similar topic on SO.

#header #button {
  width:200px;
  background:#ddd;
  transition: border-radius .3s ease .15s;
}

#header #button:hover, #header #button > .content {
    border-radius: 0px 0px 7px 7px;
}

#header #button:hover > .content {
  opacity: 1;
  height: 150px;
  padding: 8px;    
}

#header #button > .content {
  opacity:0;
  clear: both;
  height: 0;
  padding: 0 8px;
  overflow: hidden;

  -webkit-transition: all .3s ease .15s;
  -moz-transition: all .3s ease .15s;
  -o-transition: all .3s ease .15s;
  -ms-transition: all .3s ease .15s;
  transition: all .3s ease .15s;

  border: 1px solid #ddd;

  -webkit-box-shadow: 0px 2px 2px #ddd;
  -moz-box-shadow: 0px 2px 2px #ddd;
  box-shadow: 0px 2px 2px #ddd;
  background: #FFF;
}

#button > span { display: inline-block; padding: .5em 1em }
<div id="header">
  <div id="button"> <span>This is a Button</span>
    <div class="content">
      This is the Hidden Div
    </div>
  </div>
</div>
Community
  • 1
  • 1
Hashem Qolami
  • 97,268
  • 26
  • 150
  • 164
  • @HashemQolami: Without height reverse transition won't work, for make the height auto, animate the max-height:0 to max-height:999px, see the Boomstein answer below. – Mohamed Hussain Aug 23 '16 at 08:40
  • 1
    @MohamedHussain That's right. I didn't update the answer for that senario as Boomstein had already mentioned it :) – Hashem Qolami Aug 23 '16 at 09:06
  • use opcity method need to make sure pointer-event is none when opacity is 0 otherwise ppl might ghost click it – Zoe L Dec 03 '21 at 18:08
  • while agreed that `display` doesn't work well with transitions, `visibility` works fine. – mac Apr 02 '23 at 21:30
16

You cannot use height: 0 and height: auto to transition the height. auto is always relative and cannot be transitioned towards. You could however use max-height: 0 and transition that to max-height: 9999px for example.

Sorry I couldn't comment, my rep isn't high enough...

Boomstein
  • 161
  • 2
5

I found a solution while tinkering around.

People who directly wanna see the results:

With click: https://jsfiddle.net/dt52jazg/

With Hover: https://jsfiddle.net/7gkufLsh/1/

Below is the code:

HTML

<ul class="list">
  <li>Hey</li>
  <li>This</li>
  <li>is</li>
  <li>just</li>
  <li>a</li>
  <li>test</li>
</ul>

<button class="click-me">
  Click me
</button>

CSS

.list li {
  min-height: 0;
  max-height: 0;
  opacity: 0;
  -webkit-transition: all .3s ease-in-out;
  transition: all .3s ease-in-out;
}

.active li {
  min-height: 20px;
  opacity: 1;
}

JS

(function() {
  $('.click-me').on('click', function() {
    $('.list').toggleClass('active');
  });
})();

Please let me know whether there is any problem with this solution 'coz I feel there would be no restriction of max-height with this solution.

shet_tayyy
  • 5,366
  • 11
  • 44
  • 82
1

I faced the problem with display:none

I have several horizontal bars with transition effects but I wanted to show only part of that container and fold the rest while maintaining the effects. I reproduced a small demo here

The obvious was to wrap those hidden animated bars in a div then toggle that element's height and opacity

.hide{
  opacity: 0;
  height: 0;
}
.bars-wrapper.expanded > .hide{
 opacity: 1;
 height: auto;
}

The animation works well but the issue was that these hidden bars were still consuming space on my page and overlapping other elements

enter image description here

so adding display:none to the hidden wrapper .hide solves the margin issue but not the transition, neither applying display:none or height:0;opacity:0 works on the children elements.

So my final workaround was to give those hidden bars a negative and absolute position and it worked well with CSS transitions.

Jsfiddle

Raja Khoury
  • 3,015
  • 1
  • 20
  • 19
0

Made some changes, but I think I got the effect you want using visibility. http://jsfiddle.net/9dsGP/49/

I also made these changes:

position: absolute; /* so it doesn't expand the button background */
top: calc(1em + 8px); /* so it's under the "button" */
left:8px; /* so it's shifted by padding-left */
width: 182px; /* so it fits nicely under the button, width - padding-left - padding-right - border-left-width - border-right-width, 200 - 8 - 8 - 1 - 1 = 182 */

Alternatively, you could put .content as a sibling of .button, but I didn't make an example for this.

Jayen
  • 5,653
  • 2
  • 44
  • 65
0

max-height

.PrimaryNav-container {
...
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease;
...
}

.PrimaryNav.PrimaryNav--isOpen .PrimaryNav-container {
max-height: 300px;
}

https://www.codehive.io/boards/bUoLvRg

Fatih Hayrioğlu
  • 3,458
  • 1
  • 26
  • 46
-1

When you need to toggle an element away, and you don't need to animate the margin property. You could try margin-top: -999999em. Just don't transition all.

Itay Grudev
  • 7,055
  • 4
  • 54
  • 86