Elegant Accordion with jQuery and CSS3

Today we will create an elegant accordion for content. The idea is to have some vertical accordion tabs that slide out when hovering. We will add some CSS3 properties to […]

Today we will create an elegant accordion for content. The idea is to have some vertical accordion tabs that slide out when hovering. We will add some CSS3 properties to enhance the looks.
Ok, let’s start with the markup.

The Markup

The HTML will consist of a list where each accordion tab is a list element. Inside of the list element we will have a heading that disappears when we hover. Also, there will an element for the white background gradient and a div for the description. Here is the markup with just one list element:

<ul class="accordion" id="accordion">
	<li class="bg1">
		<div class="heading">Heading</div>
		<div class="bgDescription"></div>
		<div class="description">
			<h2>Heading</h2>
			<p>Some descriptive text</p>
			<a href="#">more ?</a>
		</div>
	</li>
</ul>

The other list elements will have the classes bg2, bg3 and bg4. The unordered list gets a class and an id since we want to address it later in the JavaScript. Of course, we would not really need the class but instead,  style the element using #accordion in our style sheet. But this is a good way to keep things separate.

The CSS

The style for the list will look as follows:

ul.accordion{
    list-style:none;
    position:absolute;
    right:80px;
    top:0px;
    font-family: Cambria, serif;
    font-size: 16px;
    font-style: italic;
    line-height: 1.5em;
}

The list elements will each have a different background image, so we will first define the general style properties for every list element and then the single classes with the background images:

ul.accordion li{
    float:right;
    width:115px;
    height:480px;
    display:block;
    border-right:2px solid #fff;
    border-bottom:2px solid #fff;
    background-color:#fff;
    background-repeat:no-repeat;
    background-position:center center;
    position:relative;
    overflow:hidden;
    cursor:pointer;
    -moz-box-shadow:1px 3px 15px #555;
    -webkit-box-shadow:1px 3px 15px #555;
    box-shadow:1px 3px 15px #555;
}
ul.accordion li.bg1{
    background-image:url(../images/1.jpg);
}
ul.accordion li.bg2{
    background-image:url(../images/2.jpg);
}
ul.accordion li.bg3{
    background-image:url(../images/3.jpg);
}
ul.accordion li.bg4{
    background-image:url(../images/4.jpg);
}

Note, that the box shadow will not work in IE.
The initial width of each item will be 115 pixels. We will alter this in the JavaScript hover function (to 480px).
The border that we give each list element can only be applied to one side, otherwise we would have a double border in between the items and just a single one at the outer limits. So, we need to define a class for a left border, that we will apply to the last list element (they are floating right, so the order is reversed):

ul.accordion li.bleft{
    border-left:2px solid #fff;
}

Now, we want a nice looking header with a white semi-transparent background for each list item when in the normal “closed” state:

ul.accordion li .heading{
    background-color:#fff;
    padding:10px;
    margin-top:60px;
    opacity:0.9;
    text-transform:uppercase;
    font-style:normal;
    font-weight:bold;
    letter-spacing:1px;
    font-size:14px;
    color:#444;
    text-align:center;
    text-shadow:-1px -1px 1px #ccc;
}

The div that contains the description will have the following style:

ul.accordion li .description{
    position:absolute;
    width:480px;
    height:175px;
    bottom:0px;
    left:0px;
    display:none;
}

We set it to display:none initially, since we only want it to appear when hovering. And here is, how we style the inner elements:

ul.accordion li .description h2{
    text-transform:uppercase;
    font-style:normal;
    font-weight:bold;
    letter-spacing:1px;
    font-size:45px;
    color:#444;
    text-align:left;
    margin:0px 0px 15px 20px;
    text-shadow:-1px -1px 1px #ccc;
}
ul.accordion li .description p{
    line-height:14px;
    margin:10px 22px;
    font-family: "Trebuchet MS", sans-serif;
    font-size: 12px;
    font-style: italic;
    font-weight: normal;
    text-transform: none;
    letter-spacing: normal;
    line-height: 1.6em;
}
ul.accordion li .description a{
    position:absolute;
    bottom:5px;
    left:20px;
    text-transform:uppercase;
    font-style:normal;
    font-size:11px;
    text-decoration:none;
    color:#888;
}
ul.accordion li .description a:hover{
    color:#333;
    text-decoration:underline;
}

The only style missing is the one for the gradient element:

ul.accordion li .bgDescription{
    background:transparent url(../images/bgDescription.png) repeat-x top left;
    height:340px;
    position:absolute;
    bottom:0px;
    left:0px;
    width:100%;
    display:none;
}

