Menu

How to Create CSS-Only Accordions

How to Create CSS-Only Accordions

Accordions are great space-saving UI components that allow users to show and hide content sections without cluttering the page. While many developers reach for JavaScript to create accordions, you can build them using only CSS.

In this article we'll be creating an accordion component relying solely on CSS using a few clever tricks.

What We're Building

We'll create a simple accordion that:

  • Expands/collapses when clicked
  • Shows a visual indicator for the open/closed state
  • Works without any JavaScript
  • Is keyboard accessible

The final output will look like the following:

CSS (Cascading Style Sheets) is the language used to style web pages. It describes how HTML elements should be displayed, controlling layout, colors, fonts, and more.

CSS allows you to separate the presentation of a document from its content, making maintenance easier.

This accordion works by using hidden checkboxes and the CSS sibling selector (~).

When you click on a label, it toggles the associated checkbox. We then use CSS to detect the checkbox's state and show or hide the content accordingly.

No JavaScript is needed for this functionality!

CSS-only solutions have several benefits:

  • Faster performance (no JavaScript parsing/execution)
  • Works even if JavaScript is disabled
  • Less code to maintain
  • No dependencies on external libraries

This CSS-only accordion works in all modern browsers including:

  • Chrome
  • Firefox
  • Safari
  • Edge

The technique relies on CSS transitions and the sibling selector, which are widely supported.

The HTML Structure

First, let's set up our HTML:

<div class="accordion">
  <!-- First Accordion Item -->
  <div class="accordion-item">
    <input type="checkbox" id="accordion-1" class="accordion-toggle">
    <label for="accordion-1" class="accordion-title">
      What is CSS?
      <span class="accordion-icon"></span>
    </label>
    <div class="accordion-content">
      <p>CSS (Cascading Style Sheets) is the language used to style web pages. 
         It describes how HTML elements should be displayed.</p>
    </div>
  </div>
  
  <!-- Second Accordion Item -->
  <div class="accordion-item">
    <input type="checkbox" id="accordion-2" class="accordion-toggle">
    <label for="accordion-2" class="accordion-title">
      How does CSS work?
      <span class="accordion-icon"></span>
    </label>
    <div class="accordion-content">
      <p>CSS works by selecting HTML elements and applying styles to them. 
         The browser combines the content and styling to render the page.</p>
    </div>
  </div>
</div>

The key to our solution is the hidden checkbox (input type="checkbox") combined with a label.

When a user clicks the label, it toggles the checkbox, which we'll use to control the accordion's open/closed state.

The CSS Magic

/* Basic styling for the accordion container */
.accordion {
  width: 100%;
  max-width: 600px;
  margin: 0 auto;
  border-radius: 8px;
  overflow: hidden;
}

/* Style for each accordion item */
.accordion-item {
  border-bottom: 1px solid #e0e0e0;
}

/* Hide the checkbox visually but keep it accessible */
.accordion-toggle {
  position: absolute;
  opacity: 0;
  z-index: -1;
}

/* Style the accordion title/header */
.accordion-title {
  display: flex;
  justify-content: space-between;
  padding: 16px;
  background: #f7f7f7;
  cursor: pointer;
  font-weight: 500;
}

/* Create the plus/minus icon */
.accordion-icon {
  position: relative;
  width: 14px;
  height: 14px;
}

.accordion-icon::before,
.accordion-icon::after {
  content: '';
  position: absolute;
  background-color: #333;
  transition: transform 0.25s ease-out;
}

/* Horizontal line */
.accordion-icon::before {
  top: 6px;
  left: 0;
  width: 14px;
  height: 2px;
}

/* Vertical line (becomes hidden when expanded) */
.accordion-icon::after {
  top: 0;
  left: 6px;
  width: 2px;
  height: 14px;
}

/* Style for accordion content */
.accordion-content {
  max-height: 0;
  padding: 0 16px;
  overflow: hidden;
  background: white;
  transition: max-height 0.25s ease-in-out, padding 0.25s ease;
}

/* When checkbox is checked, expand the content */
.accordion-toggle:checked ~ .accordion-content {
  max-height: 500px; /* Adjust based on your content needs */
  padding: 16px;
}

/* Rotate the plus into a minus when open */
.accordion-toggle:checked ~ .accordion-title .accordion-icon::after {
  transform: rotate(90deg); /* Makes vertical line disappear */
}

/* Accessibility: Focus styles */
.accordion-toggle:focus ~ .accordion-title {
  outline: 2px solid #4a90e2;
}

How It Works

Let's break down the key CSS techniques used:

  • Hidden Checkbox: We use opacity: 0 and position: absolute to hide the checkbox visually while keeping it accessible to screen readers and keyboard navigation.

  • The Adjacent Sibling Selector (~): This is crucial for our CSS-only solution. The tilde selector targets sibling elements that follow the checkbox. When the checkbox state changes (by clicking the label), we can style elements that come after it.

  • max-height Transition: We set max-height: 0 for the collapsed content and expand it when the checkbox is checked. Using max-height instead of height allows us to accommodate content of varying lengths.

  • Plus/Minus Icon: The icon is created using pseudo-elements (::before and ::after). We create perpendicular lines and rotate one of them when the accordion is open to create a minus sign.

  • Focus Styles: We include styles for keyboard focus, ensuring our accordion is accessible to users navigating with a keyboard.

Making It Even Better

For a more robust accordion, consider these enhancements:

/* For smoother animations, consider using transform instead of max-height */
.accordion-content {
  transform: translateY(-20px);
  opacity: 0;
  transition: transform 0.3s, opacity 0.3s, padding 0.3s;
}

.accordion-toggle:checked ~ .accordion-content {
  transform: translateY(0);
  opacity: 1;
}

/* Add hover effect for better UX */
.accordion-title:hover {
  background: #efefef;
}

Browser Support

This CSS-only accordion works in all modern browsers. The technique relies on:

  • CSS transitions (supported in all modern browsers)
  • The CSS sibling selector (~) (widely supported)
  • Checkbox state (fundamental HTML feature)

Conclusion

Creating an accordion with CSS alone is not only possible but fairly straightforward. It offers a lightweight solution without the overhead of JavaScript libraries.

By leveraging the hidden checkbox technique, you can create interactive components that respond to user input with pure CSS.

Remember that while this approach works well for simple accordions, more complex functionality (like ensuring only one panel is open at a time or controlling accordions programmatically) will still require JavaScript.

Walter Guevara is a Computer Scientist, software engineer, startup founder and previous mentor for a coding bootcamp. He has been creating software for the past 20 years.
AD: "Heavy scripts slowing down your site? I use Fathom Analytics because it’s lightweight, fast, and doesn’t invade my users privacy." - Get $10 OFF your first invoice.

Community Comments

No comments posted yet

Code Your Own Classic Snake Game – The Right Way

Master the fundamentals of game development and JavaScript with a step-by-step guide that skips the fluff and gets straight to the real code.

Ad Unit

Current Poll

Help us and the community figure out what the latest trends in coding are.

Total Votes:
Q:
Submit

Add a comment