Animating max-height with CSS transitions

I want to create an expand/collapse animation that's powered only by classnames (javascript is used to toggle the classnames).

I'm giving one class max-height: 4em; overflow: hidden;

and the other max-height: 255em; (I also tried the value none, which didn't animate at all)

this to animate: transition: max-height 0.50s ease-in-out;

I used CSS transitions to switch between them, but the browser seems to be animating all those extra em's, so it creates a delay in the collapse effect.

Is there a way of doing it (in the same spirit - with css classnames) that doesn't have that side-effect (I can put a lower pixel count, but that obviously has drawbacks, since it might cut off legit text - that's the reason for the big value, so it doesn't cut off legit long text, only ridiculously long ones)

See the jsFiddle - http://jsfiddle.net/wCzHV/1/ (click on the text container)


Solution 1:

Fix delay solution:

Put cubic-bezier(0, 1, 0, 1) transition function for element.

scss

.text {
  overflow: hidden;
  max-height: 0;
  transition: max-height 0.5s cubic-bezier(0, 1, 0, 1);

  &.full {
    max-height: 1000px;
    transition: max-height 1s ease-in-out;
  }
}

css

.text {
  overflow: hidden;
  max-height: 0;
  transition: max-height 0.5s cubic-bezier(0, 1, 0, 1);
}

.text.full {
  max-height: 1000px;
  transition: max-height 1s ease-in-out;
}

Solution 2:

This is an old question but I just worked out a way to do it and wanted to stick it somewhere so I know where to find it should I need it again :o)

So I needed an accordion with clickable "sectionHeading" divs that reveal/hide corresponding "sectionContent" divs. The section content divs have variable heights, which creates a problem as you can't animate height to 100%. I've seen other answers suggesting animating max-height instead but this means sometimes you get delays when the max-height you use is larger than the actual height.

The idea is to use jQuery on load to find and explicitly set the heights of the "sectionContent" divs. Then add a css class 'noHeight' to each a click handler to toggle it:

$(document).ready(function() {
    $('.sectionContent').each(function() {
        var h = $(this).height();
        $(this).height(h).addClass('noHeight');
    });
    $('.sectionHeader').click(function() {
        $(this).next('.sectionContent').toggleClass('noHeight');
    });
});

For completeness, the relevant css classes:

.sectionContent {
    overflow: hidden;
    -webkit-transition: all 0.3s ease-in;
    -moz-transition: all 0.3s ease-in;
    -o-transition: all 0.3s ease-in;
    transition: all 0.3s ease-in;
}
.noHeight {
        height: 0px !important;
}

Now the height transitions work without any delays.