Pure CSS3 accordion

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.


View demo

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>

John Resig HTML5 Shiv

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 accordion div wraps the sections that compose the proper accordion.
  • Each section panel 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

View demo

Browser support

The demo works in browsers that sup­port the :tar­get 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!

View Jquery demo

67 thoughts on “Pure CSS3 accordion

  1. 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!

  2. 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.

  3. 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 “.

  4. 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).

  5. How can I add jquery fallback to these beautiful animations? I have to support IE8. Thanks so much for this inspiring piece of code.

  6. 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 section element.

      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?

  7. 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.

  8. 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!

  9. 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.

  10. 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.

  11. 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?

  12. 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?

  13. Hi Red,

    I didn’t understand how you inserted that little icon on the right side of the header. Can you explain it?

  14. 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.

  15. 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

  16. 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

  17. 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.

  18. 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?

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>