Home > Software engineering >  Animate height (auto) when items are displayed (on click) if taller than initial value
Animate height (auto) when items are displayed (on click) if taller than initial value

Time:08-31

I have a list with icons, when the icons are clicked the text is revealed. This works - just using opacity and toggling a class. But the problem is if the text wraps over one line, you get space between each of the icons.

I've tried toggling between display: none / block which does collapse the space ...but then the content 'jumps' into view.

Is there a way once the content is displayed with .visible as well as fading in, the height could also animate smoothly pushing the rest of the content down?

$('.list-numbers--reveal li').click(function() {
  $(this).toggleClass('visible');
});
.list-numbers {
  counter-reset: li;
  line-height: 1.25;
  list-style: none;
}

.list-numbers li {
  display: flex;
  min-height: 24px;
  margin-bottom: 12px;
  position: relative;
  text-decoration: none;
  text-shadow: none;
}

.list-numbers li:before {
  background: black;
  border-radius: 100%;
  color: white;
  content: counter(li);
  counter-increment: li;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 14px;
  height: 24px;
  line-height: 14px;
  margin-right: 8px;
  position: relative;
  top: -2px;
  width: 24px;
}

.list-numbers--reveal li {
  cursor: pointer;
}

.list-numbers--reveal li span {
  opacity: 0;
  transition: opacity .12s;
}

.list-numbers--reveal li.visible span {
  opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>

<ol >
  <li><span>Lorem</span></li>
  <li><span>Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</span></li>
  <li><span>Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</span></li>
  <li><span>Duis aute irure</span></li>
</ol>

CodePudding user response:

To do what you require you can use the max-height property. Note you need to use max-height here and not height as height: auto cannot be animated.

Set the max-height to a setting around one line in height (to avoid a delay before the animation starts) and set it to a value much larger than your content will ever be when the class is applied.

Here's a working example - note that I slowed the animation speed down to make the effect noticeable:

$('.list-numbers--reveal li').click(function() {
  $(this).toggleClass('visible');
});
.list-numbers {
  counter-reset: li;
  line-height: 1.25;
  list-style: none;
}

.list-numbers li {
  display: flex;
  min-height: 24px;
  margin-bottom: 12px;
  position: relative;
  text-decoration: none;
  text-shadow: none;
}

.list-numbers li:before {
  background: black;
  border-radius: 100%;
  color: white;
  content: counter(li);
  counter-increment: li;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 14px;
  height: 24px;
  line-height: 14px;
  margin-right: 8px;
  position: relative;
  top: -2px;
  width: 24px;
}

.list-numbers--reveal li {
  cursor: pointer;
}

.list-numbers--reveal li span {
  opacity: 0;
  max-height: 25px;
  display: block;
  transition: all 1s ease;
  transition-property: opacity max-height;
}

.list-numbers--reveal li.visible span {
  opacity: 1;
  max-height: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>

<ol >
  <li><span>Lorem</span></li>
  <li><span>Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</span></li>
  <li><span>Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</span></li>
  <li><span>Duis aute irure</span></li>
</ol>

CodePudding user response:

Jquery has some methods which can help with this such as .slideDown() and .one() (which is an event listener which executes exactly one time).

$('.list-numbers--reveal li').click(function() {
  const $span = $(this).find('span');
  if ($span.hasClass('visible')) {
    $span.removeClass('visible').one('transitionend', function() {
      $span.slideUp();
    });
  } else {
    $span.slideDown(400, function() {
      $(this).addClass('visible');
    })
  }

});
.list-numbers {
  counter-reset: li;
  line-height: 1.25;
  list-style: none;
}

.list-numbers li {
  display: flex;
  min-height: 24px;
  margin-bottom: 12px;
  position: relative;
  text-decoration: none;
  text-shadow: none;
}

.list-numbers li:before {
  background: black;
  border-radius: 100%;
  color: white;
  content: counter(li);
  counter-increment: li;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 14px;
  height: 24px;
  line-height: 14px;
  margin-right: 8px;
  position: relative;
  top: -2px;
  width: 24px;
}

.list-numbers--reveal li {
  cursor: pointer;
}

.list-numbers--reveal li span {
  display: none;
  opacity: 0;
  transition: opacity .12s;
}

.list-numbers--reveal span.visible {
  opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>

<ol >
  <li><span>Lorem</span></li>
  <li><span>Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</span></li>
  <li><span>Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</span></li>
  <li><span>Duis aute irure</span></li>
</ol>

  • Related