Search code examples
csscss-transitionsaccordion

CSS transitions in accordion component not working


I'm not sure if I've got CSS transitions right. I'm working on an accordion component, and I just want a smooth change between the expanded and collapsed states. Here's the code:

.accordion {
  border: 1px solid #ccc;
  border-radius: 10px;
  padding: 10px;
  font-family: "Poppins";
  transition: all 1s ease-in-out;
}


.content {
  margin-top: 10px;
  overflow: hidden;
  transition: all 1s ease-in-out;
}
<div className={styles.accordion} style={accordionStyle}>
      <div className={styles.title} onClick={handleExpandClick}>
        <span>{title}</span>
        {!hideIcon && <span>{expanded ? "-" : "+"}</span>}
      </div>
      {expanded && <div className={styles.content}>{children}</div>}
    </div>

However, the accordion changes suddenly instead of using the transitions I set. What's wrong with what I'm doing?


Solution

  • You're conditionally rendering the content div using expanded. It seems like you think that the CSS transition will add a transition to the rendering/unrendering, but that's not actually how it works. As soon as expanded becomes false, <div className={styles.content}>{children}</div> stops being rendered immediately. That is completely separate from the CSS, and even if you had a proper CSS transition set up, you wouldn't see it because the content div is being renderened/unrendered instantly. Currently, nothing about your code shows any kind of transitioning effect.

    Focus on what would actually need to occur to achieve an accordion effect. The content needs to vertically shrink when it's collapsed or vertically grow when it's expanded. There are various CSS properties that can help with that (clip-path, max-height, flex, etc.). Then you just need to transition between a value that hides the content and a value that reveals it. Here's a very simple example using max-height with no consideration for padding or a proper initial height: https://codepen.io/SonicBoomNFA/pen/RwEvozJ. Hopefully that gives you a starting direction.