javascripthtmlcssaccordionrotatetransform

Accordion takes 2 clicks to initiate + icon rotation


I pieced together some code I found for a FAQ accordion on my site. I am not sure how to make the title expand with 1 click, as it currently takes 2. I would also like the icon to rotate upon expanding/collapsing. It is currently only rotating on/off hover. I am including a short example of what I currently have.

Any help would be much appreciated, thank you.

  $('.js-question').on('click', function(e) {
    var $answer = $(this).next(),
      actveClass = 'active',
      isActive = $answer.hasClass(actveClass);
    $('.answer').slideUp().addClass(actveClass);
    if (isActive) {
      $answer.toggleClass(actveClass);
      $answer.slideToggle();
    }
  });
.faqContainer {
    width: 100%;
    margin-right: auto;
    margin-left: auto;
    height: 100%;
}

.question {
    font-family: Arial MT Pro!important;
    font-size: 14px;
    color: #000;
    letter-spacing: 3px;
    font-weight: 300;
    cursor: pointer;
    overflow: hidden;
    display: table-cell;
    width: 100%;
    vertical-align: middle;
}
    
.answer {
    font-family: Arial,"Helvetica Neue",Helvetica,sans-serif;
    font-size: 10px;
    line-height: 1.7;
    text-transform: uppercase;
    letter-spacing: 1px;
    color: #333;
    overflow: hidden;
    display: none;
    margin: 10px 0 15px
}
    
.answer a{
    font-family: Arial,"Helvetica Neue",Helvetica,sans-serif;
    font-size: 10px;
    line-height: 1.7;
    text-transform: uppercase;
    letter-spacing: 1px;
    color: #333!important;
}
    
.answer:hover a{
    font-family: Arial,"Helvetica Neue",Helvetica,sans-serif;
    font-size: 10px;
    line-height: 1.7;
    text-transform: uppercase;
    color: #ababab!important;
    letter-spacing: 1px;
    transition: all 0.4s ease-in-out 0s
}

.faqContainer hr {
    opacity: 0;
}

.bracket-button .outer {
    letter-spacing: 0px;
    font-family: 'Arial MT Pro';
    position: absolute;
    margin-top: 0px;
    margin-left: 8px;
}
    
