Horizontal Accordion Slider with Vertical Text

In this tutorial, we’re going to take a look at how to build a horizontal accordion slider using CSS 2D transforms and a bit of jQuery.

Typically, the trickiest part about this kind of horizontal accordion is getting the text on the accordion “spines” to display vertically, so people usually use images to display the text. It’s not simple, but using some CSS 2D transforms, we can actually make the text display vertically without using images.

2D transforms work in most modern browsers, but for those that don’t, we’re going to have our accordion degrade gracefully, without resorting to images.
Caveat: This isn’t a WordPress tutorial… yet. Wait for it, one step at a time!

Step 1: Photoshop

So let’s take a look at our design. It’s not going to win any awards, but it’s clean and straight forward. There are a few challenges related to there being borders between each spine, but we’ll address those with the CSS. For now, let’s just slice out the images.

Shark-week inspired

Slicing The Image

When we slice out the spines, we’re going to take the borders on each side. The easiest way to do this is to just slice out one of the spines, and then save it for the web 4 times, changing the number each time.

You only have to make one slice, then re-save it 4 times.

If you’re following along with my PSD, the images are pre-sliced. We’ll also need the background and the main images.

A CSS sprite would be more efficient, but I’m trying to keep things simple.

While we’re going through the HTML and CSS, I’m actually not going to use the images at first, I’m just going to use regular CSS backgrounds, to keep things simple.

Step 2: HTML

The markup for our accordion is pretty simple. The whole thing is one unordered list, where each list item is a slide. Inside each list item, we have an anchor tag, which will be the trigger for the slide, and the slide content. Give the first slide a class of “active” so that we can style it differently if we like.

Step 3: CSS

First, we’re just going to do a basic reset and get some of the structure set. The only really important thing here is the width of the list items: it should be the width of a slide, including the trigger, but not including the leftmost border.

The slide content width is just the width of the content images. The 50px margin refers to the width of each trigger.

Right now we just have a semi-styled list of images with room for our trigger spines.

It doesn't look like much yet

Next we need to get all those slides to pile on top of eachother, instead of coming one after the other. To do this, we’re going to use some clever absolute positioning and z-index values. Well, not that clever. But handy. The left values for each slide are just multiples of the 50px triggers.

Okay, so after we set the display to block (because anchors are inline), we’re rotating the text around 270 degrees (3/4 of a rotation). Because we’ve rotated the element, height is now width and width is now height, so we set the height to 50 and the width to 300. Similarly, the padding-top actually refers to padding to the left padding on the text.

All our slides in a row

I’m going to admit, I’m not really sure how the transform-origin property works, all I know is that I tried adding it on a whim, it turned out to be the secret ingredient that makes this all work. I messed around with the values for a while until I found one that worked.

If you’re using different sized elements than me, you’re going to have to adjust both the -transform-origin values and the top value. I suggest using [Firebug for Firefox] or just the webkit Inspector to view your changes real-time in the browser.

Anyways, so now we’ve got what’s starting to look like an accordion slider. Time to animate this puppy!

Step 4: jQuery

Now, I can’t take credit for the javascript in this tutorial, I found it and modified it from [this website] ages ago when I was building an old version of my portfolio.

And there we have it, a fully functional horizontal accordion with vertical text, sans images. Stay tuned for part 2, where I discuss cross-browser application (this only works properly in Firefox, Chrome & Safari) and graceful degradation, and part 3: WordPress!

Edit: I still haven’t been able to get my Windows virtual machine up and running since my hard drive crash, so perhaps I’ll do the WordPress first. Or you’ll just have to wait… I can’t find my Windows install disks