No animations match your search in this category.
The code for all 4 accordions, explained
Every effect above, with the markup to use and the complete CSS. Each one is self-contained: paste the CSS once, add the class, done.
Smooth Accordion
Height auto can't be transitioned — but grid-template-rows 0fr → 1fr can. That's the modern trick for smooth accordions with no fixed max-height guesswork. The checkbox stays keyboard-focusable (Space toggles it); for proper button semantics use native details or a button with aria-expanded, as in our accordion animation recipe.
Markup
<div class="fh-accordion">
<input type="checkbox" id="q1" />
<label class="fh-acc-head" for="q1">Question?</label>
<div class="fh-acc-body"><div>
<p>Answer content…</p>
</div></div>
</div>
CSS
.fh-accordion {
position: relative;
border: 1px solid #3a4358;
border-radius: 10px;
overflow: hidden;
}
/* Hidden visually but still focusable: display: none would
make the accordion impossible to open from the keyboard */
.fh-accordion input {
position: absolute;
opacity: 0;
pointer-events: none;
}
.fh-accordion input:focus-visible + .fh-acc-head {
outline: 2px solid #22d3ee;
outline-offset: -2px;
}
.fh-acc-head {
display: block;
padding: 12px 16px;
font-weight: 600;
cursor: pointer;
background: rgba(255, 255, 255, 0.04);
}
.fh-acc-body {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}
.fh-acc-body > div { overflow: hidden; }
.fh-acc-body p { padding: 12px 16px; margin: 0; opacity: 0.75; }
.fh-accordion input:checked ~ .fh-acc-body {
grid-template-rows: 1fr;
}
Chevron Rotate
Native gives you the open/close behaviour and accessibility for free — the [open] attribute selector drives the rotation.
Markup
<details class="fh-details">
<summary>Question? <span class="fh-acc-chevron">▾</span></summary>
<p>Answer…</p>
</details>
CSS
.fh-details {
border: 1px solid #3a4358;
border-radius: 10px;
padding: 0 16px;
}
.fh-details summary {
display: flex;
justify-content: space-between;
align-items: center;
gap: 10px;
padding: 12px 0;
cursor: pointer;
font-weight: 600;
list-style: none;
}
.fh-details summary::-webkit-details-marker { display: none; }
.fh-details p { padding: 0 0 12px; margin: 0; opacity: 0.75; }
.fh-acc-chevron {
display: inline-block;
transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}
.fh-details[open] .fh-acc-chevron { transform: rotate(180deg); }
Content Fade-In
Layer this on any accordion: the panel content animates in each time it opens, making the reveal feel deliberate instead of abrupt.
Markup
<details class="fh-details fh-acc-reveal">
<summary>Question?</summary>
<p>Answer…</p>
</details>
CSS
.fh-details {
border: 1px solid #3a4358;
border-radius: 10px;
padding: 0 16px;
}
.fh-details summary {
padding: 12px 0;
cursor: pointer;
font-weight: 600;
list-style: none;
}
.fh-details summary::-webkit-details-marker { display: none; }
.fh-details p { padding: 0 0 12px; margin: 0; opacity: 0.75; }
.fh-acc-reveal[open] p {
animation: fh-accFade 0.35s ease both;
}
@keyframes fh-accFade {
from { opacity: 0; transform: translateY(-6px); }
to { opacity: 0.75; transform: translateY(0); }
}
Plus / Minus Morph
Two bars drawn with pseudo-elements; on open, the vertical bar rotates into the horizontal one and fades — a tiny morph that reads as premium.
Markup
<details class="fh-details">
<summary>Question? <span class="fh-plusminus"></span></summary>
<p>Answer…</p>
</details>
CSS
.fh-details {
border: 1px solid #3a4358;
border-radius: 10px;
padding: 0 16px;
}
.fh-details summary {
display: flex;
justify-content: space-between;
align-items: center;
gap: 10px;
padding: 12px 0;
cursor: pointer;
font-weight: 600;
list-style: none;
}
.fh-details summary::-webkit-details-marker { display: none; }
.fh-details p { padding: 0 0 12px; margin: 0; opacity: 0.75; }
.fh-plusminus {
position: relative;
width: 14px;
height: 14px;
flex-shrink: 0;
}
.fh-plusminus::before,
.fh-plusminus::after {
content: '';
position: absolute;
inset: 0;
margin: auto;
background: #06b6d4;
border-radius: 2px;
transition: transform 0.3s ease, opacity 0.3s ease;
}
.fh-plusminus::before { width: 14px; height: 2px; }
.fh-plusminus::after { width: 2px; height: 14px; }
.fh-details[open] .fh-plusminus::after { transform: rotate(90deg); opacity: 0; }
.fh-details[open] .fh-plusminus::before { transform: rotate(180deg); }
Solving the height: auto problem
The classic accordion frustration is that height: auto cannot be transitioned — CSS needs two numeric values to interpolate between, and "auto" isn't one. For years the workaround was guessing a max-height large enough to fit any content, which produces a delay on close (the transition runs through the unused space) and breaks whenever content exceeds the guess.
The modern solution is grid-template-rows: 0fr transitioning to 1fr, with the content wrapped in a child that has overflow: hidden. Fractional units are interpolatable, so the row grows smoothly to exactly the content's height — no magic numbers, no guessing, and no delay.
Use the native details element where you can
Three of the four effects here build on <details> and <summary>, which give you the open/close behaviour, keyboard support and screen reader semantics for free. The [open] attribute selector then drives your animation — no state management, no ARIA to maintain.
The trade-off is that <details> toggles instantly, so animating the height itself requires either the grid technique on a wrapper or the newer ::details-content support. Animating the icon and fading the content, as these effects do, works everywhere today.
Accordions and FAQ content
Accordions are the standard pattern for FAQ sections — including on this site — and they're safe for SEO: content inside a collapsed <details> is in the HTML and Google indexes it normally. Pair it with FAQPage structured data and you're eligible for FAQ rich results.
Where accordions go wrong is hiding content people need. If most visitors will want most of the answers, hiding them behind clicks adds friction for no benefit. Reserve accordions for genuinely optional or reference-style content, and consider opening the first item by default so the pattern is obvious.