Search code examples
htmlcssaccordionjquery-ui-accordion

Animated accordion - panel padding (top, bottom) breaks design


In the following animated accordion (it's from W3 school https://www.w3schools.com/howto/howto_js_accordion.asp), I'm finding that adding big top+bottom padding to panel breaks design.

so instead of

.panel {
  padding: 0 18px; 
} 

doing the following

.panel {
  padding: 22px 18px; 
} 

leads to

enter image description here

You can see a bit of text in panel, which is not OK.

Is there a way to fix this here so that top/bottom padding for panel isn't shown when it's not clicked on. i.e. you see it only when it's clicked

<style>
.accordion {
  background-color: #eee;
  color: #444;
  cursor: pointer;
  padding: 18px;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
  transition: 0.4s;
}

.active, .accordion:hover {
  background-color: #ccc;
}

.panel {
  padding: 0 18px;
  background-color: white;
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.2s ease-out;
}
</style>
</head>
<body>

<h2>Animated Accordion</h2>
<p>Click on the buttons to open the collapsible content.</p>

<button class="accordion">Section 1</button>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, 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.</p>
</div>

<button class="accordion">Section 2</button>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, 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.</p>
</div>

<button class="accordion">Section 3</button>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, 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.</p>
</div>

<script>
var acc = document.getElementsByClassName("accordion");
var i;

for (i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function() {
    this.classList.toggle("active");
    var panel = this.nextElementSibling;
    if (panel.style.maxHeight) {
      panel.style.maxHeight = null;
    } else {
      panel.style.maxHeight = panel.scrollHeight + "px";
    } 
  });
}
</script>

</body>
</html>

Solution

  • Since you already are using JS to achieve the changes applied to the text-fields when your panels are active, you can basically just include the padding-changes too and make the transition smooth for everything. The example-Snippet below is commented where i made changes and what / why i made them.

    var acc = document.getElementsByClassName("accordion");
    var i;
    
    for (i = 0; i < acc.length; i++) {
      acc[i].addEventListener("click", function() {
        this.classList.toggle("active");
        var panel = this.nextElementSibling;
        if (panel.style.maxHeight) {
          panel.style.maxHeight = null;
          //add padding-changes, same as base-padding
          panel.style.padding = "0px 18px";
        } else {
          panel.style.maxHeight = panel.scrollHeight + "px";
          //add padding-changes you want to apply when active
          panel.style.padding = "22px 18px";
        } 
      });
    }
    .accordion {
      background-color: #eee;
      color: #444;
      cursor: pointer;
      padding: 18px;
      width: 100%;
      border: none;
      text-align: left;
      outline: none;
      font-size: 15px;
      transition: 0.4s;
    }
    
    .active, .accordion:hover {
      background-color: #ccc;
    }
    
    .panel {
      /*keep this as the base-padding you want*/
      padding: 0 18px;
      background-color: white;
      max-height: 0;
      overflow: hidden;
      /*Make transition changes to "all" so it affects height and padding*/
      transition: all 0.2s ease-out;
    }
    <body>
    
    <h2>Animated Accordion</h2>
    <p>Click on the buttons to open the collapsible content.</p>
    
    <button class="accordion">Section 1</button>
    <div class="panel">
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, 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.</p>
    </div>
    
    <button class="accordion">Section 2</button>
    <div class="panel">
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, 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.</p>
    </div>
    
    <button class="accordion">Section 3</button>
    <div class="panel">
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, 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.</p>
    </div>