I am trying to make a <ul>
slide down using CSS transitions.
The <ul>
starts off at height: 0;
. On hover, the height is set to height:auto;
. However, this is causing it to simply appear, not transition,
If I do it from height: 40px;
to height: auto;
, then it will slide up to height: 0;
, and then suddenly jump to the correct height.
How else could I do this without using JavaScript?
#child0 {
height: 0;
overflow: hidden;
background-color: #dedede;
-moz-transition: height 1s ease;
-webkit-transition: height 1s ease;
-o-transition: height 1s ease;
transition: height 1s ease;
}
#parent0:hover #child0 {
height: auto;
}
#child40 {
height: 40px;
overflow: hidden;
background-color: #dedede;
-moz-transition: height 1s ease;
-webkit-transition: height 1s ease;
-o-transition: height 1s ease;
transition: height 1s ease;
}
#parent40:hover #child40 {
height: auto;
}
h1 {
font-weight: bold;
}
The only difference between the two snippets of CSS is one has height: 0, the other height: 40.
<hr>
<div id="parent0">
<h1>Hover me (height: 0)</h1>
<div id="child0">Some content
<br>Some content
<br>Some content
<br>Some content
<br>Some content
<br>Some content
<br>
</div>
</div>
<hr>
<div id="parent40">
<h1>Hover me (height: 40)</h1>
<div id="child40">Some content
<br>Some content
<br>Some content
<br>Some content
<br>Some content
<br>Some content
<br>
</div>
</div>
The solution that I've always used was to first fade out, then shrink the
font-size
,padding
andmargin
values. It doesn't look the same as a wipe, but it works without a staticheight
ormax-height
.Working example:
I've recently been transitioning the
max-height
on theli
elements rather than the wrappingul
.The reasoning is that the delay for small
max-heights
is far less noticeable (if at all) compared to largemax-heights
, and I can also set mymax-height
value relative to thefont-size
of theli
rather than some arbitrary huge number by usingems
orrems
.If my font size is
1rem
, I'll set mymax-height
to something like3rem
(to accommodate wrapped text). You can see an example here:http://codepen.io/mindfullsilence/pen/DtzjE
The max-height solution from Jake works well, if the hard-coded max-height value supplied is not much bigger than the real height (because otherwise there are undesirable delays and timing problems). On the other hand if the hard-coded value accidentially is not bigger than the real height the element won't open up completely.
The following CSS only solution also requires a hard-coded size that should be bigger than most of the occurring real sizes. However this solution also works if the real size is in some situations bigger than the hard-coded size. In that event the transition might jump a bit, but it will never leave a partially visible element. So this solution could also be used for unknown content, e.g. from a database, where you just know that the content is usually not bigger than x pixels, but there are exceptions.
Idea is to use a negative value for margin-bottom (or margin-top for a slightly diffenrent animation) and to place the content element into a middle element with overflow:hidden. The negative margin of the content element so reduces the height of the middle element.
The following code uses a transition on margin-bottom from -150px to 0px. This alone works fine as long as the content element is not higher than 150px. In addition it uses a transition on max-height for the middle element from 0px to 100%. This finally hides the middle element if the content element is higher than 150px. For max-height the transition is just used to delay its application by a second when closing, not for a smooth visiual effect ( and therefore it can run from 0px to 100%).
CSS:
HTML:
The value for margin bottom should be negative and as close as possible to the real height of the content element. If it('s absoute value) is bigger there are similar delay and timing problems as with the max-height solutions, which however can be limited as long as the hard coded size is not much bigger than the real one. If the absolute value for margin-bottom is smaller than the real height the tansition jumps a bit. In any case after the transition the content element is either fully displayed or fully removed.
For more details see my blog post http://www.taccgl.org/blog/css_transition_display.html#combined_height
You should use scaleY instead.
HTML:
CSS:
I've made a vendor prefixed version of the above code on jsfiddle, http://jsfiddle.net/dotnetCarpenter/PhyQc/9/ and changed your jsfiddle to use scaleY instead of height, http://jsfiddle.net/dotnetCarpenter/7cnfc/206/.
Here's a solution I just used in combination with jQuery. This works for the following HTML structure:
and the function:
You could then use a click function to set and remove the height using
css()
CSS:
The accepted answer works for most cases, but it doesn't work well when your
div
can vary greatly in height — the animation speed is not dependent on the actual height of the content, and it can look choppy.You can still perform the actual animation with CSS, but you need to use JavaScript to compute the height of the items, instead of trying to use
auto
. No jQuery is required, although you may have to modify this a bit if you want compatibility (works in the latest version of Chrome :)).