A CSS only accordion menu sounds like a magic trick. You click a label, a panel slides open, and the page never runs a single line of JavaScript. It works because CSS has a few clever tricks up its sleeve. The most common approach uses the :checked pseudo-class with a hidden checkbox input. When a user clicks a label tied to that checkbox, the browser flips the input to :checked. Your CSS can then target that state and reveal the hidden content. No JavaScript. No dependencies. Just clean, declarative code that browsers have supported for years.
A CSS only accordion menu removes the need for JavaScript entirely, making your site faster and more reliable. By using the checkbox hack, you create expandable sections that work on every modern browser. This approach also improves accessibility when you pair it with proper ARIA attributes. In 2026, lightweight components like this are essential for performance focused web design.
Why Ditch JavaScript for an Accordion?
JavaScript accordions are everywhere. They work fine, but they add weight. A typical jQuery accordion pulls in a library, runs DOM queries, and handles click events. That is extra bytes to download and extra work for the browser. A CSS only accordion menu skips all of that.
Here is what you gain:
- Faster page loads. No scripts to parse or execute.
- Fewer points of failure. No JavaScript errors to debug.
- Better performance on low end devices. CSS is highly optimized in modern browsers.
- Simpler maintenance. Less code means fewer bugs.
For many projects, a CSS only solution is enough. You can build a full FAQ section, a pricing table, or a navigation menu without writing a single function.
How the Checkbox Hack Works
The checkbox hack is the foundation of most CSS only accordion menus. You hide a real checkbox input, then use a <label> as the visible trigger. When the label is clicked, the checkbox becomes :checked. Your CSS uses the adjacent sibling combinator (+) or the general sibling combinator (~) to style the content panel.
Here is the basic structure:
- Wrap each accordion item in a container.
- Place a hidden
<input type="checkbox">at the start of the item. - Add a
<label>that acts as the header button. - Put the content inside a
<div>that follows the checkbox. - Use CSS to show the content only when the checkbox is
:checked.
That is the whole pattern. You can repeat it for as many items as you need.
Step by Step: Building Your First CSS Only Accordion Menu
Let us walk through a real example. This will be a simple FAQ section with three questions.
Step 1: Write the HTML
<div class="accordion">
<div class="accordion-item">
<input type="checkbox" id="item1" class="accordion-input">
<label for="item1" class="accordion-label">What is a CSS only accordion?</label>
<div class="accordion-content">
<p>It is an accordion component that uses only HTML and CSS. No JavaScript is required to open or close the panels.</p>
</div>
</div>
<div class="accordion-item">
<input type="checkbox" id="item2" class="accordion-input">
<label for="item2" class="accordion-label">Does it work on mobile?</label>
<div class="accordion-content">
<p>Yes. The checkbox hack works on all modern browsers, including mobile Safari and Chrome.</p>
</div>
</div>
<div class="accordion-item">
<input type="checkbox" id="item3" class="accordion-input">
<label for="item3" class="accordion-label">Is it accessible?</label>
<div class="accordion-content">
<p>With proper ARIA attributes and keyboard support, it can be. We will cover that later.</p>
</div>
</div>
</div>
Step 2: Add the CSS
.accordion-input {
display: none;
}
.accordion-label {
display: block;
padding: 12px 16px;
background: #f5f5f5;
cursor: pointer;
border-bottom: 1px solid #ddd;
font-weight: 600;
}
.accordion-content {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease-out;
padding: 0 16px;
background: #fff;
}
.accordion-input:checked ~ .accordion-content {
max-height: 300px;
padding: 16px;
}
That is it. When a user clicks a label, the associated checkbox becomes :checked, and the content panel expands. The max-height transition gives a smooth slide effect.
Common Mistakes and How to Fix Them
Even a simple CSS only accordion menu can trip you up. Here are the most frequent issues and their solutions.
| Mistake | Why It Happens | How to Fix It |
|---|---|---|
| Content jumps when opening | The max-height value is too large, causing a delay. |
Use a value just slightly larger than the actual content height. |
| Multiple items open at once | Each checkbox is independent by default. | Use radio inputs instead of checkboxes if you want only one open. |
| Clicking the label does nothing | The for attribute does not match the input id. |
Double check the for and id values are identical. |
| Animation feels clunky | The transition property is missing or set incorrectly. | Add transition: max-height 0.3s ease-out; to the content panel. |
| Content is hidden on page load | The max-height is set to 0, which is correct. |
Ensure the :checked state sets a larger max-height. |
Making Your Accordion Accessible
Accessibility is not optional. A CSS only accordion menu can be accessible, but you need to add a few things.
- Use
<button>elements inside the label if you want native keyboard support. Some screen readers struggle with labels tied to hidden inputs. - Add
role="region"andaria-labelledbyto the content panel. - Use
aria-expandedon the trigger element. You can toggle this with a small JavaScript snippet if you need dynamic state, but for a pure CSS approach, the:checkedstate is enough for visual users.
“Accessibility is not a feature. It is a baseline. A CSS only accordion can meet that baseline if you pair it with semantic HTML and ARIA attributes.” – Heydon Pickering, Inclusive Design Advocate
If you want to go deeper on inclusive interfaces, check out this guide on designing accessible web interfaces.
When to Use a CSS Only Accordion (and When Not To)
A CSS only accordion menu is perfect for:
- FAQ pages where content is static.
- Pricing tables with expandable features.
- Documentation sections.
- Mobile navigation menus.
It is not ideal for:
- Dynamic content that loads via AJAX.
- Accordions that need complex animations.
- Components that require real time state management.
If your project needs dynamic behavior, you might want to add a small JavaScript layer. But for most static content, CSS is enough.
Performance Benefits in 2026
In 2026, web performance is more important than ever. Core Web Vitals directly affect search rankings. A CSS only accordion menu helps in three ways.
- Zero JavaScript overhead. No libraries, no event listeners, no DOM manipulation.
- Faster rendering. CSS is processed by the browser’s native engine.
- Smaller file size. A typical CSS accordion adds less than 1 KB to your stylesheet.
Compare that to a JavaScript accordion that might pull in 30 KB of jQuery. The difference adds up, especially on pages with multiple components.
For more ways to speed up your site, read about how to implement lazy loading for faster web design performance in 2026.
Advanced Techniques: Radio Buttons and Multiple Open Panels
You can extend the basic checkbox pattern in two useful ways.
Radio button accordion (only one open at a time)
Replace type="checkbox" with type="radio". Give all radio inputs the same name attribute. Now only one panel can be open at a time. This is great for step by step wizards or single select FAQs.
Allow multiple open panels
Stick with checkboxes. Each checkbox is independent, so users can open several panels at once. This works well for documentation or reference pages.
Both patterns use the same CSS. The only change is the input type.
Styling Tips for a Polished Look
A CSS only accordion menu does not have to look basic. You can style it to match any design system.
- Use
::beforeor::afterpseudo-elements on the label to add plus/minus icons. - Change the background color of the label when the panel is open.
- Add a border or shadow to the content panel for depth.
- Use CSS custom properties for colors and spacing so the accordion fits your brand.
Here is a small example of a plus/minus icon using only CSS:
.accordion-label::after {
content: "+";
float: right;
transition: transform 0.3s;
}
.accordion-input:checked + .accordion-label::after {
content: "-";
}
No icon fonts. No SVGs. Just a simple character that changes on state.
Testing Your Accordion
Before you ship, test these scenarios:
- Click each label to verify the panel opens.
- Click the same label again to close it.
- Tab through the accordion using the keyboard.
- Test on a mobile device with touch input.
- Check with a screen reader to confirm labels and content are announced.
If you are building a full design system, consider using CSS custom properties to streamline your web design workflow. It makes global changes much easier.
Your Next Project Deserves a CSS Only Accordion
A CSS only accordion menu is a small win that adds up. It makes your codebase lighter, your pages faster, and your life as a developer simpler. You do not need a JavaScript framework to build interactive components. Sometimes the best tool is already in your browser.
Try it on your next FAQ page or documentation section. You might be surprised how much you can do with just HTML and CSS. And if you want to keep exploring modern design techniques, check out the top web design trends to elevate your projects in 2026. Your users will thank you for the speed.