A while ago, I wrote about the CSS3 :target pseudo-class and how can that help you achieve cool results. Today you’ll learn how to create a pretty simple animated CSS3 accordion with its help.

What is an accordion
If you’re designing with usability in mind, then an accordion can be very useful when willing to organize content. The main advantage is packing a lot of content in a reduced space.
HTML5 part
For this experiment I’ll use one of the new HTML5 elements, it’s about the section element. When using new HTML5 elements like this one, for older browsers, you need to use the following trick:
<script>document.createElement('section');</script>
To simplify things here, I just used the de facto script for enabling HTML5 elements in Internet Explorer. It’s about Remy Sharp’s html5shiv:
<!--[if lt IE 9]> <script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script> <![endif]-->
Markup
Enough with theory, let’s see how this actually works:
<div class="accordion"> <section id="one"> <h2><a href="#one">Heading 1</a></h2> <div> <p>content</p> </div> </section> </div>
- The
accordiondiv wraps the sections that compose the proper accordion. - Each
sectionpanel contains a title and of course its content.
CSS
section
{
display: block;
}
.accordion
{
background-color: #eee;
border: 1px solid #ccc;
width: 600px;
padding: 10px;
margin: 50px auto;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
-moz-box-shadow: 0 1px 0 #999;
-webkit-box-shadow: 0 1px 0 #999;
box-shadow: 0 1px 0 #999;
}
.accordion section
{
border-bottom: 1px solid #ccc;
margin: 5px;
background-color: #fff;
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#eee));
background-image: -webkit-linear-gradient(top, #fff, #eee);
background-image: -moz-linear-gradient(top, #fff, #eee);
background-image: -ms-linear-gradient(top, #fff, #eee);
background-image: -o-linear-gradient(top, #fff, #eee);
background-image: linear-gradient(top, #fff, #eee);
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
.accordion h2,
.accordion p
{
margin: 0;
}
.accordion p
{
padding: 10px;
}
.accordion h2 a
{
display: block;
position: relative;
font: 14px/1 'Trebuchet MS', 'Lucida Sans';
padding: 10px;
color: #333;
text-decoration: none;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
.accordion h2 a:hover
{
background: #fff;
}
.accordion h2 + div
{
height: 0;
overflow: hidden;
-moz-transition: height 0.3s ease-in-out;
-webkit-transition: height 0.3s ease-in-out;
-o-transition: height 0.3s ease-in-out;
transition: height 0.3s ease-in-out;
}
.accordion :target h2 a:after
{
content: '';
position: absolute;
right: 10px;
top: 50%;
margin-top: -3px;
border-top: 5px solid #333;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
}
.accordion :target h2 + div
{
height: 100px;
}
Result

Browser support
The demo works in browsers that support the :target pseudo-class. Check compatibility table for more details.
So, if you want to use this for your projects, you must be aware that the above isn’t a cross-browser solution.
Later update: Jquery solution
If the above isn’t a recommended solution to use for production purposes because of support lacking for older browsers, the below solution is a cross-browser one.
Please check the Jquery demo, I hope it will help you!
Hey, I am surprised to know this is really possible.
I mean this awesome dude, no jQuery, no and JS and this is pretty smooth as well.
Hey team, You are great!
Very nice Red. Really smooth and light-weight.
Very nice tutorial, thanks for posting it.
I noticed something that might be a bit inconvenient to some people, and that is the back button of the browser registering all of my clicks on the accordion. It means that I need to click the back button many times in order to go back a page. Just my 2 cents.
Thank you all for your comments!
@Endre, the reason why this behavior is encountered is because the “jump links” method is used here.
The fact that clicking “back” doesn’t take you to the previous page is an disadvantage when dealing with “within-page links “.
Very cool!
Hm, it would be better to use :not(:target) to hide the divs initially, because otherwise you will run into big problems like stupid browser (especially IE 8).
Excellent tutorial, very well done, thanks
HTML5 & CSS3 makes web design fun :D
Really nice tutorial!
How can I add jquery fallback to these beautiful animations? I have to support IE8. Thanks so much for this inspiring piece of code.
Mark, I’m planning to create a Jquery fallback example for this accordion. So, stay tunned! :)
Please do! Thanks again!
Mark, now you can check the Jquery demo!
hello i went into the demo in IE 8 and it wasn’t working.
could you email me the fix?
Wow, I didn’t expect a solution so quick. You the man! Thanks a lot!
Also, I wanted to mention a Selectivizr http://selectivizr.com/ which got this sweet accordion working under pure css in ie. The jQuery backup is always nice to have. Thanks again!
hey, any way to add an html5 tag inside the accordian?
I can’t seem to get it to work with the jQuery version
Eric, the accordion already has an HTML5 element inside of it: the
sectionelement.Anyway, you can edit the HTML as you wish, as long you also update the CSS.
I’m pretty new to this HTML5 business. Does that mean I can’t have an Audio tag inside a section tag. (this is the first I’ve heard of a section tag)
Can you suggest any reading material so I can brush up on this stuff?
I think this can help you. ;)
I appreciate it.
So is there any way to include audio inside this accordion?
It worked on another one I found, but I like the look of this one better.
Eric, it will work. Just add your audio within the div that wraps the content for each section.
I just read over all my comments and realized I’m not making any sense. Here’s a link to what I’m currently working on.
http://erichuecker.com/bcc/listen
I want to get the audio inside the accordion, but for some reason they won’t show up.
I ended up using an iframe. Not ideal, but it’ll work until I can figure something else out
Eric
There is a doctype missing, that’s why you maybe have problems to get your audio working in the div.
Just add the html5 doctype and it should work.
Hi there.
Here is a “ported” version.
valid XHTML 1.0 Strict
http://w3cvalidco.de/accordion/index.html
Thank you, you are awesome.
Quick question. Do you have a solution to add a click option to close an open accordion window? I working on a page now and each of the options have a fair amount of content to them and when they expand they open out over the footer of the page so if you want to get to any of the links there you have to go to another page and to get away from the open accordion window so you can see the footer links.
Thanks
David, with the above jQuery code you could create a reset function which will hide all the visible content. Then, you will call it when clicking an option.
Hope that helps.
I’d like to see a solution that handles variable-height content sections without forcing overflow to scroll.
You can check the jQuery solution for that.
Can I Have the Download of the above…
also any demo related to webview
Saumik, you can view the demo source and copy it. That’s all! ;)
ok no problem
This is great! Thank you for sharing.
Dave
Dave, I’m glad you like it. Thanks for your comment.
Hi,
after open once, how can you close completly the accordeon ?
I mean, you click on and if your click again it close it self.
Does it possible with your nice solution ?
Thanks mate :-)
Hey John, to do that, use the following jQuery code:
$(document).ready(function(){ $('.accordion h2').click(function(){ $('.accordion h2').not(this).removeClass('active').next().slideUp(); $(this).toggleClass('active').next().slideToggle(); }); });It’s tested, so this is the solution. Hope this helps you!
This is great! I am currently using the pure html5 + css3 version, I have run into an issue where I have two div’s inside one section to have two columns. Left columns are labels and the right column is the data from the db.
in my second I have run into the problem where the section will open and close the above section but the current section stays open and the left column does not shoe the data.
Jason, try to use something like this:
<div class="accordion"> <section id="one"> <h2><a href="#one">Heading 1</a></h2> <div> <div class="column1">content</div> <div class="column2">content</div> </div> </section> </div>I think this should solve your problem. Good luck!
Were you able to see my code? I essentially have that I just have a inside each which holds the content .
And how do you post the code like you have?
So it seems to me that this is more of a CSS issue, and I’m still not sure of how to fix this problem. I had my HTML set up like you suggested prior. The issue is that the bottom accordion is not showing the text or values in the accordion, it isn’t even opening.
As I inspect the the HTML with firebug, I find there is a hidden div that has the information in it?
So there is the H2 tag then there is a div which appears to be the div that is surrounding the two other divs holding the columns. This outer div has the info like I stated before but when you select that outer div it shows where the overflow would be or where the info would show if the accordion opened.
Hope this makes sense. I guess my questions is, does this CSS select the first section or element, that it would prevent the second accordion from opening. On another note the second accordion does close the first one when you click the accordion header.
Thank you for your time and help…
Update: Got it :)
I have my accordions in one containing div for each accordion, the css gets the first immediate child so it would only show the first accordion. If you put each accordion in it’s own div and give it the same class=”name” then it will be perfect. hope this helps anyone else out there..
New to this…great work:) question for you though. I see John had asked how to have get the accordion to close when you click on it and you provided jQuery code to do that…..
I hate to ask this newbie question, but where do you put that code?
Thanks in advance
Tanya, copy&paste the above jQuery accordion solution. Then, while editing it, replace the existing jQuery code with the one I wrote to John.
Good luck!
Hey there, awesome code. Will definitely be using this as a reference. I was wondering if it was possible to use the jquery accordion and use this css3 version as a fallback? If so, what methods would I be looking at using?
Also, I’m assuming yes, but is there a way to get the css3 version to have a ‘slideback’ function. That is, post-expansion of the content, re-clicking the link would close the content.
Thank you! Hope to hear from you soon.
JJ, I’m afraid using the jQuery accordion with CSS3 only accordion fallback is not an option.
For production purposes, I’d recommend you to use the jQuery version.
Hi Red,
Great tutorial- I’ve had a play with it and learned something new about CSS3! Thanks!
I’ve decided to use the jQuery version of the accordion for the site I’m building as it has to be cross-browser compatible. I’m wondering if there’s any way to default to the first being open, rather than all the text being hidden.
Thanks,
Martin.
Just to clarify, I just need the default class of the first h2 to be .active
I’ve tried adding it manually but it looks like it has to be generated by the jQuery. My jQuery skills are pretty minimal, I’m afraid…
Thanks for your help : )
Hi Martin, check this out: http://jsfiddle.net/catalinred/mkt5p/
Wow- thanks Red! Works a charm!
Keep up the good work!
You’re welcome! ;)
hello red
great accordion really helped but i didnt understand how to make it IE8 compatible.
i went into the Jquery demo but there is no info about how to do it
any help, thank you
Hi there, indeed, there is no tutorial for the jQuery accordion version. But you can check the source for the demo page in order to understand it. ;)
I think it’s quite self explanatory. Good luck!
thank you very much :P
this might be a noob question but do u know of a way for the accordion div not to inherit any of the other css in the page?
Hey all,
I have a question, I have used the pure CSS method and I have an issue. When you click on the first item to have it “slide down” it hops down to that position, then when you click the 2nd it “slides up” but it slides past your point of view and you have to scroll up to see it. Any suggestions?
Hi Red,
I didn’t understand how you inserted that little icon on the right side of the header. Can you explain it?
Hi Rafael,
the right triangle is made using the after pseudo-element.
Here’s a similar example that might help you understanding it: http://www.red-team-design.com/css3-dropdown-menu.
Hope that helps!
Great tutorial Red, however I think that the pure css design can be a little improved with some images. I have searched a bit, and found this nifty little accordion skin, that works great with the accordion you designed, especially since it offers a lot more design elements for the content section of the accordion. The file is PSD and layered, and you can get it from here, http://www.creattor.com/web-elements/sleek-accordion-3997.
Thanks for the tutorial and keep them coming.
Red,
Again, thanks for all the great tutorials! You are a life saver for many of us beginners to intermediates. I had a question about this for one of my clients. I added the If and endif statements for the jquery for this to work in IE9 and it does work perfectly. My question is when I change back to IE8 or IE7 the drop down according does not work. The rest of my page will show up in IE8&7 with the exception of the login which I am also working on. Any direction you could put me in would be a great help.
Thanks so much!
Tusk
Tusk, perhaps a link might help. Or you may contact me and send me more details.
hi there
i’d like to use this as a menu for my website.
is it somehow possible to change the colour of the heading that is actually open?
look at http://tonecraft.ch/menu.html
the idea is to make the topmenu (home,about,etc.) red when clicked.
if i click a submenu-link, it has to change color into red and by clicking it another will appear.
any idea?
thanks ,t
Try
.accordion *:target h2 a {color: red;}.hmm. seems not to work… another idea?
It works: http://jsfiddle.net/catalinred/tAZFf/1/
Hi Red,
Is there a way when:
You click on an according tab – in this example “heading1″ – and it opens up the holder for the text, links, etc you want to add, but when you make the heading1 an actual link itself you have to click twice for the according to open up. So, my question is this – Is there a way you can make the according open up when you click on heading1 but also it will take you to another page – almost like the according is embedded but the content of the page will change. Not sure if this is possible without clicking twice.
hello Red-Team !
Great work, just one question, can I use jquery version to display vertical menu for my website? I did some testing but I found such a problem. If you click let’s say on Heading 5 the website is scrolling down the way that Heading 5 goes to the top edge of browser and my menu section exists around the middle part of page so after clicking #header of my page goes up and is hidden. Is there any solution for it?
Nice article. but i have a problem.
when your page is to long the anchor jumps to the element.
any solution to prevent this?