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>
Here's a way to transition from any starting height, including 0, to auto (full size and flexible) without requiring hard-set code on a per-node basis or any user-code to initialize: https://github.com/csuwildcat/transition-auto. This is basically the holy grail for what you want, I believe --> http://codepen.io/csuwldcat/pen/kwsdF. Just slap the following JS file into your page, and all you need to do after that is add/remove a single boolean attribute -
reveal=""
- from the nodes you want to expand and contract.Here's all you need to do as the user, once you include the code block found below the example code:
Here's the code block to include in your page, after that, it's all gravy:
Drop this JS file in your page - it all Just Works™
/* Code for height: auto; transitioning */
/* Code for DEMO */
No hard coded values.
No JavaScript.
No approximations.
The trick is to use a hidden & duplicated
div
to get the browser to understand what 100% means.This method is suitable whenever you're able to duplicate the DOM of the element you wish to animate.
As I post this there are over 30 answers already, but I feel my answer improves on the already accepted answer by jake.
I was not content with the issue that arises from simply using
max-height
and CSS3 transitions, since as many commenters noted, you have to set yourmax-height
value very close to the actual height or you'll get a delay. See this JSFiddle for an example of that problem.To get around this (while still using no JavaScript), I added another HTML element that transitions the
transform: translateY
CSS value.This means both
max-height
andtranslateY
are used:max-height
allows the element to push down elements below it, whiletranslateY
gives the "instant" effect we want. The issue withmax-height
still exists, but its effect is lessened. This means you can set a much larger height for yourmax-height
value and worry about it less.The overall benefit is that on the transition back in (the collapse), the user sees the
translateY
animation immediately, so it doesn't really matter how long themax-height
takes.Solution as Fiddle
Ok, so I think I came up with a super simple answer... no
max-height
, usesrelative
positioning, works onli
elements, & is pure CSS. I have not tested in anything but Firefox, though judging by the CSS, it should work on all browsers.FIDDLE: http://jsfiddle.net/n5XfG/2596/
CSS
HTML
Use
max-height
in the transformation and notheight
. And set a value onmax-height
to something bigger than your box will ever get.See JSFiddle demo provided by Chris Jordan in another answer here.
You can't currently animate on height when one of the heights involved is
auto
, you have to set two explicit heights.