You can build a CSS accordion with two HTML elements and no script. Details wraps each item, summary holds the clickable label, and the browser does the rest.

Give a group of details elements the same name attribute and opening one closes the others.

Animation is where browsers still disagree. The interpolate-size property, which lets a panel’s height transition to auto, shipped in only Chrome 129 and Edge 129. Firefox and Safari still lack it (Web Platform DX, 2026).

Checkbox, radio and :target accordions came before details, and they don’t have its built-in semantics.

Which CSS accordion method should you use?

See the Pen
Pure CSS Accordion
by Álvaro (@alvarotrigo)
on CodePen.

No JavaScript needed, fam! This gem pulls off a slick move with HTML checkboxes, and even rocks a “close all” button. Advanced but smooth, like a cocktail you can’t put down.

Native details and summary, with a shared name attribute when only one panel should stay open at a time.

Radio inputs, checkboxes and :target links exist because details used to be unreliable. These days they cost you semantics and give very little back.

In practice, a CSS accordion here means any stack of expandable panels that toggles without script handlers. A button wired with aria-expanded needs JavaScript to flip its state, so it falls outside this comparison.

The details interface itself is old. MDN’s browser compatibility data dates it to Chrome 12, Firefox 49 and Safari 6.

MethodSemanticsPanels openBrowser floor
details and summaryNative disclosure widgetSeveral at onceEvery current browser
details with nameNative disclosure widgetOne at a timeChrome 120, Safari 17.2, Firefox 130
Radio inputsRadio button, no expanded stateOne at a timeSelector support only
CheckboxCheckbox, no expanded stateSeveral at onceSelector support only
:target linksPlain links and URL fragmentsOne at a timeSelector support only

If several panels can stay open, plain details is enough. For one panel at a time in current browsers, add name. And if you need one at a time with no script on browsers older than the versions in the table, radio inputs will do it, though you accept the accessibility cost.

Checkbox and :target accordions never beat details. Skip them in new builds.

How to build a CSS accordion with details and summary

See the Pen
Collapsing Accordion Pure CSS
by Kniw Studio (@JeremyWink)
on CodePen.

Got no time for complicated stuff? All you need is this pure CSS and HTML gold. No Javascript shenanigans here.

Wrap each item in a details element and put the visible label in a summary. The browser takes care of the toggle and the open state, and keyboard operation comes along with it.

Both elements are standard HTML, so the accordion still works with the stylesheet switched off.

  1. Write the markup, one details per item, with the summary first and the content after it. MDN’s reference says summary must be the first child, otherwise the browser inserts a default label (typically “Details”). Add the open attribute to any item that should start expanded.
  2. Style the summary. Set cursor, padding, a border between items, and visible hover and focus states.
  3. Remove the default triangle by setting list-style to none, and add summary::-webkit-details-marker with display none for Safari, as MDN documents.
  4. Add a custom icon. Draw it with summary::after and rotate it in a rule scoped to details[open].
  5. Style the panel itself. Target details::details-content for padding and background, wrapped in an @supports selector(::details-content) block.

The @supports wrapper matters because ::details-content shipped late. Per the Web Platform DX web-features dataset, Chrome added it in 131 (2024-11-12), Safari in 18.4 (2025-03-31) and Firefox in 143 (2025-09-16), which made it Baseline Newly Available on 2025-09-16.

In browsers without it, the accordion still opens and closes. It just keeps the default panel styling.

One catch from MDN is that the role assigned to summary varies across browsers. Test the widget on more than one platform before calling it accessible.

Exclusive accordions with the details name attribute

Give several details elements the same name value and the browser closes the open one whenever another opens.

Chrome for Developers and the Web Platform DX web-features dataset (checked October 2026) list these support dates for the name attribute:

  • Chrome and Chrome Android 120, released 2023-12-05
  • Safari and Safari on iOS 17.2, released 2023-12-11
  • Firefox 130, released 2024-09-03
  • Baseline status: Newly Available since 2024-09-03, expected to reach Widely Available on 2027-03-03

Firefox was the last engine to ship it, so the practical floor is September 2024. Check the Can I use table before dropping a fallback for older devices.

