Animate accordion plugin with auto height

472 Views Asked by At

I am using a very lightweight plugin for an accordion which is great but I can't get it to animate without a fixed height.

I initially tried the usual transitions before realising they did not work with auto height

I tried modifying some JS I found but this did not work

var headers = document.querySelectorAll('.aab__accordion_head');

for (var i=0; i<headers.length; i++) {
  headers[i].addEventListener('click', toggleDisplay);
}

function toggleDisplay() {
  if (this.parentNode.classList.contains('aab__accordion_body--show')) {
    var currentlyDisplayed = document.querySelectorAll('.aab__accordion_body--show');
    for (var e=0; e<currentlyDisplayed.length; e++) {
      currentlyDisplayed[e].classList.remove('aab__accordion_body--show');
    } 
  } else {
    this.closest('.aab__accordion_body').classList.add('aab__accordion_body--show');
  }
}

I also tried a suggestion of using ScaleY like this

.wp-block-aab-accordion-block .aab__accordion_body {
    transform: scaleY(0);
    display: 
    transition: scale 300ms ease-in-out !important; 

}


.wp-block-aab-accordion-block .aab__accordion_body.aab__accordion_body--show {
    transform: scaleY(1);
    transition: scale 300ms ease-in-out !important; 
}

But this still reserves the space where it should be and doesn't work.

I've tried this too but with no luck

.aab__accordion_container  {
    display: grid !important;
}

.aab__accordion_head:hover + .aab__accordion_body--show {
    display: flex !important;
    flex-direction: column !important;
}

.aab__accordion_container p {
    flex-basis: 0;
    overflow: hidden;
    transition: 1s;
}

I will actually have Gutenberg blocks in there too but I just thought i would test to see if I could get the

to show

I wold post all the other code but I'm finding it difficult as I didn't write it.

Essentially the basic structure for 1 - Each accordion container 2- The heading container that always shows 3 - The heading that you click 4 - The content is:

<div class=".aab__accordion_container">
   <div class=".aab__accordion_head">
      <div class=".aab__accordion_heading .aab_right_icon">
        <h4>the heading</h4>
      </div>
   </div>
   <div class=".aab__accordion_body">
      The content
    </div>
</div>

An active accordion gets the class

.aab__accordion_body--show

added to

.aab__accordion_body

Any help would be appreciated

Thanks

EDIT

So I managed to get it working by editing this JS

// jQuery accordion
;(function($){
    $( ".wp-block-aab-accordion-block" ).accordion({
      collapsible: true,
      active : 'none',
      header: ".aab__accordion_head",
      heightStyle: "content",
      activate: function( event, ui ) {
        if(!$.isEmptyObject(ui.newHeader.offset())) {
          if ($(window).width() > 767) {
            $('html:not(:animated), body:not(:animated)').animate({ scrollTop: ui.newHeader.offset().top -180 }, 'slow');
          }
          else {
            $('html:not(:animated), body:not(:animated)').animate({ scrollTop: ui.newHeader.offset().top -50 }, 'slow');
          }
        }
      }
    });
})(jQuery);

Credit to this website https://titus-design.com/custom-accordion-gutenberg-block-using-advanced-custom-fields/

I just have to work out how to override the plugin JS now...

1

There are 1 best solutions below

11
PsiKai On

The only issue with transitioning scaleY is that the element will still take up it's full height in the flow of elements, leaving a space where you don't want it.

Transitioning to a height: auto is not possible with CSS (as I'm sure you know) but there is a hacky workaround I have used in the past for such situations.

Make use of the max-height property. You will have to set a fixed value on the max-height, but the element will still only have a height of its content if you set max-height to a value larger than you expect the largest element to be.

Something like this:

.wp-block-aab-accordion-block .aab__accordion_body {
    max-height: 0;
    transition: max-height 300ms ease-in-out !important; 
}


.wp-block-aab-accordion-block .aab__accordion_body.aab__accordion_body--show {
    max-height: 1000px;
}

Notice, that you only need the transition property on the base class, and you only need to modify the max-height on the added class.

As a note, your implementation of scaleY will not work because of your transition property. If you want to use scaleY, change it to be like this:

.wp-block-aab-accordion-block .aab__accordion_body {
    transform: scaleY(0);
    transition: transform 300ms ease-in-out !important; 
}


.wp-block-aab-accordion-block .aab__accordion_body.aab__accordion_body--show {
    transform: scaleY(1); 
}

The transition is on transform, not on scale. scaleY is the type of transform, but you can only apply transition on the property itself, not its values.