DEV Community

loading...
Cover image for How to build a pure CSS accordion

How to build a pure CSS accordion

cchana profile image Charanjit Chana Originally published at 1thingaweek.com ・2 min read

I had this topic in mind, but planned to build it using CSS and vanilla JS as follow up to an article from a few months ago where I built pure CSS tabs and carousels. Then this past week I came across an article about pure CSS tabs making use of the :target pseudo class and my mind is blown.

The demo

Jumping straight into it, here's the demo with the markup and SCSS I used to create the simple layout:

The explanation

The important bit is making use the of the :target pseudo-class. Here's a dt element containing a link that takes you to the element with the id #first.

<dt id="first"><a href="#first">First heading</a></dt>
Enter fullscreen mode Exit fullscreen mode

In my case there's effectively one and the same thing. The parent element has the ID we're looking for but this could be anywhere on the page. If this was a carousel, perfect for highlighting the current tab!

As for the CSS, we simply take the highlighted dt and reveal the adjacent dd which contains the content for that part of the accordion.

&:target {
    + dd {
        display: block;
    }
}
Enter fullscreen mode Exit fullscreen mode

My demo is a little more complicated because I've added rounded borders and tried to cater for various browser quirks when it comes to the border-radius property. Browser support is pretty good for the :target pseudo-class so not too much to worry about there.

The one drawback I've found is that there's no obvious way to do this with just CSS. With a bit of JavaScript you could remove the target from the URL but in that case I'd not bother with a pure CSS solution and just do it with a minimal amount of vanilla JavaScript.

I also haven't catered for the scenario where you would want to allow for the entire accordion to be open or to have a default open. The later could be solved with a bit of additional CSS, but the former would require JavaScript again as far as I can see.

CSS FTW!

Discussion (0)

pic
Editor guide