The name groups elements, not their DOM order, so grouped panels can sit in different containers. A new name value starts a new group, which lets one page hold several exclusive accordions.

For older browsers, Chrome for Developers publishes a polyfill built on the toggle event. When a named details opens, the script removes the open attribute from the others in the group.

Browsers that never fire toggle skip the script entirely. The same page calls that acceptable progressive enhancement.

The documentation also adds a caution. Exclusive accordions save space, but people may have to open many items to find an answer, and anyone comparing two items at once gets frustrated.

Default to several panels open. Use name when each answer is long and independent, like a support FAQ where readers want one answer and nothing else.

How do checkbox, radio and :target accordions work?

They keep the open state outside a details element, either in a checked input or in the URL fragment, and a selector reveals the matching panel.

Checkbox accordions

See the Pen
CSS3 Multi Open “Accordion”
by Frank Ali (@frankieali4)
on CodePen.

Big up to Frank Ali. It’s not your usual “one-at-a-time” gig. Checkboxes, not radios, give it that twist.

A hidden checkbox sits before a label and a content block. Clicking the label toggles the checkbox, and the :checked pseudo-class plus a sibling combinator shows the panel.

Codrops published this pattern in 2012 and it spread because it needs no script. Each checkbox is independent, so several panels stay open together.

Radio accordions

See the Pen
CSS Accordion: Radio Button Hack (Fixed Height)
by Jon Yablonski (@jonyablonski)
on CodePen.

Radio button hack in action. Sass is in the mix too. Dive in, and explore the magic!

Swap the checkbox for a radio input, give every item the same name, and the browser allows one open panel. That is the same rule the details name attribute now provides natively.

The upside is single-open behavior in browsers that predate the name attribute. The downside is that a radio can’t be unchecked by clicking it again, so the open panel has no built-in way to close. It also announces itself as a radio button, not as an expandable section.

:target accordions

Each header links to a section ID, and the panel matching :target opens. GrahamTheDev’s DEV Community walkthrough pairs this with a grid-rows trick for animated height.

  • Every click changes the URL fragment, so the Back button steps through panel states.
  • Only one panel can open, because a page has a single :target.
  • Collapsing needs a second link pointing at a different fragment.
  • The page also scrolls toward the target on each click.

Where these methods break

Wikimedia’s Phabricator task T243126 records the trade-off. The checkbox hack spread across skins and Vector menus to cut JavaScript, and the proposed accessibility fix (updating aria-expanded by script) brings JavaScript back.

The same discussion notes that the checkbox keeps its inherent role, because ARIA should not override it with role=”button”.

My take is to skip all of them wherever the name attribute works. Radio inputs only make sense on script-free pages that must support browsers older than Chrome 120, Safari 17.2 or Firefox 130.

Animating CSS accordion height without JavaScript

Animating panel height in plain CSS comes down to interpolate-size with ::details-content, a grid-template-rows switch from 0fr to 1fr, or a max-height transition. On a native details element, only the first animates both opening and closing.

The shared problem is that height: auto is not a value the browser can interpolate by default. Each technique is a different workaround for it.

Support splits along engine lines. The name attribute and ::details-content ship in Chrome, Safari and Firefox, but interpolate-size does not, so animated auto height is a Chromium feature for now.

::details-content with interpolate-size

Opt in with interpolate-size: allow-keywords on :root. Then start details::details-content at height 0 with overflow clip, transition height and content-visibility (with the allow-discrete keyword), and set height auto under details[open].

It animates opening and closing on plain details markup, with no wrapper div and no guessed heights. The catch is that auto-height animation only runs where interpolate-size exists. The pseudo-element also defaults to display block, where it used to behave like display contents, so children that rely on height 100% can break.

Chrome for Developers documents a workaround for that last problem: display contents on the open pseudo-element. It can’t be combined with a height animation, because a display contents box has no height to animate.

Per the Web Platform DX web-features dataset, interpolate-size (specified in CSS Values and Units Level 5 by the CSS Working Group) shipped in Chrome 129 on 2024-09-17 and Edge 129 on 2024-09-19. Firefox (bug 1945962, vendor position positive) and Safari (WebKit bug 295132, vendor position support) lack it as of October 2026.

