0

I'm trying to create a simple javascript accordion. All is good, except there is a slight jolt when one tab is open and you click to open another (in turn closing the previous one that was open).

I can't understand what is causing this issue. Feel like I'm going round in circles. If anyone can provide some assistance I'd be most grateful.

The issue is easier to see in this codepen

function initAcc(elem, option){
    document.addEventListener('click', function (e) {
        if (!e.target.matches(elem+' .accordion-toggle')) return;
        else{
            if(!e.target.parentElement.classList.contains('active')){
                if(option==true){
                    var elementList = document.querySelectorAll(elem+' .accordion__container');
                    Array.prototype.forEach.call(elementList, function (e) {
                        e.classList.remove('active');
                    });
                }            
                e.target.parentElement.classList.add('active');
            }else{
                e.target.parentElement.classList.remove('active');
            }
        }
    });
    }

    initAcc('.accordion-wrapper', true);
.accordion-wrapper .accordion-toggle {
    position: relative;
    cursor: pointer;
    padding: 20px 0;
    margin: 0;
    border-top: 1px solid; }

.accordion-wrapper .accordion-toggle .accordion-closed {
    display: block; }

.accordion-wrapper .accordion-toggle .accordion-closed:after {
    content: '+';}

.accordion-wrapper .accordion-toggle .accordion-open:after {
    content: '-'; }

.accordion-wrapper .accordion-toggle .accordion-open {
    display: none; }

.accordion-wrapper .accordion-toggle.border-top {
    border-color: rgba(0,0,0,0.15); }

.accordion-wrapper .accordion-toggle span {
    pointer-events: none; }


.accordion-wrapper .accordion__container.border-bottom {
    border-bottom: 1px solid rgba(0,0,0,0.15); }

.accordion-wrapper .accordion__container.active .accordion-toggle .accordion-closed {
    display: none; }

.accordion-wrapper .accordion__container.active .accordion-toggle .accordion-open {
    display: block; }

.accordion-wrapper .accordion-toggle .accordion-open,
.accordion-wrapper .accordion-toggle .accordion-closed {
    float: right; }

.accordion-wrapper .accordion-content {
    position: relative;
    transition: all 0.3s ease-in-out;
    opacity: 0;
    max-height: 0;
    width: 100%;
    opacity: 0;
    height: auto;
    max-height: 0;
    overflow: hidden;} 

.accordion-wrapper .accordion__container.active .accordion-content {               
    opacity: 1;
    max-height: 600px; } }
<div class="accordion-wrapper">
  <div class="accordion__container">
    <p class="accordion-toggle border-top">Toggle 1
      <span class="accordion-closed"></span>
      <span class="accordion-open"></span>
    </p>
    <div class="accordion-content">
      Content 1.
    </div>
  </div>
  <div class="accordion__container">
    <p class="accordion-toggle">Toggle 2
      <span class="accordion-closed"></span>
      <span class="accordion-open"></span>
    </p>
    <div class="accordion-content">
      Content 2.
    </div>
  </div>
  <div class="accordion__container">
    <p class="accordion-toggle">Toggle 3
      <span class="accordion-closed"></span>
      <span class="accordion-open"></span> 
    </p>
    <div class="accordion-content">
      Content 3.
    </div>
  </div>
</div>
user2498890
  • 1,528
  • 4
  • 25
  • 58
  • Even though your question is marked closed, I'd still comment that the problem I observed is in the animation `ease-in-out`. When other panel is opening, its content eases-in in 0.3s. Meanwhile, previous panel's content eases out in those 0.3s. The height of previous content won't become 0 immediately, hence the jolt. So I'd suggest applying `ease-in` animation on the `.active` 's content. [Codepen](https://codepen.io/sanamumtaz/pen/KKmmMyx) – Sana Mumtaz Jul 16 '21 at 14:51
  • The problem hs nothing to do with easing, it's because they are trying to animate `600px` of height change (~580 of which are extraneous) in `0.3s`. – lawrence-witt Jul 16 '21 at 14:52
  • @lawrence-witt Thanks for your response, would you advise using a different approach? Could you provide any examples to get the desired effect? – user2498890 Jul 19 '21 at 14:05
  • In my experience (I've implemented one or two of these), the only way to get a perfectly smooth and auto-height-finding transition is to use JavaScript. Grab the computed `height` of the content (don't manually set it to zero) and add it directly on the container, then use a ResizeObserver to keep the container updated if/when the content reflows. There are lots of creative CSS alternatives with demos in the thread that has been linked for you, whether any of them will be satisfactory for you is subjective. The thread also has pointers on how to go about implementing this with JS. – lawrence-witt Jul 19 '21 at 17:41

0 Answers0