Last updated: March 13, 2026
How to Create a CSS-Only Accordion (3 Methods)
Build accessible, animated accordions without JavaScript. Learn the details/summary approach, checkbox hack, and :target selector with interactive examples.
Why CSS-Only Accordions?
CSS-only accordions reduce JavaScript bundle size, work without scripting enabled, and can be more performant. They're perfect for FAQ sections, mobile menus, and collapsible content areas.
Details/Summary
Native HTML with built-in accessibility. Best for most use cases.
Checkbox Hack
Enables smooth CSS animations. Multiple items can be open.
:target Selector
URL-based state. Great for shareable deep links.
Pro tip: Use <details>/<summary> as your default choice. It's accessible, semantic, and works everywhere.
Quick Reference
Compare the three CSS-only accordion methods at a glance.
| Method | Browser Support | Animations | Accessible | Multiple Open |
|---|---|---|---|---|
| Details/SummaryBest | 97%+ | Yes | Yes | With name attr |
| Checkbox | 99%+ | Yes | Needs ARIA | Yes |
| :target | 99%+ | Yes | Needs ARIA | No |
Details/SummaryBest
Checkbox
:target
Details/Summary (Recommended)
RecommendedThe native HTML approach using <details> and <summary> elements. Built-in accessibility, keyboard navigation, and toggle functionality without any CSS or JavaScript required.
Live Preview
What is Frontend Hero?+
How much does it cost?+
Full Code
Pros
- +Native HTML - no CSS required for basic functionality
- +Built-in keyboard accessibility (Enter/Space to toggle)
- +Screen reader friendly out of the box
- +State preserved on page reload (with name attribute)
- +Works without CSS or JavaScript
Cons
- -Limited animation support (content appears instantly)
- -Custom arrow styling requires extra CSS
- -Cannot have multiple accordions open at once (without name attribute)
When to Use
- *FAQ sections on websites
- *Mobile navigation menus
- *When accessibility is a priority
- *Simple expand/collapse content
Checkbox Hack
Uses a hidden checkbox input with a label to toggle visibility. The CSS sibling selector (~) shows/hides content based on checkbox state.
Live Preview
This content uses the checkbox hack for smooth animation. The hidden checkbox controls visibility.
Full Code
Pros
- +Smooth CSS animations possible
- +Multiple items can be open simultaneously
- +Excellent browser support (99%+)
- +Checkbox state persists during session
Cons
- -Not semantically correct HTML
- -Requires unique IDs for each accordion
- -Poor accessibility without ARIA attributes
- -max-height animation requires known content height
When to Use
- *When smooth animations are required
- *Multiple accordions that can be open at once
- *Legacy browser support needed
- *When you're comfortable adding ARIA attributes
:target Selector
Uses URL hash fragments and the CSS :target pseudo-class. When you click a link with an anchor, the :target selector styles the matching element.
Live Preview
In a real implementation, clicking would add #section1 to the URL, and CSS :target would show this content.
The :target method is great for FAQ pages where you want shareable links to specific answers.
Full Code
Pros
- +URL reflects accordion state (shareable links)
- +Can deep-link to specific accordion items
- +Pure CSS - no hidden inputs needed
- +Can trigger CSS animations
Cons
- -Changes browser URL (affects history)
- -Only one accordion can be open at a time
- -Page jumps to the accordion when clicked
- -Requires close button or different UX for closing
When to Use
- *FAQ pages where you want shareable links
- *Documentation with deep-linkable sections
- *Single-page applications with hash routing
- *When URL state is beneficial
Styling Tips
Smooth Height Transitions
The max-height trick creates smooth open/close animations. Set a max-height larger than your content will ever be.
.accordion-content {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease-out;
}
.accordion.open .accordion-content {
max-height: 500px; /* Larger than content */
}Custom Arrow Icons
Replace the default arrow with CSS pseudo-elements or SVG icons for a custom look.
.accordion-header::after {
content: "";
width: 10px;
height: 10px;
border-right: 2px solid currentColor;
border-bottom: 2px solid currentColor;
transform: rotate(45deg);
transition: transform 0.3s ease;
}
details[open] .accordion-header::after {
transform: rotate(-135deg);
}Animation Timing
Use different easing functions for open vs close animations to feel more natural.
.accordion-content {
transition: max-height 0.35s ease-out;
}
/* Faster close animation */
.accordion:not(.open) .accordion-content {
transition: max-height 0.2s ease-in;
}Grid-based Animation (Modern)
Use CSS Grid for true height animation without max-height hacks. Works in modern browsers.
.accordion-content {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 0.3s ease;
}
.accordion.open .accordion-content {
grid-template-rows: 1fr;
}
.accordion-content > div {
overflow: hidden;
}Accessibility Considerations
Use details/summary when possible
The <details> and <summary> elements have built-in accessibility. Screen readers announce them as expandable sections, and they work with keyboard navigation out of the box.
Add ARIA attributes for checkbox hack
If using the checkbox method, add role="button", aria-expanded, and aria-controls to make it accessible. Update aria-expanded with JavaScript when the state changes.
<div class="accordion">
<input type="checkbox" id="acc1" class="accordion-checkbox" />
<label
for="acc1"
class="accordion-header"
role="button"
aria-expanded="false"
aria-controls="content1"
>
Click to expand
</label>
<div id="content1" class="accordion-content">
Content here
</div>
</div>Ensure keyboard navigation
Users should be able to navigate to accordion headers with Tab and toggle them with Enter or Space. Native <details> handles this automatically.
Visible focus states
Always provide clear focus indicators for keyboard users. Never remove the outline without providing an alternative.
.accordion-header:focus {
outline: 2px solid #3b82f6;
outline-offset: 2px;
}
.accordion-header:focus:not(:focus-visible) {
outline: none; /* Hide for mouse users */
}Frequently Asked Questions
The best method is using HTML <details> and <summary> elements. They provide built-in toggle functionality, keyboard accessibility, and screen reader support without any CSS or JavaScript. For smooth animations, the checkbox hack combined with max-height transitions is a good alternative.
You can't directly animate height: auto in CSS. The common workaround is using max-height with a value larger than your content will ever be. For modern browsers, you can use CSS Grid with grid-template-rows transitioning from 0fr to 1fr, which gives true height animation without guessing max values.
Yes! With <details> elements, add the same name attribute to all items - browsers will automatically close others when one opens. For the checkbox method, use radio buttons instead of checkboxes with the same name. The :target method naturally supports this since only one hash can be active.
The <details>/<summary> method is fully accessible by default - it supports keyboard navigation and screen readers. The checkbox and :target methods require additional ARIA attributes (aria-expanded, aria-controls, role='button') to be accessible. Always test with screen readers and keyboard navigation.
CSS cannot animate between height: 0 and height: auto. Use max-height instead, setting it to 0 when closed and a value larger than your content when open. The transition will animate the max-height property. For a more elegant solution, use CSS Grid with grid-template-rows.
More CSS Tutorials
Copy CSS from Website
Extract styles with 2 clicks
Center a Div (CSS)
Flexbox, Grid, and more
Center a Div (Tailwind)
Utility classes for centering
Convert CSS to Tailwind
CSS to utility classes
Glassmorphism Effect
Frosted glass UI style
Neumorphism Button
Soft UI button design
Responsive Navbar
Mobile-friendly navigation
Sticky Header
Fixed navigation on scroll
CSS Pagination
Page navigation styles
Dropdown Menu
Hover and click dropdowns
CSS Modal
Popup dialog boxes
Toast Notifications
Animated alert messages
Hamburger Menu
Animated menu icon
Animate Gradients
Moving gradient backgrounds
Skeleton Loader
Loading placeholder UI
Element Screenshot
Capture any element as image
Pick Color from Website
Eyedropper tool comparison
Identify Fonts
Find fonts on any website
Download All Images
Bulk save images from any site
Measure Elements
Page ruler and measurements
Extract Colors from Website
Get any color palette instantly
Dark Mode Toggle
CSS variables and localStorage
Responsive Grid
CSS Grid auto-fit and minmax
Center Text in CSS
text-align, Flexbox, and Grid
Make Text Bold
font-weight values explained
Add Shadow in CSS
box-shadow, text-shadow, drop-shadow
Round Corners in CSS
border-radius and pill shapes
Style File Input
Custom upload buttons
