Accordion Menu with jQuery Collapser and CSS3

Thu, 08/23/2012 - 12:15 -- Arisen

I recently tried to make a accordion menu system using various different jQuery libraries but they all seem to be flawed in one way or another so I took some pieces from each and combined them with jQuery Collapser plugin. I had a big problem trying to get the current url because of ajax requests and redirects so I stumbled upon a great jQuery function call .data. I'll go over everything below and how I tied it altogether. Demo can be found here

First we load up the libraries.




Next we use the collapser function to create the accordion menu display.

jQuery(document).ready( function ($) {
	
	$('.demo').collapser({
		target: 'siblings',
		targetOnly: 'ul',
		changeText: 0,
		effect: 'slide',
		expandClass: 'expArrow',
		collapseClass: 'collArrow'
	});
});

We now create the rough outline for our html menu. I added the links above the <ul> elements so I could put headers of images and have the text stay there when collapsing. You'll noticed in the javascript I called target: 'siblings' and targetOnly: 'ul'

Make a list collapser (Demo)

Collapse List

This is where it got a bit tricky for me since I need to somehow store the link address that the user was clicking on in order to highlight and expand the menu to the proper location when it was view on the next page. Turns out jQuery .data does the trick just fine.

	
jQuery(document).ready( function ($) {

    $('.collapser').collapser({
        target: 'siblings',
        targetOnly: 'ul',
        changeText: 0,
        effect: 'slide',
        expandClass: 'expArrow',
        collapseClass: 'collArrow'
    });

    var current = $.data(document.body, 'current-url');
    
    if(current === undefined) {
        current = window.location.pathname;
    }

    if(current !== undefined) { 
        var pathname = current.split('?');
        var base = pathname[0];
        base = base.split('/');
        var tester = base[base.length-1];

        $('.custom-navigation a').each(function(){
            var test = $(this).attr('href').split('/');
            test = test[test.length-1];
            if (test == tester){
                $(this).parents('ul').prev('a').removeClass('expArrow').addClass('collArrow');
                $(this).parent('li').addClass('active');
                $(this).parents('ul').css('display', 'block');
                
            }
        });
    }
    
    $('.custom-navigation a').click(function(){
        $.data(document.body, 'current-url', $(this).attr('href'));
    });
});

And now just some simple CSS3 styling to look nice you to look it if you've got a newer version browser.


.custom-navigation {
    float: left;
    margin-right: 30px;
    width: 300px;
}

.custom-navigation,
.custom-navigation a {
    display: block;
    color: white;
    text-shadow: 1px 1px 1px #1D6097;
    font-weight: bold;
    text-alin: left;
}
 
.custom-navigation ul {
    list-style-type: none;
}
 
.custom-navigation li {
    list-style: none;
    background: rgb(76,76,76); /* Old browsers */
    background: #4c4c4c; /* Old browsers */
    /* IE9 SVG, needs conditional override of 'filter' to 'none' */
    background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzRjNGM0YyIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEyJSIgc3RvcC1jb2xvcj0iIzU5NTk1OSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjI1JSIgc3RvcC1jb2xvcj0iIzY2NjY2NiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjM5JSIgc3RvcC1jb2xvcj0iIzQ3NDc0NyIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjUwJSIgc3RvcC1jb2xvcj0iIzJjMmMyYyIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjUxJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjYwJSIgc3RvcC1jb2xvcj0iIzExMTExMSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9Ijc2JSIgc3RvcC1jb2xvcj0iIzJiMmIyYiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjkxJSIgc3RvcC1jb2xvcj0iIzFjMWMxYyIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMxMzEzMTMiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
    background: -moz-linear-gradient(top,  #4c4c4c 0%, #595959 12%, #666666 25%, #474747 39%, #2c2c2c 50%, #000000 51%, #111111 60%, #2b2b2b 76%, #1c1c1c 91%, #131313 100%); /* FF3.6+ */
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#4c4c4c), color-stop(12%,#595959), color-stop(25%,#666666), color-stop(39%,#474747), color-stop(50%,#2c2c2c), color-stop(51%,#000000), color-stop(60%,#111111), color-stop(76%,#2b2b2b), color-stop(91%,#1c1c1c), color-stop(100%,#131313)); /* Chrome,Safari4+ */
    background: -webkit-linear-gradient(top,  #4c4c4c 0%,#595959 12%,#666666 25%,#474747 39%,#2c2c2c 50%,#000000 51%,#111111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%); /* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(top,  #4c4c4c 0%,#595959 12%,#666666 25%,#474747 39%,#2c2c2c 50%,#000000 51%,#111111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%); /* Opera 11.10+ */
    background: -ms-linear-gradient(top,  #4c4c4c 0%,#595959 12%,#666666 25%,#474747 39%,#2c2c2c 50%,#000000 51%,#111111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%); /* IE10+ */
    background: linear-gradient(to bottom,  #4c4c4c 0%,#595959 12%,#666666 25%,#474747 39%,#2c2c2c 50%,#000000 51%,#111111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%); /* W3C */
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4c4c4c', endColorstr='#131313',GradientType=0 ); /* IE6-8 */
    box-shadow: 1px 1px 3px 1px gray;
    padding: 6px;
    margin: 0px 4px 0px 0px;
}
 
.custom-navigation li.active,
.custom-navigation a:hover {
     
    background: #bfd255; /* Old browsers */
    background: -moz-linear-gradient(top,  #bfd255 0%, #8eb92a 50%, #72aa00 51%, #9ecb2d 100%); /* FF3.6+ */
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#bfd255), color-stop(50%,#8eb92a), color-stop(51%,#72aa00), color-stop(100%,#9ecb2d)); /* Chrome,Safari4+ */
    background: -webkit-linear-gradient(top,  #bfd255 0%,#8eb92a 50%,#72aa00 51%,#9ecb2d 100%); /* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(top,  #bfd255 0%,#8eb92a 50%,#72aa00 51%,#9ecb2d 100%); /* Opera 11.10+ */
    background: -ms-linear-gradient(top,  #bfd255 0%,#8eb92a 50%,#72aa00 51%,#9ecb2d 100%); /* IE10+ */
    background: linear-gradient(to bottom,  #bfd255 0%,#8eb92a 50%,#72aa00 51%,#9ecb2d 100%); /* W3C */
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#bfd255', endColorstr='#9ecb2d',GradientType=0 ); /* IE6-9 */
 
}
 
.custom-navigation .expArrow {
    padding-left: 30px;
    background: url('/sites/all/themes/arisen/images/arrow.png') no-repeat left center transparent;
}
.custom-navigation .collArrow {
    padding-left: 30px;
    background: url('/sites/all/themes/arisen/images/arrow-active.png') no-repeat left center transparent;
}
 
 
.custom-navigation ul {
    display: none;
}

See the whole thing working here