# Animate an accordion with CSS while keeping it usable To add subtle animation to an accordion, make the disclosure work first, then enhance the opening. A native details element can provide the basic show/hide interaction without JavaScript. The example below animates the visible content on opening; it does not animate the closing height. ## Start with a useful disclosure Choose a label that tells people what they will find. Keep information needed for a decision visible rather than hiding it merely to shorten the page. For an optional download question, “What is included?” can be a meaningful label. MDN documents details and summary as a native disclosure. The W3C accordion pattern describes a custom alternative with its own keyboard and state requirements. Do not copy ARIA attributes from that custom pattern onto a native element without understanding why they are needed. ## Original HTML example ```html
What is included?

The download contains instructions, examples and setup steps.

Read the setup steps
``` This example is ordinary HTML, not a complete design system. The destination assumes the setup page exists. The contents remain available when JavaScript is disabled. ## Add a small opening effect ```css .download-question summary { cursor: pointer; } .download-question summary:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; } .download-question[open] .answer { animation: answer-in 160ms ease-out; } @keyframes answer-in { from { opacity: 0.7; transform: translateY(-2px); } to { opacity: 1; transform: translateY(0); } } @media (prefers-reduced-motion: reduce) { .download-question[open] .answer { animation: none; } } ``` The duration and distance are starting design choices. The content starts mostly visible rather than waiting behind a long reveal. Closing uses the browser's immediate native behavior. If you need a height transition in both directions, that is a separate implementation to evaluate; this snippet does not claim to provide it. ## Keep state separate from the effect The open attribute determines whether the disclosure is open. The animation is presentation. Do not delay the state change until an animation callback finishes, and do not leave an opacity or transform style that hides the final content. If your site removes the native marker, provide another understandable indication of the disclosure state. Keep focus visible on the summary. A pointer-only animation does not establish that a keyboard user can reach the content or its links. ## Try the complete interaction | Action | What to inspect | | --- | --- | | Tab to the summary and activate it | Disclosure opens and focus stays visible | | Open and close rapidly | Final state follows the last action | | Tab into an open answer | Its link is reachable | | Close the disclosure | Hidden descendants are not reached in ordinary tab order | | Enable reduced motion | Contents appear without the movement | | Disable JavaScript | Disclosure and link still work | Use the browser and input methods your page needs to support. A custom component has different obligations from this native example, especially when it manages focus or hides content with CSS rather than native disclosure state. ## Give your coding AI the constraint Ask it to preserve the existing disclosure semantics, add an opening effect only, and explain what happens without animation. Have it show the reduced-motion rule and any cleanup required by scripts. Then test the actual page; reading generated CSS is not a substitute for checking the interaction. --- SkillStall · 2026-10-03 MDN: The details disclosure element: https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/details W3C WAI: Accordion pattern: https://www.w3.org/WAI/ARIA/apg/patterns/accordion/ MDN: prefers-reduced-motion: https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@media/prefers-reduced-motion