Simple Responsive Accordion With Pure CSS – Free Code Download

Welcome to a tutorial on how to create a simple responsive accordion. Yes, there are a lot of “accordion plugins” in the world, but some of them require a third-party framework. It simply does not make sense to load an entire library for a single accordion – So here it is, a super lightweight accordion using only pure CSS. Read on!

ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.

 


 

REAL QUICK TUTORIAL


 

TABLE OF CONTENTS

Download & Notes CSS Accordion Useful Bits
The End

 

DOWNLOAD & NOTES

Firstly, here is the download link to the example code as promised.

 

EXAMPLE CODE DOWNLOAD

Click here to download all the source code in a zip file – I have released it under the MIT License, so feel free to build on top of it if you want to.

 

QUICK NOTES

If you spot a bug, please feel free to comment below. I try to answer questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

 

CSS ACCORDION

All right, let us now get into creating an accordion using pure HTML and CSS.

 

1) CHECKBOX ACCORDION

THE DEMO

Next to the risk dictates a nurse.

Should the pace attack?

A circumstance strikes a deserved trap.

 

THE HTML

1-accordion.html
<!-- FIRST TAB -->
<div class="tab">
  <input id="tab-1" type="checkbox">
  <label for="tab-1">Tab 1</label>
  <div class="tab-content"><p>Next to the risk dictates a nurse.</p></div>
</div>

<!-- SECOND TAB -->
<div class="tab">
  <input id="tab-2" type="checkbox">
  <label for="tab-2">Tab 2</label>
  <div class="tab-content"><p>Should the pace attack?</p></div>
</div>

<!-- THIRD TAB -->
<div class="tab">
  <input id="tab-3" type="checkbox">
  <label for="tab-3">Tab 3</label>
  <div class="tab-content"><p>A circumstance strikes a deserved trap.</p></div>
</div>

The HTML should be straightforward enough.

  • Create a <div class="tab"> container.
  • Sandwich 3 things inside the container.
    • <input id="tab-2" type="checkbox"> Required to toggle show/hide the tab contents.
    • <label> The tab label itself.
    • <div class="tab-content"> The tab contents.
  • That’s all. Create as many <div class="tab"> sections as required.

 

 

THE CSS

1-accordion.css
/* (A) TABS CONTAINER */
.tab {
  position: relative;
  max-width: 600px;
}

/* (B) HIDE CHECKBOX */
.tab input { display: none; }

/* (C) TAB LABEL */
.tab label {
  display: block;
  margin-top: 10px;
  padding: 10px;
  color: #fff;
  font-weight: bold;
  background: #2d5faf;
  cursor: pointer;
}

/* (D) TAB CONTENT */
.tab .tab-content {
  background: #ccdef9;
  /* CSS ANIMATION WILL NOT WORK WITH AUTO HEIGHT */
  /* THIS IS WHY WE USE MAX-HEIGHT INSTEAD */
  overflow: hidden;
  transition: max-height 0.3s;
  max-height: 0;
}
.tab .tab-content p { padding: 10px; }

/* (E) OPEN TAB ON CHECKED */
.tab input:checked ~ .tab-content { max-height: 100vh; }

/* (F) EXTRA - ADD ARROW INDICATOR */
.tab label::after {
  content: "\25b6";
  position: absolute;
  right: 10px;
  top: 10px;
  display: block;
  transition: all 0.4s;
}
.tab input:checked ~ label::after { transform: rotate(90deg); }

/* (X) DOES NOT MATTER */
html, body { font-family: arial, sans-serif; }

This may look complicated, but the basic mechanic is actually very simple.

  1. First, hide the ugly checkbox – .tab input { display: none; }
  2. Hide the tab contents by default – .tab .tab-content { max-height: 0 }
  3. Show the tab contents when the checkbox is checked (when we click on the label) – .tab input:checked ~ .tab-content { max-height: 100vh; }.

Yep, that’s all. The rest is pretty much just cosmetics.

 

 

