Subscribe

CSS Only Accordion

โœ๏ธ

CSS Only Accordion with the input hack

17 Apr, 2020 ยท 4 min read

Another great example where we can make the web lean again.

Accordions don't even need to have fancy JavaScript plugins. Surely we can do it simply in Vanilla JavaScript, but sometimes it's best to even look at other solutions.

Today we will look into doing a CSS-only accordion with the input hack.

There are multiple ways of doing it with CSS. But today, we will look into just the input hack.

HTML Setup for CSS only Accordion

For the HTML part we are going to use the following:

<div class="accordion">
  <input type="checkbox" id="tab1" />
  <label class="accordion-label" for="tab1">Item 1</label>
  <div class="accordion-content">
    Lorem ipsum dolor sit amet consectetur, adipisicing elit. Ipsum, reiciendis!
  </div>
</div>

This will generate one accordion for us. As you can see, we use a checkbox and a label. The label will be our accordion title.

CSS for the Accordion

input {
  position: absolute;
  opacity: 0;
  z-index: -1;
}
.accordion {
  margin: 10px;
  border-radius: 5px;
  overflow: hidden;
  box-shadow: 0 4px 4px -2px rgba(0, 0, 0, 0.5);
}
.accordion-label {
  display: flex;
  justify-content: space-between;
  padding: 1em;
  font-weight: bold;
  cursor: pointer;
  background: #333;
  color: #fff;
}
.accordion-content {
  max-height: 0;
  padding: 0 1em;
  background: white;
  transition: all 0.35s;
}
input:checked ~ .accordion-content {
  max-height: 100vh;
  padding: 1em;
}

Let's loop through this in more detail step by step:

input {
  position: absolute;
  opacity: 0;
  z-index: -1;
}

We don't need the input visible, so we give it a postion: absolute; and z-index: -1 to hide it. We set the opacity: 0 so it's not visible to the user.

.accordion {
  margin: 10px;
  border-radius: 5px;
  overflow: hidden;
  box-shadow: 0 4px 4px -2px rgba(0, 0, 0, 0.5);
}

For the main accordion styling, we do some simple styling.

We set a margin of 10px to give it some space. Then we make the corners rounded with border-radius: 5px;. Then we also set the overflow: hidden to not make the accordion content show before clicking the label. Lastly, we set a nice box-shadow to give it a clean effect.

.accordion-label {
  display: flex;
  padding: 1em;
  font-weight: bold;
  cursor: pointer;
  background: #333;
  color: #fff;
}

The label we give a display: flex to make full width. Then we add some padding, make the font bold, add a cursor: pointer, and add some color to make it pop.

.accordion-content {
  max-height: 0;
  padding: 0 1em;
  background: white;
  transition: all 0.35s;
}

We set the content div to have a max-height: 0 give it a small padding, and add a transition to make it animated once it opens.

input:checked ~ .accordion-content {
  max-height: 100vh;
  padding: 1em;
}

No for the magic, once the input is checked we set the max-height: 100vh (100% of the viewport) and add the overall padding to the content div.

The ~ is a general sibling selector it will select a sibling that follows the first one.

See the following Codepen for a demo:

See the Pen CSS Only Accordion by Chris Bongers (@rebelchris) on CodePen.

Or see this example a bit more styled and more options:

See the Pen Challenge #3 by Chris Bongers (@rebelchris) on CodePen.

Thank you for reading, and let's connect!

Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter

Spread the knowledge with fellow developers on Twitter
Tweet this tip
Powered by Webmentions - Learn more

Read next ๐Ÿ“–

CSS Logos: Vue logo

22 Jun, 2022 ยท 3 min read

CSS Logos: Vue logo

CSS Logos: Strava logo

21 Jun, 2022 ยท 5 min read

CSS Logos: Strava logo

Join 1513 devs and subscribe to my newsletter