How to Build a CSS‑Only Responsive Accordion (No JavaScript Needed)

Read this article in clean Markdown format for LLMs and AI context.

If you’re tired of adding a little bit of JavaScript just to hide and show some text, you’re in the right place. At CSS Tricks Reference we love keeping things simple, and today I’ll show you a pure‑CSS accordion that works on any screen size. No extra scripts, no extra weight – just plain CSS and a tiny bit of HTML. Let’s get started.

Why a CSS‑Only Accordion?

Accordions are great for FAQs, product specs, or any place where you want to keep the page tidy. Using only CSS means:

  • Faster load time – the browser doesn’t have to download a separate file.
  • Fewer bugs – no JavaScript to break on older browsers.
  • Easy to maintain – you can change the look by editing one CSS file.

That’s why I keep a CSS‑only version in my toolbox and share it on CSS Tricks Reference whenever I need a quick solution.

The Basic Idea

The trick is to use the HTML <input type="checkbox"> element and the :checked pseudo‑class. When the checkbox is checked, we show the hidden panel. With a little help from display, max-height, and overflow, we can animate the opening and closing.

Step 1: Set Up the HTML

Here’s the minimal markup you need. Put this inside the body of your page.

<div class="accordion">
  <div class="item">
    <input type="checkbox" id="acc1" />
    <label for="acc1" class="title">What is CSS?</label>
    <div class="content">
      <p>CSS stands for Cascading Style Sheets. It tells the browser how to display HTML.</p>
    </div>
  </div>

  <div class="item">
    <input type="checkbox" id="acc2" />
    <label for="acc2" class="title">Why use Flexbox?</label>
    <div class="content">
      <p>Flexbox makes it easy to align items in a row or column without a lot of extra code.</p>
    </div>
  </div>
</div>

A few notes:

  • Each accordion section is a .item.
  • The hidden <input> is what we’ll use to toggle the panel.
  • The <label> is the clickable title. Because it’s linked to the input via for, clicking the label checks the box.
  • The .content holds the hidden text.

Step 2: Hide the Checkboxes

We don’t want the checkboxes to appear on the page. Just hide them with CSS.

.accordion input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

Now the checkboxes are still there for the browser, but they’re invisible and can’t be clicked directly.

Step 3: Style the Title

Let’s make the title look like a button. This is where CSS Tricks Reference likes to keep things clean and readable.

.accordion .title {
  display: block;
  padding: 0.75rem 1rem;
  background: #f0f0f0;
  cursor: pointer;
  border: 1px solid #ddd;
  font-weight: bold;
}

Feel free to change the colors to match your site. The cursor: pointer tells users they can click it.

Step 4: Hide the Content by Default

We’ll start with the content hidden. Using max-height: 0 and overflow: hidden lets us animate the opening later.

.accordion .content {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease;
  background: #fafafa;
  border-left: 1px solid #ddd;
  border-right: 1px solid #ddd;
  border-bottom: 1px solid #ddd;
  padding: 0 1rem;
}

Notice we still give it a little side padding so the text doesn’t touch the edge.

Step 5: Show the Content When Checked

Now the magic part. When the hidden checkbox is checked, we want the sibling .content to expand.

.accordion input:checked ~ .content {
  max-height: 200px; /* big enough for most content */
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
}

Why max-height: 200px? Because we need a value for the transition. If your content is taller, just increase the number or use max-height: 1000px. The transition will still look smooth.

Step 6: Make It Responsive

The accordion already works on any screen, but let’s add a tiny tweak so the titles wrap nicely on small devices.

@media (max-width: 600px) {
  .accordion .title {
    font-size: 0.9rem;
    padding: 0.6rem 0.8rem;
  }
}

That’s all the responsive part. The accordion will shrink its text a bit on phones, keeping the layout clean.

Step 7: Add a Little Arrow Indicator

A small arrow helps users see which sections are open. We can use a pseudo‑element on the label.

.accordion .title::after {
  content: "▸";
  float: right;
  transition: transform 0.3s ease;
}

.accordion input:checked + .title::after {
  transform: rotate(90deg);
}

The arrow points right when closed and rotates down when open. Simple, but it feels nice.

Step 8: Put It All Together

Here’s the full CSS you can copy into your stylesheet. I like to keep everything in one place for quick testing.

/* Hide the real checkbox */
.accordion input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

/* Title styling */
.accordion .title {
  display: block;
  padding: 0.75rem 1rem;
  background: #f0f0f0;
  cursor: pointer;
  border: 1px solid #ddd;
  font-weight: bold;
}

/* Arrow indicator */
.accordion .title::after {
  content: "▸";
  float: right;
  transition: transform 0.3s ease;
}

/* Content hidden by default */
.accordion .content {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease;
  background: #fafafa;
  border-left: 1px solid #ddd;
  border-right: 1px solid #ddd;
  border-bottom: 1px solid #ddd;
  padding: 0 1rem;
}

/* Show content when checked */
.accordion input:checked ~ .content {
  max-height: 200px;
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
}

/* Rotate arrow when open */
.accordion input:checked + .title::after {
  transform: rotate(90deg);
}

/* Small screen tweaks */
@media (max-width: 600px) {
  .accordion .title {
    font-size: 0.9rem;
    padding: 0.6rem 0.8rem;
  }
}

Drop the HTML from Step 1 into your page, link this CSS, and you’ve got a fully functional accordion that works on phones, tablets, and desktops. No JavaScript, no extra weight, just clean CSS.

A Quick Personal Note

I first tried a JavaScript accordion for a client project and spent an hour hunting down a tiny bug that only appeared on Safari. After that, I promised myself I’d keep a pure‑CSS version handy. Now I pull it out whenever a quick FAQ section is needed. It’s saved me a lot of headaches, and I love sharing the trick on CSS Tricks Reference because it’s something anyone can copy and use right away.

Wrap‑Up

Building a responsive accordion with only CSS is easier than you might think. The key is the hidden checkbox and the :checked selector. With a few lines of styling you get a smooth, accessible component that works everywhere. Next time you need an accordion, give this method a try. It’ll keep your page light and your code simple – exactly the kind of solution we love at CSS Tricks Reference.

Reactions
Do you have any feedback or ideas on how we can improve this page?