Depth and Perspective Themed jQuery Accordion

Alt Text

Introduction

I was working on a perspective styled wordpress theme, and I created this accordion for the sidebar. The wordpress theme is not ready at this time, but I really liked how the accordion turned out. So I am releasing this accordion on its own as a cool freebie.

This is my first tutorial/freebie that I am releasing so feedback is definitely wanted. I tried to use as much CSS3 as possible to remove dependency on images, but I ended up using two images for trapezoid gradients that I couldn’t make with CSS3.

This perspective styled accordion is based on the custom jQuery accordion made by Nettuts. I customized the script to give the accordion a 3D depth and a custom animation for the depth.

HTML

Here is the basic HTML for the accordion. It is mostly unchanged from the nettuts version except for 2 divs creating the top and bottom images creating the depth for the accordion.

<ul id="accordion">
			<div class="topAccord">
			</div>
			<li<?php if($section == '' || $section == 'recent'): ?> class="current"<?php endif; ?>>
					
				<a href="?section=recent" class="first heading">Recent Entries</a>
				<div class="wrap">
					<ul id="recent">
						<div class="wrapper">
						<li><span class="date">01.19.2009</span> <a href="#">Recent Entry Title</a></li>
						<li><span class="date">01.15.2009</span> <a href="#">Recent Entry Title</a></li>
						<li><span class="date">01.13.2009</span> <a href="#">Recent Entry Title</a></li>
						<li><span class="date">01.11.2009</span> <a href="#">Recent Entry Title</a></li>
						<li><span class="date">01.10.2009</span> <a href="#">Recent Entry Title</a></li>
						</div>

					</ul>
					<div class="botAccord">
					</div>
				
				</div>
			</li>
			<li<?php if($section == 'popular'): ?> class="current"<?php endif; ?>>
				<a href="?section=popular" class="heading">Popular Entries</a>
				<div class="wrap">
				<ul id="popular">
					<div class="wrapper">
					<li><span class="date">08.16.2008</span> <a href="#">Popular Entry Title</a></li>
					<li><span class="date">06.12.2008</span> <a href="#">Popular Entry Title</a></li>
					<li><span class="date">04.12.2008</span> <a href="#">Popular Entry Title</a></li>
					<li><span class="date">06.12.2007</span> <a href="#">Popular Entry Title</a></li>
					<li><span class="date">03.12.2007</span> <a href="#">Popular Entry Title</a></li>
					</div>
				</ul>
				<div class="botAccord">
				</div>
				
				</div>
			</li>
			<li<?php if($section == 'categories'): ?> class="current"<?php endif; ?>>
				<a href="?section=categories" class="heading">Categories</a>
				<div class="wrap">
				<ul id="categories">
					<div class="wrapper">
					<li><a href="#">Category Name</a> <span class="count">23</span></li>
					<li><a href="#">Category Name</a> <span class="count">4</span></li>
					<li><a href="#">Category Name</a> <span class="count">15</span></li>
					<li><a href="#">Category Name</a> <span class="count">29</span></li>
					<li><a href="#">Category Name</a> <span class="count">8</span></li>
					</div>
				</ul>
				<div class="botAccord">
				</div>
				
				</div>
			</li>
			<li<?php if($section == 'archive'): ?> class="current"<?php endif; ?>>
				<a href="?section=archive" class="heading">Archive</a>
				<div class="wrap">
				<ul id="archive">
					<div class="wrapper">
					<li><a href="#">January 2009</a> <span class="count">4</span></li>
					<li><a href="#">December 2008</a> <span class="count">14</span></li>
					<li><a href="#">November 2008</a> <span class="count">12</span></li>
					<li><a href="#">October 2008</a> <span class="count">8</span></li>
					<li><a href="#">September 2008</a> <span class="count">18</span></li>
					</div>
				</ul>
				<div class="botAccord">
				</div>
				
				</div>
			</li>
			<div class="AllAccordBot">
				
			</div>
		</ul>

CSS

Here is the CSS. It is based on the CSS of the nettuts accordion.

/*****Accordion Styles*****/
ul#accordion, ul#accordion ul { list-style: none; margin: 0; }
ul#accordion { position: relative; top:0px; }
ul#accordion li {  overflow: hidden;  }
ul#accordion li ul { display: none; }
ul#accordion li.current ul { display: block; }