Gate the animation with @supports (interpolate-size: allow-keywords). Browsers outside the gate keep a working accordion without motion, and for most content that beats a fixed-height box with a scrollbar.

grid-template-rows from 0fr to 1fr

DockYard’s October 2024 write-up calls CSS Grid the cleanest browser-safe route to intrinsic-size animation.

The wrapper uses display grid with grid-template-rows 0fr and a transition on that property. The open state switches it to 1fr, and the inner element needs overflow hidden so the collapsed row clips its content.

One quirk. Between 0 and 1fr, Grid can briefly create a second row and the animation stutters. DockYard fixes it with grid-row: 1 / span 2 on the container.

It works in every major browser, takes content of any height and needs no script. But on a native details element the wrapper animates only on opening. Chrome for Developers tested a wrapper div and saw no closing animation.

The pattern stays the standard choice for button-driven accordions, where an attribute such as data-open flips the state, as in DockYard’s example.

max-height transitions

Skip it in new builds.

A max-height transition runs between 0 and the cap you declare, not the real content height. Put a 1000px cap on a 200px panel and most of the duration passes with nothing visibly moving, and the close lags.

ProsCons
Works in every browserNeeds a guessed upper bound
One property to learnTiming drifts from the real height
Fine for fixed-height panelsTaller content gets clipped

It still suits panels with a known height. Variable copy needs one of the two techniques above.

Respecting reduced motion

Wrap every transition in a prefers-reduced-motion check. WCAG 2.3.3 Animation from Interactions (Level AAA) asks that motion triggered by interaction can be turned off unless it carries information, and W3C’s Technique C39 shows the media query route.

  • Set the duration through a CSS variable and zero it under prefers-reduced-motion: reduce, as the DEV Community accordion walkthrough does.
  • Or write static styles first and add motion only under prefers-reduced-motion: no-preference.

Chrome for Developers leaves the check out of its ::details-content demos for brevity and says production code should include it.

What makes a CSS accordion accessible?

See the Pen
ARIA Accessible Accordion
by Kiri Egington (@kiriegington)
on CodePen.

Dropdowns, quick responses, touch-enabled, and it doesn’t leave anyone behind. How’s that for inclusive?

Each header needs to be a real control with an announced expanded or collapsed state, and every action has to work from the keyboard alone.

Native details and summary supply that behavior by default. W3C’s WCAG 2.2 text notes that standard HTML controls already meet Success Criterion 4.1.2 (Name, Role, Value, Level A) when used according to specification, so the burden falls on components you script or fake.

Semantics a custom accordion must add

The W3C ARIA Authoring Practices Guide sets the baseline for anything built from buttons and panels, using ARIA states and properties. The title goes inside an element with role button, aria-expanded is true while the panel is visible, and aria-controls holds the ID of the panel content. If the accordion doesn’t allow collapsing, an open header also gets aria-disabled set to true.

Keyboard operation

KeyActionStatus
Enter or Space on a headerExpands a collapsed panel, collapses an open one if allowedRequired
Tab and Shift+TabMove through all focusable elements, panel contents includedRequired
Down and Up arrowsMove to the next or previous headerOptional
Home and EndMove to the first or last headerOptional

Native summary covers the two required rows. The optional arrow-key movement between headers is absent from details, and adding it takes script.

A checkbox or radio accordion whose input uses display none never receives focus, so keyboard users can’t reach the header at all. Hide the input with a visually-hidden pattern instead, and tie the label to it with the for attribute.

Focus visibility

WCAG 2.4.7 Focus Visible (Level AA) means summary and label need a visible focus indicator. Removing the default outline without a replacement fails it.

WCAG 2.2 added 2.4.11 Focus Not Obscured (Minimum) (Level AA). A sticky navigation bar that covers a focused summary after the page scrolls runs into it. A scroll-padding-top on the root keeps focused headers clear of the bar.

Testing the result

Deque’s March 2021 study of its axe-powered automated testing found it covered 57 percent of accessibility issues by volume, above the 20 to 30 percent commonly assumed. It is the vendor’s own tooling and data set, so treat the figure as a best case for Lighthouse or axe DevTools.

