0

I've created a list that shows partial content and collapses with a trigger. Everything is working fine except I can't manage to make this works with CSS transition when it collapses. Basically, I toggle between 2 classes and apply a height: 100%

HTML

<div class="list">
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
    <li>Item 5</li>
    <li>Item 6</li>
    <li>Item 7</li>
    <li>Item 8</li>
    <li>Item 9</li>
    <li>Item 10</li>
    <li>Item 11</li>
    <li>Item 12</li>
    <li>Item 13</li>
    <li>Item 14</li>
  </ul>
  <span class="more-less"></span>
</div>

CSS

.list.expand {
  height: 180px;
  overflow: hidden;
}
.list.expand.open {
    height: 100%;
  padding-bottom: 20px;
}

JS

var list = $(".list");
$(".more-less").click(function() {
    list.toggleClass("open closed"); 
});

I made CODEPEN to make some tests. I think this is a specific situation that needs a specific solution. I've spent hours trying snippets found here on Stackoverflow (CSS and JS) but without success.

neither CSS transition: height .5s ease; or .animate(height...) seems to work for me :/ So, any help or clue would be much appreciated :) Thanks

EDIT: I forgot a crucial information: The list content is loaded dynamically (WP), so that's why I need to set the height to "auto".

dragoweb
  • 699
  • 1
  • 8
  • 17

3 Answers3

1

I found a better way to achieve this, with .scrollHeight

JS

var list = $(".list");

// variable storing an integer corresponding to the scrollHeight pixel value of the element.
var fullHeight = list[0].scrollHeight+'px';

if (list.height() > 100) {
  list.addClass("expand closed");
  list.height(100);
}

$(".more-less").on("click", function() {  
  if(list.hasClass("closed")) {
    list.animate({
      height: fullHeight
    }, 200);
  } else if (list.hasClass("open")) {
    list.animate({
      height: "100px"
    }, 200);
  }
  list.toggleClass("open closed");
});

CSS

.list.expand {
  overflow: hidden;
}

DEMO HERE on CodePen

dragoweb
  • 699
  • 1
  • 8
  • 17
0

have you tried to add a transition to .list.expand?

.list.expand {
  height: 180px;
  overflow: hidden;
  -webkit-transition: height 2s; /* For Safari 3.1 to 6.0 */
  -moz-transition: height 2s; 
  transition: height 2s;
}
DeDolderas
  • 13
  • 5
  • Yes that was the first I've tried. The problem is that I need to set the height to "auto" because the content is loaded dynamically. If I set the height to 300px for example, it works. I need a solution that works with height: auto. – dragoweb Jan 25 '20 at 17:13
  • Thanks but, yes, I've tried both. I think there's no pure CSS solution so I'm looking now with jQuery. slideToggle() could be an idea so I'm "investigating" right now. – dragoweb Jan 25 '20 at 23:53
0

Thanks to this post, I finally found a workaround with jQuery. Probably not the best way to achieve that, but it works :p

var list = $(".list");

// Apply only if list height is taller than 100px
if (list.height() > 100) {
    list.addClass("expand closed");
}   

// First, set height to auto then memorize the height value in a variable,
// then set the height to 100px
list.css("height", "auto");
var listheight = list.css("height");
list.css("height", "100px");

// When click to the "more-less" trigger, toggle between "open" and "closed" class,
// then apply the correct height for each class
$(".more-less").on("click", function() {
  list.toggleClass("open closed");
  if (list.hasClass("open")) {
    list.height(listheight);
  }
  if (list.hasClass("closed")) {
    list.height(100);
  }
});

CSS

.list.expand {
  height: 180px;
  overflow: hidden;
  -webkit-transition: height .3s ease-in-out;
  -moz-transition: height .3s ease-in-out;
  transition: height .3s ease-in-out;
}

DEMO HERE on CodePen

dragoweb
  • 699
  • 1
  • 8
  • 17