Advanced CSS Accordion Effect

Published December 17, 2008 by saurav.roy.

css accordion technique

A while back, I wrote an article demonstrating how the popular “accordion” effect (as in the image above) could be replicated with nothing more than CSS. There was one caveat, however: the technique didn’t work in Internet Explorer 6 due to the browser’s extremely limited support of the :hover pseudo-element.

Now, IE6’s market share is decreasing day by day – and we’re all undoubtedly thankful. But the browser will continue to maintain a healthy market share for quite some time to come. To that end, I’d like to revisit the CSS accordion technique and make a modification or two that will let it work with IE6.

I’m going to admit up front: these modifications require JavaScript. So what’s the point of having a “CSS” accordion technique that uses JavaScript? Well, all those other accordion techniques out there require JavaScript, and almost all require an entire JavaScript framework. This technique is merely improved by JavaScript – all modern browsers will handle this technique just fine even without JS enabled.

The Original Markup

We’re going to have to make a couple of teensy modifications to the CSS later on, but I wanted to show the original markup for consistency’s sake. Here’s the XHTML we originally used:

<div id="accordion">
	<div id="part1">
		<p>This text is in part 1.</p>
	</div>
	<div id="part2">
		<p>This text is in part 2.</p>
	</div>
	<div id="part3">
		<p>This text is in part 3.</p>
	</div>
	<div id="part4">
		<p>This text is in part 4.</p>
	</div>
</div>

And here is the CSS:

#accordion {
	width: 500px;
	margin: 100px auto; }
#accordion div {
	float: left;
	width:25%;
	height: 300px;
	overflow: hidden;}
#accordion:hover div {
	width: 20px; }
#accordion:hover div:hover {
	width: 440px;
	overflow: auto; }

If you’d like to better understand how all of this works, please refer to the original article.

Better Living Through JavaScript

The idea on how to improve this script came to me one day while I was going through the CSS Newbie archives (yes, I have to refer to my own archives to remember how to do things some days!). I was rereading my article on Easy CSS Dropdown Menus and I realized that the same JavaScript that allows my dropdown menus to be hover-able (that is, the Suckerfish technique) would work just as well on my CSS accordion. Here’s that code modified to effect the accordion:

accHover = function() {
	var accContainer = document.getElementById("accordion");
	accContainer.onmouseover=function() {
		this.className+=" hover";
	}
	accContainer.onmouseout=function() {
		this.className=this.className.replace(new RegExp(" hover\b"), "");
	}
	
	var accDivs = accContainer.getElementsByTagName("div");
	for (var i=0; i<accDivs.length; i++) {
		accDivs[i].onmouseover=function() {
			this.className+=" hover";
		}
		accDivs[i].onmouseout=function() {
			this.className=this.className.replace(new RegExp(" hover\b"), "");
		}
	}	
}
if (window.attachEvent) window.attachEvent("onload", accHover);

Basically, this code loops through all the divs within the accordion, as well as the containing accordion div itself, and applies a mouseover and mouseout function to each. Then when the user mouses over the div, it gains a class of “hover”. When the user moves the mouse away from the div, the hover class is removed.

Now all we need to do is edit our CSS to look for either the hover pseudo-class or our new hover class, which is made easy with sequential selectors:

#accordion {
	width: 500px;
	margin: 100px auto; }
#accordion div {
	float: left;
	width:25%;
	height: 300px;
	overflow: hidden;}
#accordion:hover div, #accordion.hover div {
	width: 20px; }
#accordion:hover div:hover, #accordion.hover div.hover {
	width: 440px;
	overflow: auto; }

Even Easier with jQuery

Those of you who have been reading for a while know that I’m a big fan of the jQuery JavaScript framework. Thus, when I started to rewrite this script to work for our accordion, I decided to rewrite it in jQuery as well. For those of you who aren’t currently using jQuery, this script might be a bit overkill, as it’d require your users to download a lot more code in the long run (our tiny script plus the jQuery framework). But if you’re already using jQuery, this cuts our heavy lifting down by quite a bit:

$(document).ready(function() {
	$("#accordion, #accordion div").mouseover(function() {
		$(this).addClass("hover");
	}).mouseout(function() {
		$(this).removeClass("hover");
	});
});

This script does the same thing as our longer JavaScript above, but with far less code.

So that’s all there is to it! You can see a demo of this in action here. The accordion should function just fine in all major browsers with our without JavaScript enabled, and will function in IE6 with JavaScript. Enjoy!