Run both for the cheap catches, then test by hand. Tab to each header and toggle it with Enter and Space, checking that the focus ring stays visible and unobscured once a panel opens. Then listen with NVDA, JAWS or VoiceOver for the announced state.

Searchability and layout shift in collapsed panels

A collapsed panel built carelessly costs two things: text that find-in-page can’t reach, and height changes that move the page.

Find-in-page and fragment links

Native details elements are searchable. Per the HTML Standard as summarized by Chrome for Developers, a closed details expands automatically when the browser scrolls to hidden content after find-in-page, a text fragment link or an element fragment link.

Custom panels need hidden=until-found. Chrome for Developers documents it as available from Chrome 102 (May 2022), with a beforematch event that fires just before the browser reveals the section.

The documentation attaches a few caveats. The attribute applies content-visibility hidden, not display none, so the element keeps its box and borders still render. Put borders on a nested element. Panels also have to open without find-in-page, since not every visitor searches.

Browsers without support fall back to plain hidden content. Chrome for Developers suggests detecting them by checking for onbeforematch on HTMLElement.prototype, but Safari 26.2 added the beforematch event while the attribute value is still unsupported there, so the check may pass in Safari. Test in Safari instead of relying on it alone.

GOV.UK Frontend’s accordion adopted the attribute in v4.5.0, so the browser’s own search can open its sections.

Support has moved since then. The v4.5.0 release notes (January 2023) limited it to recent Chrome, Edge and Samsung Internet. Firefox has now shipped hidden=until-found (Firefox 148, released 2026-02-24), while Safari still does not support the attribute value, according to the Web Platform DX dataset. Auto-expanding closed details elements on find-in-page and hidden=until-found were both part of the details element focus area in Interop 2025.

Check the browsers you target before relying on it.

Layout shift

web.dev’s CLS guide sets a good Cumulative Layout Shift score at 0.1 or less, measured at the 75th percentile of page loads across mobile and desktop. Each shift scores impact fraction times distance fraction, and CLS is one of the Core Web Vitals.

The same guide says a shift only hurts when the user does not expect it. A tap on a summary is an expected cause, so the risk sits elsewhere. A panel opened by script after first paint, from a URL hash for example, pushes everything below it down, so set the open attribute in the HTML instead. Late-loading content or images without declared dimensions inside an open panel change its height too.

Height animation also reflows the content below on every frame, while opacity and transform do not. Keep durations short on long pages.

When a CSS accordion is the wrong choice

Skip the accordion when the hidden text is what most visitors came to read, or when the page needs controls CSS can’t provide.

It’s also a poor fit when panels hold a single short sentence, since the header then costs more than the content, or when the content must be visible on first load. Need open-all and close-all buttons, analytics on every toggle, or arrow-key movement between headers? Details fires a toggle event, but wiring any of that takes script. And if the sections are peer views of one subject, tabs are the better pattern.

Accordion or tabs?

See the Pen
Responsive Flexbox Tabs / Accordion – CSS Only
by Josh Vogt (@josh_vogt)
on CodePen.

Flexbox doing its thing. Super responsive. And if you’re into techie stuff, there’s a switch when the viewport’s below 600px. Cool, huh?

DimensionAccordionTabs
Keyboard modelTab through headers, arrows optionalArrow keys move within the tab list
Panels visibleOne, several or allOne at a time
FitsLong lists of independent sectionsPeer views of one subject

The W3C APG gives each pattern its own keyboard model. A layout that swaps tabs for an accordion at a breakpoint must implement both correctly, so pick one unless the design demands the switch.

When a framework fits better

Want a basic vertical menu? Nah. Go big with an expandable accordion!

The accordion component in Bootstrap runs on the framework’s collapse plugin. Buttons carry data-bs-toggle=”collapse” and data-bs-target with aria-expanded and aria-controls set in the markup, and data-bs-parent groups panels into single-open behavior (Bootstrap 5.3 documentation).

The cost is loading Bootstrap’s JavaScript bundle for a widget that details handles natively.

Tailwind CSS goes the other way. An accordion styled with Tailwind utilities adds classes to native markup and no behavior of its own.

