DEV Community

Mykolas Mankevicius
Mykolas Mankevicius

Posted on

CSS Only Accordion with animations

These days CSS has a lot of cool features and you can really do a lot without javascript!

I though we have all the parts for creating an animating accordion. So set off to do it, here's what i've come up with:

<div class="bg-slate-700 text-white">
  <div>
    <details class="group peer">
      <summary class="flex cursor-pointer justify-between px-4 py-5">
        <h2 class="text-body-1">Title 1</h2>
        <svg class="inline-block h-6 w-6 transition-transform group-open:rotate-180" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5">
          <polyline points="6 9 12 15 18 9"></polyline>
        </svg>
      </summary>
    </details>
    <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-300 peer-open:grid-rows-[1fr]">
      <ul class="overflow-hidden">
        <li class="px-4 py-2">Item 1</li>
        <li class="px-4 py-2">Item 2</li>
      </ul>
    </div>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

TL; DR; Play around with the code here:

https://play.tailwindcss.com/uUGBz7pYh9

Here's an explanation:

  • First we have a wrapper div, we really only need this to group this together in our minds or when using with other things to have one group rather than two root elements.
  • <details> component is a nice way to have an accordion without any javascript, but it lacks a way to animate the content.
    • we use the group class so that we can animate the icon
    • we use the peer class so that we can animate the content
    • we can't use the slot as it would only animate the open state, also couldn't even get that to work nicely hence we create a sibling.
  • the sibling <div> uses the grid-template-rows to animate the height from 0 to auto, this alone is a cool CSS trick.
    • the first child has to have the overflow-hidden class as otherwise the 0fr will show the content.
  • there is a few lines of custom css to hide the native arrow

Top comments (0)