How to Build an Accordion Component With the CSS Checkbox Hack

Final product image
What You’ll Be Creating

In this short tutorial, we’ll learn how to build a CSS-only flexible accordion component by taking advantage of the “CSS checkbox hack technique”. Most importantly, our component will be fully responsive and its layout will switch between horizontal and vertical depending on the viewport size. 

Along the way, we’ll discuss how the CSS Checkbox Hack works, and look at some other Checkbox Hack inspiration from developers on CodePen. Sound interesting?

Our Responsive CSS Accordion

Here’s what we’ll be building during this tutorial:

Note: This tutorial assumes some flexbox knowledge. If you’re just beginning, check out this beginners flexbox tutorial:

Wait, What’s the CSS Checkbox Hack?

The CSS checkbox hack allows you to control certain styles depending on whether checkboxes (or radio buttons) are checked or not. It uses the :checked pseudo-class selector, which enables us to say “if a checkbox is checked, apply these style rules to its sibling etc.”

Developers usually hide the input itself, controlling the checked value via its label, so users can’t even tell they’re toggling a checkbox at all.

It’s a favourite of mine; in fact, I’ve used the same technique in several tutorials:

1. Begin With the HTML Markup

For the purposes of this exercise, we’ll grab some content from Wikipedia about four different things: animals, plants, space, and rivers.

Then, we’ll create the corresponding radio buttons which we’ll group under the wiki keyword:

Build an Unordered List

Next up, we’ll specify an unordered list with four list items. Each list item will represent an accordion item/pane and hold two elements: 

  1. Firstly, a label which will serve as the accordion’s title and be responsible for opening the target item. Its for value should match the id value of one of the aforementioned radio buttons. 
  2. Secondly, a div  element which will serve as the accordion’s content area.

By default, one pane in our accordion must be open. With that in mind, let’s add the checked attribute to the first radio button.

Putting it all together, here’s the markup that we’ll need:

2. Define the Styles

With the markup ready (and inline with the CSS checkbox hack I described earlier) we’ll first visually hide the radio buttons by moving them off screen:

The accordion will have a maximum width, a minimum height, and behave as a flex container:

Also, each list item will serve as a flex wrapper:

The accordion items should be separated, so let’s give them a border:

Each title (label) inside an item will be a flex container and its child elements will be distributed vertically across the main axis. In addition, all items will have a 70px width:

The text inside the .accordion-heading will be rotated vertically:

Initially, apart from the first pane, all the other panes will be hidden:

3. Checkbox Hack: Toggle the Panes

Now for the Magic. Each time we click on a label, its associated content should appear. To make that happen, we’ll take advantage of the :checked pseudo-class, the subsequent-sibling selector (~), and the adjacent sibling combinator (+). If you need a refresher of what these selectors do, check out this tutorial:

So, when an item becomes visible, it will receive display: flex and not display: block. This is because we want to vertically center its content by taking advantage of the align-items: center property value. Additionally, the colors of the active pane have to change, so a visitor can clearly understand which pane is open.

Optionally, each time a radio button receives focus, we can add an outline to its associated label. This small detail will help us enhance the accessibility of our component.

Here’s the related CSS stuff:

4. Going Responsive

As we’ve already discussed, on small screens the items inside the accordion should be stacked, so the accordion will have a vertical layout. Thanks to flexbox, we can implement this design without putting in too much effort. In fact, all we have to do is to update the direction of the flex wrappers and reset the transform property value of the .accordion-heading.

Have a look at the responsive styles within a media query below:

5. Bonus: Limited Content

In our case, there’s a lot of content inside each of the accordion items, so everything looks great. But, let’s ensure that the accordion will still work fine when there isn’t enough content within the panes (e.g. a pane contains only social links). 

The accordion with limited content

To satisfy this scenario, we have to do two things:

  • Add flex-grow: 1 to the list item which contains the active pane. To target only that item and not all of them, we’ll need to add a new custom attribute (data-radio) to the list items with value their label’s value.
  • Add flex-grow: 1 to the .accordion-content, so it will expand and cover the full parent width.
  • Center horizontally the content of the .accordion-content thanks to the justify-content: center.

With all the above in mind, we’ll modify our HTML as follows:

Then, in the CSS we’ll include these styles:

Conclusion

That’s it folks! In this quick tutorial, we managed to build a pure CSS accordion by taking advantage of the “CSS checkbox hack technique”. Hopefully, you enjoyed this exercise and you’ll spend some time extending it for your own specific purposes.

Here’s a reminder of what we built:

Extra Project

To conclude, just keep in mind that with this implementation only one pane of the accordion can be open at a time. That’s because we used radio buttons in the markup. In case you want to display multiple accordion items at the same time, replace the radio buttons with checkboxes and make the necessary changes (hide the checkboxes) in the CSS.

As always, thanks a lot for reading!

Checkbox Hack Inspiration on CodePen

Where better to see what others have built with the CSS Checkbox Hack than CodePen? Here are some great examples to whet your appetite:

Responsive Emoji Toggles by George W. Park

CSS Only Tabbed Content by Stephen Greig

Modal pure CSS – “Checkbox Hack” by BeardedBear

CSS checkbox hack nav by JAD3

Further Reading

Check out these resources to learn more about similar CSS techniques, and other ways of building accordion components (did someone say Bootstrap?!):