ul#accordion li ul .wrapper{ /*Accordion individual content*/
	width: 220px;
	margin-left: 40px;
	background-color: #444; 
   background-image: -moz-linear-gradient(#555, #888);
   background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#bbb), to(#999));
   background-image: -webkit-linear-gradient(#555, #888); 
   background-image: -o-linear-gradient(#bbb, #999);
}

ul#accordion li .wrap{ /*Only needed to achieve the negative margin-top animation*/
	position: relative;
	overflow: hidden;
	margin-top:-50px;
	z-index: -100;
}
ul#accordion li.current .wrap{
	margin-top:0px;
	z-index: 100;
}

ul#accordion ul li { 
	border: none; color: #999; padding: 5px 10px; 
	}

ul#accordion .topAccord{ /*Only used at the top to create depth*/
	background: url(../images/AccordTop.png) no-repeat; 
	height: 50px;
}
ul#accordion .botAccord{ /*Used in every individual content to create depth*/
	position: relative;
	background: url(../images/AccordShadow.png) no-repeat; 
	height: 50px;
}

ul#accordion a.heading { /*This styles the button for each individual content*/
	position: relative;
	color: #777;
	display: block;
	font-size: 18px;
	line-height: 18px;
	padding: 10px 5px;
	text-decoration: none;
   background-color: #a1a1a1; 
   background-image: -moz-linear-gradient(#bbb, #999);
   background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#bbb), to(#999));
   background-image: -webkit-linear-gradient(#bbb, #999); 
   background-image: -o-linear-gradient(#bbb, #999);
	text-shadow: 1px 1px 1px #bcbcbc;
	height: 20px;
	z-index: 1000;
}
ul#accordion a.heading:hover { background: #88D7E3; color: #fff; text-shadow: 1px 1px 1px #444; }


ul#accordion .AllAccordBot { /*The footer of the accordion. Not a button*/
   background-color: #a1a1a1; 
   background-image: -moz-linear-gradient(#bbb, #999);
   background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#bbb), to(#999));
   background-image: -webkit-linear-gradient(#aaa, #999); 
   background-image: -o-linear-gradient(#bbb, #999);
	height: 40px;
}
ul#accordion li ul{
	position: relative;
	top:0px;
}


/*Link Style*/
ul#accordion li ul a { font-size: 15px;color: #4998DE; text-decoration: none; border-bottom: 1px solid #aaa; text-shadow: 1px 1px 1px #444; }
ul#accordion li ul a:hover { border-bottom: 1px solid #6199C9; color: #aaa; background-color: #555;}
ul#accordion li ul .date { padding-right: 10px; }
ul#accordion li ul .count { padding-left: 10px; }

I commented most of the parts that can be customized to your liking.

jQuery

Here is the entire javascript file for the accordion.

$(document).ready(function() {
	$('ul#accordion a.heading').click(function() {
		if($(this).parent().hasClass('current')) {
			$(this).siblings('.wrap').children('ul').slideUp(500,function() {
				$(this).parent('.wrap').animate({marginTop: '-50px'});
				$(this).parent().parent().removeClass('current');
			});
			
		} else {
			$('ul#accordion li.current').children('.wrap').children('ul').slideUp(500,function() {
				$(this).parent('.wrap').animate({marginTop: '-50px'});
				$(this).parent().parent().removeClass('current');
			});

			$(this).siblings('.wrap').animate({marginTop: '0px'}, function() {
				$(this).children('ul').slideDown(500);
				$(this).parent().addClass('current');
			});

		}
		return false;
	});
});

When one of the headings are clicked, it checks if it has the class current, or not, meaning if it is open at the time. If it is open, then it uses the SlideUp method to hide the contents of the accordion. I couldn’t use a SlideUp method to hide the entire contents of the accordion because the image for the bottom of the accordion (the image that gives the perspective) looked unrealistic when using SlideUp. Instead I used a callback to animate the bottom image alone using a negative margin-top to make it look like it was sliding shut.

The second part is when the heading clicked is a hidden part of the accordion. It closes the open part of the accordion using the same SlideUp and Animate. The closed part then does the opposite of the open part by first animating the margin-top to reveal the image, and then through a callback using SlideDown to reveal the content of the accordion.

Conclusion

Thats it. Again I would like to mention Nettuts which provided the basis of the accordion. Here are the Demo and Download Links if you missed them at the top. Once again, feedback is welcome as this is my first tutorial/freebie.