0

I've got a div with the ID testimonials that has a height of auto. In the div are a number of section's that vary in height. I am currently running a script that only shows one section at a time, and animates the opacity. I want to find a solution that allows for #testimonials to animate the height when a new section is displayed.

HTML Structure

<div id="testimonials">
  <section>
    <p>This is the first quote.</p>
  </section>
  <section>
    <p>This is the second quote. It is taller than the previous section.</p>
  </section>
  <section>
    <p>This is the third quote. It is even taller than the previous section two sections.</p>
  </section>
</div>

jQuery

(function() {
  var testimonials     = $("#testimonials section");
  var testimonialIndex = -1;

  function showNextTestimonial() {
    ++testimonialIndex;
    testimonials.eq(testimonialIndex % testimonials.length)
    .fadeIn(2000)
    .delay(2000)
    .fadeOut(2000, showNextTestimonial);
  }

showNextTestimonial();
})();

You can see my CodePen for a working example.


What I've Tried

Trying to use max-height to animate the height is impossible since I'm not using :hover, and that seems to be the only way to make it work. I also can't use transform: scale() for the same reason that it relies on :hover. The solutions I am finding either seem to rely on :hover, only fire on pageload, window.onresize, onclick, or something else that doesn't update when the visible section changes.

How do I animate the height of a div that's content is being changed out every 6 seconds like above?

Community
  • 1
  • 1
Matthew Beckman
  • 1,702
  • 2
  • 16
  • 28
  • Instead of using jQuery's fadeOut and fadeIn you could also toggle an active class: if it's active the height is auto and if its not active the height is 0px. Then just put a transition on the section. – Melvin Koopmans Feb 21 '17 at 07:15
  • @MelvinKoopmans **CSS3** doesn't support transitioning to `height: auto` from anything. If you try it in just CSS, it will go immediately from 0 to the value computed for `auto`, which is no different than what is happening now. I'm definitely open to toggling a class instead of using `fadeIn` and `fadeOut`. – Matthew Beckman Feb 21 '17 at 07:22
  • 1
    Ah yeah you're right. My mistake. What you could do is generate an array with the heights of each section and loop through those when changing items. – Melvin Koopmans Feb 21 '17 at 07:29

2 Answers2

1

Animate the height of the #testimonials with the displayed section height.

(function() {
    var testimonials = $("#testimonials section");
    var testimonialIndex = -1;

    function showNextTestimonial() {
        ++testimonialIndex;
        var section = testimonials.eq(testimonialIndex % testimonials.length);

        section.fadeIn(2000);

        $("#testimonials").animate({
            height: section.outerHeight(true)
        }, 2000);

        section.fadeOut(2000, showNextTestimonial);
    }

    showNextTestimonial();
})();

You may want to add overflow: auto to section to prevent margin collapse with p inside

section {
    display: none;
    overflow: auto;
}
Bigdragon
  • 352
  • 1
  • 4
  • 16
0

I have came closer to the solution but the issue is with callbacks, and there's a slight delay with the height update.

(function() {
  var h = $("#testimonials section");
  var testimonials     = $("#testimonials section p");
  var testimonialIndex = -1;

  function showNextTestemonial() {
    ++testimonialIndex;
  
   
  testimonials.eq(testimonialIndex % testimonials.length )
    .fadeIn(function(){h.height($(this).innerHeight());})
    .delay(2000)
    .fadeOut(showNextTestemonial);
  }

showNextTestemonial();
})();
section p{
  display: none;
}
section {
  -webkit-transition: height 0.3s ease;
  -moz-transition: height 0.3s ease;
  -o-transition: height 0.3s ease;
  transition: height 0.3s ease;
}
#testimonials {
  width: 100px;
  color: white;
  padding: 10px;
  margin: 0 auto;
  background: red;
  -webkit-transition: height 0.3s ease;
  -moz-transition: height 0.3s ease;
  -o-transition: height 0.3s ease;
  transition: height 0.3s ease;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="testimonials">
  <section>
    <p>This is the first quote.</p>
     <p>This is the second quote. It is taller than the previous section.</p>
    <p>This is the third quote. It is even taller than the previous section two sections.</p>
  </section>
 
</div>

Hope that helps. I have saved a fork of your Codepen to play around Here

Saurabh Sharma
  • 2,422
  • 4
  • 20
  • 41
  • This solution only keeps one `section` from the HTML structure. I needed those additional `section` elements. Otherwise it would have worked for me. Appreciate the effort. – Matthew Beckman Feb 21 '17 at 08:19