2) RADIO BUTTON ACCORDION

THE DEMO

Next to the risk dictates a nurse.

Should the pace attack?

A circumstance strikes a deserved trap.

 

THE HTML

2-radio.html
<!-- FIRST TAB -->
<div class="tab">
  <input id="tab-1r" type="radio" name="tabr">
  <label for="tab-1r">Tab 1</label>
  <div class="tab-content"><p>Next to the risk dictates a nurse.</p></div>
</div>

<!-- SECOND TAB -->
<div class="tab">
  <input id="tab-2r" type="radio" name="tabr">
  <label for="tab-2r">Tab 2</label>
  <div class="tab-content"><p>Should the pace attack? </p></div>
</div>

<!-- THIRD TAB -->
<div class="tab">
  <input id="tab-3r" type="radio" name="tabr">
  <label for="tab-3r">Tab 3</label>
  <div class="tab-content"><p>A circumstance strikes a deserved trap.</p></div>
</div>

Look no further, the only difference here is that we are using the radio button and not checkboxes – This will enforce “only one tab can be opened at a time” for those who need.

 

 

USEFUL BITS

That’s all for this guide, and here is a small section on some extras that may be useful to you.

 

OPENING TABS “BY DEFAULT”

How do we set a tab to be opened on page load? Very simply set the checked attribute – <input type="checkbox" checked>.

 

RADIO ACCORDION RESTRICTION

Well, as some may have already noticed. The default behavior in HTML is that one radio button will be selected at all times, and there is no way we can unselect without using Javascript. So yes, the “restriction” in the radio button accordion is that one tab will be opened at all times.

 

YOUTUBE TUTORIAL

 

INFOGRAPHIC CHEAT SHEET

Pure CSS Accordion (click to enlarge)

 

THE END

Thank you for reading, and We have come to the end of this guide. I hope that it has helped you to create a better website, and if you have anything to share with this guide, please feel free to comment below. Good luck and happy coding!

10 thoughts on “Simple Responsive Accordion With Pure CSS – Free Code Download”

  1. Thanks again for this. It is great. I have noticed an odd quirk perhaps. For the radio – one at a time drop-downs there seems to be an issue with scrolling when viewing on small screens so that sometimes when you click on a tab, the browser scrolls too far and you have to manually scroll back up to read the contents of the tab. Here is what I did to replicate which might explain better:
    1) Include lots of paragraphs of text in each drop-down.
    2) Include a few paragraphs of text after the drop-down (that is, paragraphs under the drop-down)
    3) Click Tab 1. It displays fine.
    4) Scroll down to Tab 2 and click Tab 2. It displays fine.
    5) Scroll down to Tab 3 and click Tab 3. The browser scrolls down too far and you have to scroll back up to view the start of the text in Tab 3.

    This only occurs on small sized screens. This behaviour does not occur on larger screens. I am not sure what causes it. Maybe there is a limitation on the amount of content you can include in a tab maybe?

    1. Well, you kind of already answered your own question. That is a browser behavior and that is just the way how it renders the HTML/CSS… More CSS probably won’t fix anything. I will limit the content, or use Javascript to listen to the animationend event, then scroll back up automatically.

  2. Thanks so much for this.
    One thing, though. I found that the absolute positioning of the label icon produced undesirable results. The icon – I chose plus and minus for this – was positioned to the edge of the window.
    I fixed this by making the label element a flexbox.
    Thanks again.

  3. Thank you for this tutorial! You saved me a lot of time and headache!! So many accordions require JS, and I’m excited to have found one that doesn’t.

  4. This is fantastic. I was using a javscript version, but this is working better. One quick question, for the radio button options, if I click Tab 1 to expand, is there any way I can click Tab 1 again to collapse it?

  5. Nice! I’ve been looking for an accordion solution that doesn’t include Javascript which clean and simple. Is there an way to set, by default, one of the tabs to be open? Thanks in advance!
    Jake

Leave a Comment

Your email address will not be published. Required fields are marked *