The image that we are repeating is a gradient that goes from white to transparent. This will give a nice effect when we make this div slide in from the bottom.

Let’s add some magic!

The JavaScript

First, we include the jQuery library before the body end tag:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

Now, we will add a function that makes a list element slide out when hovering over it. This will be achieved by animating the increase of the width to 480 pixels. Then the top heading should fade out while the gradient (css class “bgDescription”) and the description appear:

<script type="text/javascript">
$(function() {
    $('#accordion > li').hover(
        function () {
            var $this = $(this);
            $this.stop().animate({'width':'480px'},500);
            $('.heading',$this).stop(true,true).fadeOut();
            $('.bgDescription',$this).stop(true,true).slideDown(500);
            $('.description',$this).stop(true,true).fadeIn();
        },
        function () {
            var $this = $(this);
            $this.stop().animate({'width':'115px'},1000);
            $('.heading',$this).stop(true,true).fadeIn();
            $('.description',$this).stop(true,true).fadeOut(500);
            $('.bgDescription',$this).stop(true,true).slideUp(700);
        }
    );
});
</script>

The first function inside of $(‘#accordion > li’).hover is the function triggered when the mouse moves over the respective element and the second function gets triggered when moving the mouse out again. Here we reverse the actions and also add some timing to it, so that the elements disappear smoothly.

And that’s all! I hope you enjoyed this tutorial and find it useful!

Message from TestkingWe offer online oracle training program to help you pass pmi certifications on time. Learn about jquery and css3 using security+ tutorial and other resources.

Tagged with:

Manoela Ilic

Manoela is the main tinkerer at Codrops. With a background in coding and passion for all things design, she creates web experiments and keeps frontend professionals informed about the latest trends.

Stay up to date with the latest web design and development news and relevant updates from Codrops.

Feedback 74

Comments are closed.
  1. Hi Mary,

    I really like your accordion but before I start adjusting it I would like to ask about the legal aspects: Is it OK to use it on our company’s homepage?

  2. Hi Mary Lou,
    i love your tut’s.

    Why you do using position:absolute?
    I played a bit around and got no reason to position div’s absolut.
    Is there any reason i don’t know yet?

    Thanks in advance.

  3. I’m Trying to make every “li” stay open until I hover an other .

    I try with .parent()

    but I’m not really expert in jQuery … For Now I’m trying this:

    http://jsfiddle.net/ZnVhT/

    I will be greatly appreciated if any of you can tell me how i suppose to make this possible.

    Thanks

  4. Hi,
    I am using this accordion in my nav menu. I have 5 icons and when you hover over with the mouse they expand into icons+text. It looks very good but it doesn’t work on pages with forms. Any idea why?

  5. Nevermind. I had some closing tags html errors on those pages. It works now and it is great. Thanks

  6. Hi Mary Lou (or anyone else who has figured this out!) – Is it possible to have one slide open at all times? I have tried for hours to figure this out!!!

  7. this is stunning… Can I make use of it please… perhaps with little modification..

  8. (continuation of last post)
    Actually thinking of creating a website for a biz venture I had planned out with the scripts!!!!

  9. Hi Mary Lou, Great work!

    But how if i want the accordion to slide automatically? Any idea? Thanks.

  10. Hey… This is really a great design !! Thanks a lot !!

    I just have one recommendation with the css-file: ul.accordion li.heading {padding: 10px} could be better padding: 10px 0: otherwise you have a small space problem with larger headers…

    but this just as a very small note to a great work…!!

  11. Hi, Mary Lou

    I am a novice in CSS3 and Jquery but I really do like your design and I would like to use it, but it seems to be that in Dreamweaver CS3 (the program I use for designing a website) testing your code on the local server (XAMPP) ends up in a page in Firefox with the message “IT WORKS”. However, when I in Firefox or IE just open index.html, I can see the page and the accordion working properly! Is this caused by Dreamweaver or is there another explanation for this behavior?

  12. I can add to my previous comment that transferring the files to my server, using the ftp-client in Dreamweaver, does not present any problem. The accordion works fine. But then why not on the local server, ie. my PC?

  13. thanks for the great example. I’ve been having 2 problems with it.
    1 – When the area that the accordion expands out to and covers up contains a link, i cannot click it even when it’s not covered up (works in IE though…)
    2 – in IE, when the accordion closes it leaves vertical lines in the space it had expanded to, speeding up the animation gives me fewer lines, but I still get some.

  14. Hi Mary Lou, Great work!

    But how if i want the accordion to slide automatically? Any idea? Thanks.