CSS only accordion

CSS only accordion
CssTutorial

Accordions can be a great way to display a lot of information in a small amount of space and can be a great addition to any website or web application. We will be using the details and summary HTML elements as a starting point.

This will allow us to not use any JavaScript and to focus on a CSS only approach to land a great design. This article piece is therefore in line with two previous articles: a Navbar that works without any JS and a switch toggle button with no script.

As you already understood, in this tutorial, we will be building an accordion component using only CSS. Let's dive into it with accessibility in mind and ensuring a correct cross-browser compatibility.

Start from the details and summary elements

The HTML structure of the accordion component is relatively straightforward. Each accordion item consists of a title and a content area. The title serves as the button that expands and collapses the content area. The content area is hidden by default and is only shown when the title is clicked.

As we know all that, let's look at the code right now.

<details class="accordion">
  <summary class="accordion__title">Accordion title</summary>
  <div class="accordion__content">
    <p>Lorem ipsum dolor sit amet...</p>
  </div>
</details>

By utilizing the native functionality of the details and summary elements, we already have an accessible and working accordion. But let's design it!

Modify the accordion style

Let's add some basic styles to our accordion. Pay attention to the use of the + adjacent sibling combinator which helps us add spacing between elements that follow one another.

.accordion {
  border: solid 2px #f5f5f5;
  transition: all 0.3s ease-in-out;
  & + & {
    margin-top: 0.25rem;
  }
  &:hover {
    background-color: #f5f5f5;
  }
}
.accordion__title {
  cursor: pointer;
  font-size: 1rem;
  font-weight: 700;
  color: #555555;
}
.accordion__content {
  padding: 0 1rem 1rem 1rem;
  p {
    margin: 0;
  }
  p + p {
    margin-top: 0.5em;
  }
}

Design the accordion title

We will now tweak the typical accordion design by getting rid of the default arrow that appears on the left of the collapse. To influence most browser we will use list-style-type, but a couple more lines are needed for others.

.accordion__title {
  list-style-type: none;
  &::marker,
  &::-webkit-details-marker {
    display: none;
  }
}

And adding a new arrow using data URI as a background-image.

.accordion__title {
  background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg width='32' height='32' viewBox='0 0 32 32' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M23.024 11.263l-7.024 7.023-7.022-7.023-3.091 3.090 8.569 8.569c0.413 0.413 0.961 0.64 1.545 0.64s1.133-0.228 1.545-0.64l8.569-8.569-3.091-3.090z' fill='%23555555'/%3e%3c/svg%3e");
  background-repeat: no-repeat;
  background-position: right 0.75rem top 0.625rem;
  background-size: 1.5rem;
  padding: 0.875rem 2.5rem 0.875rem 0.875rem;
}

Manage the open state

We are almost ready with our collapse. Last step is to adapt its design when in an open state. We will leverage the power of the attribute selection of CSS; [open];

.accordion {
  &[open] {
    background-color: #ebebeb;
    border-color: #ebebeb;
    .accordion__title {
      background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg width='32' height='32' viewBox='0 0 32 32' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M8.976 22.025l7.024-7.023 7.022 7.023 3.091-3.090-8.568-8.568c-0.413-0.412-0.961-0.64-1.545-0.64s-1.133 0.228-1.545 0.64l-8.569 8.569 3.091 3.090z' fill='%23555555'/%3e%3c/svg%3e");
    }
  }
}

In the codepen linked, you will also find a way to animate the opening of an accordion element commented out. I'm not fully convinced by that workaround and that's why I don't detail it in this post.

If Sass is not your friend, copy-paste and transpile it into CSS on https://www.sassmeister.com/ or https://sass.js.org/.

Completed accordion look

We did it! A fully accessible, well-designed and smooth accordion. You probably observed the use of rem, meaning our component will follow the html element font-size.

TLDR: See the finalised code for this CSS only accordion on Codepen. You can take any level of inspiration from this and use it in your future developments.

Enjoy coding with CSS!

Please open this website with a recent browser for the best experience. Avoid Internet Explorer at all costs.