I’d use native details when styling is the only gap, and a framework accordion when its JavaScript already ships with the site. If the content should simply be visible, use neither.

CSS accordion examples

Foundation Test

See the Pen
Foundation test
by Svend Richter (@Seven-D)
on CodePen.

Sleek as your fave influencer’s IG page, man. Made with HTML, SCSS, and JavaScript. Your profile pic and username are the stars here. It even spotlights which menu item you’re vibing with.

Accordion Menu + Tooltip

See the Pen
Accordion Menu + Tooltip
by mori (@morimiko)
on CodePen.

Mori nails it by setting the accordion menu on a blank canvas of a white background. Light and fresh, kinda like biting into a crisp apple. A top-notch design option to refresh your site.

CSS Responsive Animated Accordion

See the Pen
CSS Responsive animated Accordion
by Chris Wright (@chriswrightdesign)
on CodePen.

Want those snazzy animations and transitions? You got it. Using material colors, this snippet makes sure you know which accordion you’re peeking into.

Three Dimensions Accordion Example

See the Pen
Awesome accordion menu using only HTML & CSS
by Álvaro (@alvarotrigo)
on CodePen.

This ain’t just a flat landscape; it’s 3D, baby! Ahmad Emran takes it to another level, making sure every little detail makes the accordion menu pop.

Accordion Menu

See the Pen
Accordion Menu
by Benjamin (@maggiben)
on CodePen.

No fuss, just a neat accordion setup with HTML and JavaScript. But hold up, the over-effects on the menu items give it that little spice.

Amazing Accordion Menu Using Only HTML & CSS

See the Pen
Amazing accordion menu using only HTML & CSS
by Rs Sabbir Ahmed (@rssabbir)
on CodePen.

The bold, purple menu doesn’t just sit there; it stands out. Shapes and colors all vibe together in a way that’ll make visitors do a double take.

Accordion Menu With A Header

See the Pen
CSS Accordion
by Álvaro (@alvarotrigo)
on CodePen.

Sometimes you need titles, man, and this accordion menu’s got ’em. Pop open a section and boom-a header tells you what’s what.

CSS Only Vertical Accordion Menu

See the Pen
CSS Only Vertical Accordion Menu
by Eriksen (@eriksenlezama)
on CodePen.

Why stick to boring horizontal when you can go vertical? Logos for flair and a gradient that can’t be ignored.

Accordion Menu with Image Effects

See the Pen
Accordion menu with images effects
by sayato (@sayato)
on CodePen.

If you want your visitors to stay, this one’s a catch. Sayato brings you an accordion in a dark blue backdrop that makes the menu on the left pop.

Pure CSS Horizontal Accordion

See the Pen
Pure CSS Horizontal Accordion
by Aysha Anggraini (@rrenula)
on CodePen.

Kudos to Aysha Anggraini for this. Laying it out side-by-side, man, like a landscape on your screen.

Simple Flat Theme Accordion Menu

See the Pen
Simple Flat UI CSS Accordion
by Álvaro (@alvarotrigo)
on CodePen.

This beauty here? Smooth animations and clean UI. Perfect for the minimalists out there.

Accordion Menu Html CSS Only

See the Pen
Accordion menu HTML CSS Only
by Vynter (@vynter)
on CodePen.

Big shoutout to Vynter for keeping it real and simple.

Sliding CSS Accordion Menu

See the Pen
CSS Accordion
by Álvaro (@alvarotrigo)
on CodePen.

Slide into those submenus with lightning-fast transitions. Pure CSS magic right here.

Awesome Accordion Menu

See the Pen
Awesome accordion menu using only HTML & CSS
by Ahmad Emran (@ahmadbassamemran)
on CodePen.

Who said you need more than HTML & CSS? They lied.

Swanky Little Accordion List

See the Pen
Swanky little accordian list
by Jamie Coulter (@jcoulterdesign)
on CodePen.

This gem? It’s more than an accordion. Click, and watch it gracefully toggle, like a dance of content on your screen.

Activated Accordion

See the Pen
Hover activated accordian with default state
by Cory (@uniqname)
on CodePen.

No rush here. Take your time, hover around, and enjoy that sweet content reveal.

