Preblocks

Build an Animated Accordion with <details> and Tailwind CSS

Learn how to build an animated accordion using the HTML details and summary elements with Tailwind CSS v4 for better SEO and zero JavaScript.

Written by Rin

Build an Animated Accordion with <details> and Tailwind CSS

Table of Contents

Accordions are a staple of modern UI design, perfect for organizing FAQs, product details, and complex menus. However, most implementations rely heavily on JavaScript libraries. While functional, these JS-first solutions often introduce SEO challenges.

In this guide, we will build an accordion using pure HTML elements. By leveraging the modern ::details-content pseudo-element and Tailwind CSS, we can achieve smooth animations without JavaScript, that looks like the interactive demo below:

Is it accessible?

Yes. It uses semantic HTML elements with built-in accessibility.

Is it styled?

Yes. It comes with default styles that matches the other components’ aesthetic.

Is it animated?

Yes. It uses the new ::details-content pseudo-element for smooth animations.

If you using React and shadcn/ui design system, you can install with shadcn CLI or get the source code of the above component.

The reason why I didn’t use JavaScript to build accordion

I recently faced a challenge while using the accordion component from the popular shadcn/ui library. While beautiful, it relies on Radix UI primitives to manage state and rendering.

Comparison: HTML Elements vs. JavaScript Libraries

Let’s examine the key differences and their implications:

Initial HTML & SEO Impact

  • HTML: Content exists in raw HTML from server delivery, ensuring guaranteed crawling and indexing.
  • JavaScript: Content typically injected only after client-side hydration, risking missed indexing.

Indexing & Crawl Budget

  • HTML: Content is immediately available - zero JS execution needed.
  • JavaScript: Depends on JS rendering - consumes crawl budget, causes delays.

Semantic Structure & Accessibility

  • HTML: Native semantics. The <details> and <summary> elements provide built-in accessibility.
  • JavaScript: Relies on synthetic semantics. Uses generic elements (<div>, <button>) enhanced with manual ARIA (aria-expanded, aria-controls).

Implementation: Building the animated accordion

Now, let’s apply this understanding by building the component. We’ll create a solution that leverages the SEO and accessibility advantages of HTML elements while delivering the polished animations expected from modern UI.

Step 1: The semantic HTML elements

The foundation is simple. We use the <details> element as the container and <summary> as the trigger.

<details name="faq">
  <summary>Is it accessible?</summary>
  <p>Yes. It uses semantic HTML elements with built-in accessibility.</p>
</details>

Note the name="faq" attribute. This is a newer HTML feature. When multiple <details> elements share the same name, the browser automatically closes other open items when a new one is toggled—replicating “accordion” behavior natively.

Step 2: Styling with Tailwind CSS

First, let’s make it look professional. We remove the default browser marker (the ugly triangle) using list-none and add our own custom SVG icon.

Is it accessible?

Yes. It uses semantic HTML elements with built-in accessibility.

Show code
<details class="group border-b last:border-none w-full max-w-md">
  <summary class="list-none flex items-center justify-between py-4">
    <p class="font-semibold">Is it accessible?</p>
    <svg class="size-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
    </svg>
  </summary>
  <p class="pb-4 text-muted-foreground">Yes. It uses semantic HTML elements with built-in accessibility.</p>
</details>

Step 3: Animating with transition

This is a copy-paste ready solution, and we will analyze these classes to see what they do.

Is it styled?

Yes. It comes with default styles.

Is it animated?

Yes. It uses the new ::details-content pseudo-element for smooth animations.

Show code
<details class="group border-b last:border-none w-full max-w-md details-content:transition-all details-content:transition-discrete details-content:h-0 details-content:overflow-clip open:details-content:h-auto" name="faq">
  <summary class="list-none flex items-center justify-between py-4">
    <p class="font-semibold">Is it styled?</p>
    <svg class="size-4 transition-transform group-open:rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
    </svg>
  </summary>
  <p class="pb-4 text-muted-foreground">Yes. It comes with default styles.</p>
</details>

Animating the marker

We can animate the marker using the group-open class after adding group to <details>. Like the most common group-open:rotate-180 rotate icon, and add transition-transform transition.

Transition with ::details-content pseudo-class

In modern CSS, we have the ::details-content pseudo-class, which represents the content of a <details> element when it is open. We can use this pseudo-class to create smooth animations:

  1. details-content:h-0: The content is zero height by default (even while closed).
  2. open:details-content:h-auto: When the open attribute is present, the height calculates to auto.
  3. details-content:transition-discrete: This is crucial. It allows the browser to transition properties that normally toggle instantly (like display or intrinsic height) by enabling discrete animation capability.
  4. details-content:overflow-clip: Prevents content from spilling out during the collapse animation.

In the browser versions released after 2025, the pseudo-class is supported, such as Chrome 131 (released in November 2024), Safari 18.4 (released in March 2025), and Firefox 143 (released in September 2025). Of course, if the browser does not support it, it will not affect the work, just that the visitor will not see the transition animation.

Conclusion

The journey of web development is often about finding simpler, more robust solutions. By leaning into the native capabilities of HTML and modern CSS, we can build components that are inherently more accessible, performant, and search-engine friendly.

Key Takeaways

  • SEO & Performance: Using <details> ensures your content is present in the initial HTML payload. This guarantees discoverability by search engines and provides instant content to users, without waiting for JavaScript to hydrate.
  • Accessibility: The semantic meaning of <details> and <summary> is understood by browsers and assistive technologies by default, providing a more reliable experience than ARIA-enhanced <div> structures.
  • Modern CSS: The ::details-content pseudo-class, combined with utilities like transition-discrete, unlocks smooth native animations that were once the exclusive domain of JavaScript. This reduces your bundle size and complexity.
  • Progressive Enhancement: This approach works everywhere. In browsers that support the new pseudo-class, users get a slick animation. In older browsers, they get a perfectly functional, instantly opening accordion. The core experience is never broken.

Next Steps & Resources