.bracket-button .inner {
    display: inline-block;
    background: url(https://cdn.shopify.com/s/files/1/1547/5153/t/167/assets/cross.svg?v=1631342608) center no-repeat;
    background-size: cover;
    height: 10px;
    width: 10px;
    transform: rotate(45deg);
    transition: all 0.5s cubic-bezier(0.215,  0.61,  0.355,  1);
    padding: 0px;
    -webkit-backface-visibility: hidden;
}
    
.bracket-button:hover .inner {
    transform: rotate(135deg);
    transition: all 0.5s cubic-bezier(0.215,  0.61,  0.355,  1);
    padding: 0px;
}
    
.bracket-button.active .inner {
    transform: rotate(0deg);
    background: url(https://cdn.shopify.com/s/files/1/1547/5153/t/167/assets/cross.svg?v=1631342608) center no-repeat;
    background-size: cover;
    background-position-y: 0px;
}
    
.bracket-button.active:hover .inner {
    transform: rotate(90deg);
}
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
  <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.1/jquery-ui.min.js"></script>
<div class="faqContainer">
<p class="question js-question bracket-button">LOGISTICS<span class="outer"><span class="inner"></span></span></p>
<div class="answer">Pre-order items will ship roughly 2-3 weeks from the end date specified in the product description.<br />This can sometimes take longer due to print shop schedules/holidays.<br />All in stock orders are shipped within 48 hours of purchase, usually less.<br />Orders placed Friday evenings will typically ship the following Monday.<br />Most domestic orders are delivered within a week.<br />Please allow additional time in transit for delivery.<br /> If your order contains pre-order and in stock items,<br />your order will ship when all items are on-hand.<br />Please place separate orders if you need the in stock item(s) sooner.</div>
<hr />
<p class="question js-question bracket-button">DISCOUNTS<span class="outer"><span class="inner"></span></span></p>
<div class="answer">Domestic orders $75+ receive free shipping. <br /> Canada orders $125+ receive free shipping. <br /> Everywhere else orders $150+ receive free shipping.</div>
<hr />
<p class="question js-question bracket-button">CANCELLATIONS<span class="outer"><span class="inner"></span></span></p>
<div class="answer">If you canceled an order, expect to see the funds back in your account<br />within 2-3 business days, depending on your bank.</div>
<hr />
</div>


Solution

  • You're sending contradicting orders to your function. Here $('.answer').slideUp().addClass(actveClass); you're sliding up all of the answers and adding the active class to all of them (I believe you wanted to remove it).

    Then, you ask if the target answer has the active class (the answer is obviously yes, no matter what, because you have added it to all of the elements right before).

    This conditional if (isActive) {, even if your previous code was correct, would be completely unnecessary. What you can do remove the active class from all of answers except the target one, and then toggle the clicked answer only, which you have already targeted here $answer = $(this).next().

    So the working code would be:

    $('.js-question').on('click', function(e) {
        var $answer = $(this).next(),
          actveClass = 'active';    
        $('.answer').not($answer).slideUp().removeClass(actveClass); /* remove instead of add and apply in every answer except the clicked one*/
        /* remove unnecessary conditional */  
          $answer.toggleClass(actveClass);
          $answer.slideToggle();
      });
    .faqContainer {
        width: 100%;
        margin-right: auto;
        margin-left: auto;
        height: 100%;
    }
    
    .question {
        font-family: Arial MT Pro!important;
        font-size: 14px;
        color: #000;
        letter-spacing: 3px;
        font-weight: 300;
        cursor: pointer;
        overflow: hidden;
        display: table-cell;
        width: 100%;
        vertical-align: middle;
    }
        
    .answer {
        font-family: Arial,"Helvetica Neue",Helvetica,sans-serif;
        font-size: 10px;
        line-height: 1.7;
        text-transform: uppercase;
        letter-spacing: 1px;
        color: #333;
        overflow: hidden;
        display: none;
        margin: 10px 0 15px
    }
        
    .answer a{
        font-family: Arial,"Helvetica Neue",Helvetica,sans-serif;
        font-size: 10px;
        line-height: 1.7;
        text-transform: uppercase;
        letter-spacing: 1px;
        color: #333!important;
    }
        
    .answer:hover a{
        font-family: Arial,"Helvetica Neue",Helvetica,sans-serif;
        font-size: 10px;
        line-height: 1.7;
        text-transform: uppercase;
        color: #ababab!important;
        letter-spacing: 1px;
        transition: all 0.4s ease-in-out 0s
    }
    
    .faqContainer hr {
        opacity: 0;
    }
    
    .bracket-button .outer {
        letter-spacing: 0px;
        font-family: 'Arial MT Pro';
        position: absolute;
        margin-top: 0px;
        margin-left: 8px;
    }
        
    .bracket-button .inner {
        display: inline-block;
        background: url(https://cdn.shopify.com/s/files/1/1547/5153/t/167/assets/cross.svg?v=1631342608) center no-repeat;
        background-size: cover;
        height: 10px;
        width: 10px;
        transform: rotate(45deg);
        transition: all 0.5s cubic-bezier(0.215,  0.61,  0.355,  1);
        padding: 0px;
        -webkit-backface-visibility: hidden;
    }
        
    .bracket-button:hover .inner {
        transform: rotate(135deg);
        transition: all 0.5s cubic-bezier(0.215,  0.61,  0.355,  1);
        padding: 0px;
    }
        
    .bracket-button.active .inner {
        transform: rotate(0deg);
        background: url(https://cdn.shopify.com/s/files/1/1547/5153/t/167/assets/cross.svg?v=1631342608) center no-repeat;
        background-size: cover;
        background-position-y: 0px;
    }
        
    .bracket-button.active:hover .inner {
        transform: rotate(90deg);
    }
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
      <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.1/jquery-ui.min.js"></script>
    <div class="faqContainer">
    <p class="question js-question bracket-button">LOGISTICS<span class="outer"><span class="inner"></span></span></p>
    <div class="answer">Pre-order items will ship roughly 2-3 weeks from the end date specified in the product description.<br />This can sometimes take longer due to print shop schedules/holidays.<br />All in stock orders are shipped within 48 hours of purchase, usually less.<br />Orders placed Friday evenings will typically ship the following Monday.<br />Most domestic orders are delivered within a week.<br />Please allow additional time in transit for delivery.<br /> If your order contains pre-order and in stock items,<br />your order will ship when all items are on-hand.<br />Please place separate orders if you need the in stock item(s) sooner.</div>
    <hr />
    <p class="question js-question bracket-button">DISCOUNTS<span class="outer"><span class="inner"></span></span></p>
    <div class="answer">Domestic orders $75+ receive free shipping. <br /> Canada orders $125+ receive free shipping. <br /> Everywhere else orders $150+ receive free shipping.</div>
    <hr />
    <p class="question js-question bracket-button">CANCELLATIONS<span class="outer"><span class="inner"></span></span></p>
    <div class="answer">If you canceled an order, expect to see the funds back in your account<br />within 2-3 business days, depending on your bank.</div>
    <hr />
    </div>

    Update to have the icon working properly

    Same method as for the .answer. You remove the active class from all the buttons except the clicked one, and then toggle the clicked button class.

    $('.js-question').on('click', function(e) {
      var $answer = $(this).next(),
        actveClass = 'active';
      $('.bracket-button').not($(this)).removeClass(actveClass);
      $('.answer').not($answer).slideUp().removeClass(actveClass);
      $(this).toggleClass(actveClass);
      $answer.toggleClass(actveClass);
      $answer.slideToggle();
    });
    .faqContainer {
        width: 100%;
        margin-right: auto;
        margin-left: auto;
        height: 100%;
    }
    
    .question {
        font-family: Arial MT Pro!important;
        font-size: 14px;
        color: #000;
        letter-spacing: 3px;
        font-weight: 300;
        cursor: pointer;
        overflow: hidden;
        display: table-cell;
        width: 100%;
        vertical-align: middle;
    }
        
    .answer {
        font-family: Arial,"Helvetica Neue",Helvetica,sans-serif;
        font-size: 10px;
        line-height: 1.7;
        text-transform: uppercase;
        letter-spacing: 1px;
        color: #333;
        overflow: hidden;
        display: none;
        margin: 10px 0 15px
    }
        
    .answer a{
        font-family: Arial,"Helvetica Neue",Helvetica,sans-serif;
        font-size: 10px;
        line-height: 1.7;
        text-transform: uppercase;
        letter-spacing: 1px;
        color: #333!important;
    }
        
    .answer:hover a{
        font-family: Arial,"Helvetica Neue",Helvetica,sans-serif;
        font-size: 10px;
        line-height: 1.7;
        text-transform: uppercase;
        color: #ababab!important;
        letter-spacing: 1px;
        transition: all 0.4s ease-in-out 0s
    }
    
    .faqContainer hr {
        opacity: 0;
    }
    
    .bracket-button .outer {
        letter-spacing: 0px;
        font-family: 'Arial MT Pro';
        position: absolute;
        margin-top: 0px;
        margin-left: 8px;
    }
        
    .bracket-button .inner {
        display: inline-block;
        background: url(https://cdn.shopify.com/s/files/1/1547/5153/t/167/assets/cross.svg?v=1631342608) center no-repeat;
        background-size: cover;
        height: 10px;
        width: 10px;
        transform: rotate(45deg);
        transition: all 0.5s cubic-bezier(0.215,  0.61,  0.355,  1);
        padding: 0px;
        -webkit-backface-visibility: hidden;
    }
        
    .bracket-button:hover .inner {
        transform: rotate(135deg);
        transition: all 0.5s cubic-bezier(0.215,  0.61,  0.355,  1);
        padding: 0px;
    }
        
    .bracket-button.active .inner {
        transform: rotate(0deg);
        background: url(https://cdn.shopify.com/s/files/1/1547/5153/t/167/assets/cross.svg?v=1631342608) center no-repeat;
        background-size: cover;
        background-position-y: 0px;
    }
        
    .bracket-button.active:hover .inner {
        transform: rotate(90deg);
    }
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.1/jquery-ui.min.js"></script>
    <div class="faqContainer">
      <p class="question js-question bracket-button">LOGISTICS<span class="outer"><span class="inner"></span></span>
      </p>
      <div class="answer">Pre-order items will ship roughly 2-3 weeks from the end date specified in the product description.<br />This can sometimes take longer due to print shop schedules/holidays.<br />All in stock orders are shipped within 48 hours of purchase, usually less.<br
        />Orders placed Friday evenings will typically ship the following Monday.<br />Most domestic orders are delivered within a week.<br />Please allow additional time in transit for delivery.<br /> If your order contains pre-order and in stock items,<br
        />your order will ship when all items are on-hand.<br />Please place separate orders if you need the in stock item(s) sooner.</div>
      <hr />
      <p class="question js-question bracket-button">DISCOUNTS<span class="outer"><span class="inner"></span></span>
      </p>
      <div class="answer">Domestic orders $75+ receive free shipping. <br /> Canada orders $125+ receive free shipping. <br /> Everywhere else orders $150+ receive free shipping.</div>
      <hr />
      <p class="question js-question bracket-button">CANCELLATIONS<span class="outer"><span class="inner"></span></span>
      </p>
      <div class="answer">If you canceled an order, expect to see the funds back in your account<br />within 2-3 business days, depending on your bank.</div>
      <hr />
    </div>