Sliding Accordion Menu

See the Pen
Pure Css Accordion Menu
by Álvaro (@alvarotrigo)
on CodePen.

Slide between items with this nifty design. Just remember, only one superstar at a time.

Accordion Menu In Pure CSS3

Create? More like art. This accordion menu is pure CSS3 elegance.

Funky Pure CSS Accordion

See the Pen
Funky Pure CSS Accordion
by Jamie Coulter (@jcoulterdesign)
on CodePen.

Jamie Coulter sprinkles a bit of funk in this accordion. Groovy, right?

FAQ Based Accordion Menu

See the Pen
Pure CSS Accordion
by Álvaro (@alvarotrigo)
on CodePen.

Ideal for FAQs. Open, close, play around. It’s like an interactive toy for your website.

Zoom Animated Accordion Menu

See the Pen
Pure CSS Accordion (Checkbox Hack)
by Álvaro (@alvarotrigo)
on CodePen.

This one’s like watching an optical illusion. Zoom animations for every item. Mesmerizing!

CSS Tab Menu

See the Pen
II just another Css tabs (:checked)
by Kseso (@Kseso)
on CodePen.

Oh man, got a combo here! HTML & CSS doing wonders with those tabs. Plus, you get pictures and icons? Sweet deal. Fully responsive? Even better. Supports all those fancy browsers? Oh, we’re golden!

Accordion Menu With Transition

See the Pen
CSS Accordion
by Álvaro (@alvarotrigo)
on CodePen.

Pure CSS magic here. Designed for FAQs, with numbers and everything. And trust me, it’s a looker!

Creating A Stylish Accordion Menu with Pure CSS

Style it up with this one. Click, and boom! Hidden panels reveal themselves.

CSS3 Accordion

See the Pen
CSS3 Accordion
by Ying Zhang (@dodozhang21)
on CodePen.

This one’s for the lazy peeps out there. No need to click! Plus, if you’re a tinkerer, a bit of CSS play, and you’re golden!

Multi-Coloured Accordion Menu With Icons

See the Pen
pure css accordion
by Álvaro (@alvarotrigo)
on CodePen.

Colors, icons, smooth animations. And those arrow indicators? Sweet touch!

Marvel Horizontal Accordion

See the Pen
Marvel Horizontal Accordion
by Laura C. (@lzen)
on CodePen.

Props to Laura C. for this one. I mean, horizontal accordion? Genius!

Colorful CSS Accordion V05

This is like a party for your eyes! Grouping items with colors? UI brilliance right there!

Responsive Accordion Menu using only HTML & CSS

Starting out? No worries. Craft an accordion like this, and let your website shine!

CSS Accordion FAQ

Can you nest one accordion inside another?

Navigate through levels with this one. For when you got layers to your content.

Yes. A details element can sit inside another panel, and each keeps its own open state.

Give the inner group a different name value, because a new name value starts a separate exclusive group (Chrome for Developers).

Can search engines read text inside a closed panel?

Yeah, that’s right. It’s sleek, semantic, and SEO-friendly. Dropdown magic with HTML and CSS. Winner, winner!

How do I link straight to one accordion panel?

Put an ID on an element inside the panel and link to it. In Chromium browsers a closed details expands when element fragment navigation, find-in-page or a text fragment link scrolls to hidden content, per the HTML Standard as summarized by Chrome for Developers.

Custom panels need hidden=until-found for the same behavior.

What a Production-Ready CSS Accordion Needs

Build on native details and summary, and treat every enhancement as removable. If animation or single-open grouping fails in a browser, the panels still open and close.

Start with plain details, visible focus and the open state set in HTML. Add a shared name value only where one panel at a time helps readers, and put animation behind @supports with a reduced-motion rule. Each layer fails safely, so the one before it keeps working.

The trade-off is that Firefox and Safari visitors get an instant toggle where Chromium visitors get motion.

The fallback layer disappears the day Firefox and Safari both ship interpolate-size, since one animation rule would then serve all three engines. Position verified October 2026.

When sections are peers instead of a stack, tabs built in CSS are the next component to build.

Bogdan Sandu
Latest posts by Bogdan Sandu (see all)