I had a little time to kill tonight so I decided to play around with HTML accordions, this is my experimentation using CSS3 to achieve what would normally be done with JavaScript.

The Result

After a couple hours of work I had three working examples using only HTML and CSS. Not perfect and far from being in a state to use commercially, but a proof of concept more or less.

  1. Vertical Accordion with 1 Visible Slide (using radio buttons for control)
  2. Vertical Accordion with Multiple Visible Slide (using checkboxes for control)
  3. Horizontal Accordion (using radio buttons for control)

These examples require the latest CSS3 selectors and transitions so it will only work correctly in a recent webkit or gecko browser. Eg: Chrome, Safari, Firefox.


Example 1: Vertical Accordion – 1 Visible Slide

See the Pen CSS3 Accordion (No Javascript) – Vertical – Single Visible by Michael Raffaele (@mraffaele) on CodePen.


Example 2: Vertical Accordion – Multiple Visible Slides

See the Pen CSS3 Accordion (No Javascript) – Vertical – Multiple Visible by Michael Raffaele (@mraffaele) on CodePen.


Example 3: Horizontal Accordion

See the Pen CSS3 Accordion (No Javascript) – Horizontal by Michael Raffaele (@mraffaele) on CodePen.


  1. rank one says:

    So I am guessing Google reads everything in all of these instead of being hidden by java?

    • Yes definitely although I honestly didn’t think about SEO when I made it. It was just an experiment with CSS3.

      I’m not 100% where google stands with javascript these days, but technically, even in examples using javascript, all the data is there (if not pulled in via ajax) so I don’t see why it would not be able to index the content using traditional methods.

  2. alvin says:

    This is cool.. I love it…
    But, why the nice hovering animation effect doesn’t work in Opera ?
    I can see it in Firefox, but not in my Opera 11.6…

    • Thanks!

      I hadn’t actually tested this in Opera but I assume the reason it wouldn’t work is because in my CSS I use “-webkit-transition” and “-moz-transition” to handle animations. Both of which are Webkit and Firefox specific prefixes.

      It may be as simple as adding a “-o-transition” property to handle the animations. I am unfamiliar with the Opera transition effects though, so am not 100% if it would work.

      Give it a try and let me know how you go :D

  3. Abdullah says:

    Hello bro,
    Sorry it’s not working on IE9!!, I know the firefox and chrome is beast of the browser but there is some crazy people working on this fu*** browser, Please I need solution.
    Thank you.

    • Hey thanks for the response. As I said in the article it is simply an experimentation so I did not expect it to be used it real projects.

      I’ve just had a quick look in IE9 and the only thing not working for me are the transitions, while not ideal this is expected as IE9 does not support transitions.

      If you need a real world solution I would look at using Javascript to control the accordion menu as Javascript animations generally work fine in all browsers.

  4. Martin Bartlett says:

    Very helpful example. I’m trying something slightly more complex – javascript gets run on the click on the header. What I’m seeing is that the height expansion gets done first then the height contraction, not both at the same time – so its very ugly. How does the CSS you have get both done at the same time?

    • Thanks Martin.

      Strange that the actions are running sequentially rather than simultaneously in Javascript. Typically to get events to run one after the other you specifically have to code it that way. If you can post an example over at http://jsfiddle.net/ I’m happy to take a quick look at it.

      CSS works much the same way as I would expect the JS to work, when the option is clicked both animations fire simultaneously. Eg: If I click “title two” the animation to close “title one” AND the animation to open “title two” execute at precisely the same moment. The also take the same amount of time to animate to keep it looking consistent.

      Does this make sense?

      • Martin Bartlett says:

        Thanks for the response – yes it does make sense.

        I’m taking your example and working it toward my situation (i.e. replacing the list and label elements with divs of different classes, using an onclick handler to change the “open state” instead of default radio button handler) – So far, it still all works simultaneously. I’ll let you know if I get to a point where I recreate my problem, or whether my investigations lead to solving my problem.

      • Martin Bartlett says:

        Actually I think I’ve figured it out – I’m doing SO much, and my “menu” is so big and complex (and dynamic) that something has give :-). When I run it through the debugger (and so events get more granular), it all works fine, but when I’m doing all my “populate div to be openned, mark radio button checked, process div just closed” processing, all those UI events get delayed and, it seems, it handles “look changes” and “expose” changes before it handles “hide” changes. Without some sophisticated event handling, I’m not gonna get this to work, I’m afraid. Oh well.

        • Good to hear you figured out the cause, its a shame you haven’t quite got the solution yet.

          From your comment it doesn’t sound like you are doing anything crazy so its still strange it doesn’t work. I’m a little confused as to why you are marking the radio button as checked, is it because you are working from my experiment?

          If so, you can skip that whole step, the only reason it is in this example is so the CSS can identify the current state.

          Nevertheless, shoot me through a link when you’re done, I’d love to see what it is you are trying to do :D

  5. Angel says:

    This is the only great example I have found for pure CSS accordions, I hate the JS versions of other accordions, I personally would love to see more use of the new CSS features. Thank you for posting this :)

  6. Steven says:

    Is there a way to have the box close when clicked, like the checkboxes, but also have it close when another box is clicked like the radio buttons?

    • Hi Steven,
      I don’t believe it possible without JavaScript as it is actually just a radio button. Radio buttons, unlike checkboxes, cannot be unchecked (unless a sibling is checked in its place).

  7. Irishgirl says:

    Will it work on iPhone? Web app or native app (HTML5 / Phonegap)

    • Hi, I’m honestly not sure as I have not tested on mobile devices. That being said this type of CSS has been used a lot more frequently since I had written this post and I would be surprised if it didn’t work.

  8. amrish mahajan says:

    Its very nice to see it working without js but not workin in safari

  9. Payman says:

    Hi, this is working really well. Just a quick question, when I wanted to put more than one of those in my page: let’s say two horizontal accordion each with 4 tabs! they interfere! I gave each one its individual name (id=radio-x)! but when I use the (checked=”checked”) only one tab of one block is open in initial load of the page! what is the trick to make both blocks have their checked-radio open? Thanks for the code! it is amazing!

    • Hey Payman, thanks for the comment.

      I’m not sure what issue you are running into but it seem to work fine for me. If you view my demo page you will see that I have three separate accordions on the same page.

      If you post some code I can try to have a look when I get some time if you like.

  10. pino says:

    Hi from Italy!

    About Example 2 I ask if is possible
    set a fixed background image into the “.accordion” class ?

    Thanks in advance for kind attention, best
    regards and many wishes for next XMas!!!

  11. Ryan says:

    This is a great function however can someone please help me with a small issue I am having… Is it possible to extend the size of each drop down box to fit the amount of content inside? It looks like each accordion drop down has a pre-set size, so if there is more content than what fits the size it simply doesn’t show it.. any ideas?

  12. Lisa Smith says:

    Hi there this is great – thanks so much. Is there a way that on first view all the boxes can be closed i.e. the first one not open, but still one closes when the next opens?

  13. Hey Lisa, thanks for the comment. Yes, we can absolutely do what you ask. All you need to do is have a look at the first example (with radio buttons) and remove the following code from the first element:

  14. Josh says:

    great post.

    I used this to create an accordion of posts from a WP page template we’re using. Only adjustment I had to make to get it to work with a dynamic feed was to add the code:

    $i = 0 (placed outside the loop)

    foreach (item as items)

    then add to the input


    works like a charm to pull posts and display them in an accordion format.

  15. CJ says:

    Is it possible to link to a specific accordion from another page so that when I click the link it goes directly to the open section of the accordion?

    • Hey CJ, yes that is absolutely possible, although JavaScript would be required to do so.

      One solution may be to add a hash tag to the url, e.g. ‘index.html/#/section-1’ and then use javascript to trigger the click based on the hash.

      You can access the hash with the following document.location.hash.

  16. Stephanie says:

    Hey there! I’m currently coding my website and I find that when you place two of the same accordion (I copied and pasted the same one, rewording the text)

    The 2ND accordion, when clicking on the first, second, third and so forth tabs, they make the 1ST accordions tabs drop down…is there a way to fix this? Please help!

    • Hey Stephanie, thanks for the comment. If I understand your comment correctly, the solution should be as simple as ensuring that all of the input/labels have unique ids. For example:

      <input type="radio" id="radio-1" name="radio-accordion" checked="checked" />
      <label for="radio-1">Title One</label>

      If you have multiple inputs labelled “radio-1” then issues will arise. In my example I have radio-1 through radio-4, if you continue incrementing in your new accordion you should be fine.

      • Stephanie says:

        Thanks so much! I thought I wouldn’t get a reply because of the date of the last comment lol, but I actually solved my own problem while I was away lol…but another question, I have created a FAQ section using the same accordion menu, BUT, it expands out way too far, leaving extra white area. Is there a way to make the menu only drop down to where the content ends?

  17. Tony says:

    Hey man, you work miracles, this was just what I was looking for. Amazing job. Tony.

  18. Max says:

    Hey. Thanks so much for taking the time to do this. I was wondering if there was any way to make sure it works with older versions of IE? I know it’s been mentioned before but I thought maybe there could be a way now…I’ve been looking for something like this for a long time as I don’t want to use JavaScript but I’d love for it to work everywhere if possible. Even if all the transitions etc. didn’t work and everything was just open on old IE. That would be fine. At the moment everything stays closed.

    Any help would be amazing! Thanks again.

    • Max says:

      Sorry one other thing. I’ve been trying for about an hour now to get the content box to automatically size. Someone else mentioned that to do so you need to edit the “overflow” but for the life of me I cannot seem to figure this out. Sorry to be a bother

      • To get the box to automatically size you simply need to replace height: 300px with height: auto;. The catch here is that it will no longer be able to smoothly open and close as that style of transition requires a fixed height.

    • Hi Max, thanks for your comment.

      Unfortunately there really isn’t anyway to get this accordion working in IE7 as it makes use of CSS3 selectors which simply will not work. The issue isn’t the transitions, or lack thereof, it is that IE7 doesn’t support [type=radio]:checked ~ label.

  19. Max says:

    Hi, Thanks for your reply.

    I’ve been trying to look into this more and was wondering if feature detection might work? I don’t understand how to implement it but was hoping you might have an idea?

    • Hi Max, no problems.

      Feature detection could maybe help (look into Modernizr), though it relies on using JavaScript.

      To be completely honest with you, by implementing feature detection I think you’re overcomplicating it. Unless you have a specific reason or requirement to not use JS it is absolutely your best solution in this situation.

  20. Max says:


    Thanks again for getting back to me, your help is hugely appreciated.

    Annoyingly I cannot use JavaScript. I’m designing my site on Smugmug and it’s not compatible with their system. Very frustrating…

  21. Amy H. E. says:

    Thanks a bunch, these are what I was looking for! :-)

  22. hi all, i have a little tiny question about the accordion menu. When I open the first tab my page scrolls to the top every time I click on a tab…something is pushing it to the top. I tried several codes but none of them let the menu stay on its place. Its very annoying and I guess its something simple to handle…but what..anyone who can help me?

  23. Tobias says:

    I’ve tried this, and the Accordian from W3Schools (using javascript). In both cases, the accordians work in IE11. Then when I copy the code out into a separate file, it doesn’t work in IE11. Very weird.

  24. Fadhel says:

    how can I change label text direction?!

  25. Alvaro says:

    Hi there! Such a good write-up, thanks!