Just few days ago, I shared pure CSS3 vertical accordion that works in all modern browsers, including Internet Explorer. Now it is time to share its twin – a pure CSS3 horizontal accordion. It uses same markup enabling you to switch from vertical to horizontal accordion and vice versa by simply changing the class name.

We will continue to use “:hover” instead of “:target” pseudo class to cater Internet Explorer and other usability issues (You should read “Cross Browser Pure CSS3 Vertical Accordion” article to find out why we are not using “:target” pseudo class).
Lets Start
In order to support text based panel heads, we will need to rotate entire panel head to create horizontal accordion. Interestingly, we have the ability to rotate elements in Internet Explorer (using Microsoft’s BasicImage filter) for a while. Other browsers are only able to do this with CSS3 transform. Rest of the structure and behavior will be written in cross-browser CSS that will work in IE7+ and all other modern browsers.
You can add other CSS3 features like gradients, font-face, etc to enhance it further. Our accordion will degrade to an unordered list in IE6 (which will be completely untouched by our CSS). You can use conditional CSS to style unordered list for IE6 or older browsers however you like.
Accordion Markup
We are going to use exactly the same markup that we used to create vertical accordion:
<div class="horizontalaccordion">
<ul>
<li>
<h3>Heading 1</h3>
<div>Content For Panel 1.</div>
</li>
<li>
<h3>Heading 2</h3>
<div>Content For Panel 2</div>
</li>
<li>
<h3>Heading 3</h3>
<div>Content For Panel 3.</div>
</li>
<li>
<h3>Heading 4</h3>
<div>Content For Panel 4</div>
</li>
</ul>
</div>
Note:
* Each “li” element inside unordered list represents a panel
* Each “h3” element inside a list item represents panel head
* Each “div” element inside a list item represents panel content
Styling Accordion Structure
Unlike vertical accordion, our horizontal accordion depends on CSS3 (transform) to complete its structure. What this means is that it will work in Internet Explorer but not in older versions of other web browsers. Luckily older versions of Firefox, Safari, Chrome and Opera have negligible market share. CSS3 transform is supported in these browsers: Firefox 3.5+, Opera 10.5+, Safari 3+ and Chrome.
Following CSS will create a horizontal accordion with all its panels collapsed:
.horizontalaccordion>ul {
margin: 0;
padding: 0;
list-style:none;
height: 300px;
}
.horizontalaccordion>ul>li {
display:block;
overflow: hidden;
float:left;
margin: 0;
padding: 0;
list-style:none;
width:40px;
height: 300px;
/* Decorative CSS */
background:#f0f0f0;
}
.horizontalaccordion>ul>li>h3 {
display:block;
float:left;
margin: 0;
padding:10px;
height:19px;
width:280px;
/* Decorative CSS */
border-left:#f0f0f0 1px solid;
font-family: Arial, Helvetica, sans-serif;
text-decoration:none;
text-transform:uppercase;
color: #000;
background:#cccccc;
/* CSS3 Transform Rotate & Translate */
white-space:nowrap;
-moz-transform: rotate(90.0deg) translate(-40px,0px); /* FF3.5+ */
-moz-transform-origin: 0 100%;
-o-transform: rotate(90.0deg) translate(-40px,0px); /* Opera 10.5 */
-o-transform-origin: 0 100%;
-webkit-transform: rotate(90.0deg) translate(-40px,0px); /* Saf3.1+, Chrome */
-webkit-transform-origin: 0 100%;
transform: rotate(90.0deg) translate(-40px,0px); /* Saf3.1+, Chrome */
transform-origin: 0 100%;
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1.0); /* IE6,IE7 */
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1.0)"; /* IE8 */
}
.horizontalaccordion>ul>li>div {
display:none;
float:left;
overflow: auto;
position:relative;
top:-40px;
left:40px;
*top:0px; /* IE7 Hack */
*left:0px; /* IE7 Hack */
margin:0;
width:320px;
height:280px;
padding:10px;
}

Note:
- Child Combinators
I have purposely used child combinators to make sure that CSS applies only to the elements used in creating accordion structure and not inherited by elements that are used in accordion content. - Default State: Panels
Since we are not using “:target” pseudo class, we are not able to specify accordion’s state. That’s why we have to set all panels in collapsed state by default. This is done by setting width of “li” equal to the height (which becomes width after rotation) of “h3” elements (i.e., total width of each panel is equal to the width of its head). - Panel Head
This is the trickiest part of horizontal accordion. Note that height specified here will become width and width will become height after rotating the panel head. So the total height (which will become width after transform) of “h3” element is calculated by adding height, padding-top, padding-bottom and height of the border (if any). Transformation is done using CSS3 transform property and filter for Internet Explorer. In addition to rotating the h3 element, we are also adjusting its position using “translate” so that panel’s content area will adjust its position accordingly. - Panel Content
For panel content “div”, you may want to note that overflow is set to “auto”. This will add scrolling bar(s) if content doesn’t fit inside the content area. Total width (width + padding-left + padding-right) of the content area is determined by using this formula: accordion-width - (number-of-panels x width-of-panel-head). Also note that we have to keep content panel’s position relative to its head (i.e., “h3” element) and adjust the position here as well. Since Internet Explorer 7’s behavior during transformations is different from other browsers, I have used a little hack to accommodate its position.
Styling Accordion Behavior
Now we will add behavior in our accordion using “hover”. Adding following CSS will do the trick:
.horizontalaccordion>ul>li:hover {
overflow: hidden;
width: 380px;
}
.horizontalaccordion:hover>ul>li:hover>div {
display:block;
}
.horizontalaccordion:hover>ul>li:hover>h3 {
/* Decorative CSS */
color:#fff;
background:#000000;
}
.horizontalaccordion>ul>li>h3:hover {
cursor:pointer;
}

Note:
- Opening Panel With Hover
In order to add behavior to our accordion – all we need to do is increase width of the Panel (“li” element) when mouse is moved over it. Panel width is determined by using this formula: accordion-width – ((number-of-panels – 1) x width-of-panel-head). We also need to “display” content panel’s as “block” when mouse is moved its head. - Highlighting Current Panel Head
We have highlighted current or open panel by changing the background property of the “h3” element when mouse moves over “li”. It is important to do this on “li:hover” instead of “h3:hover”, because you want to highlight panel head even mouse is hovering over its content. - Changing Mouse Pointer
Since we are not using anchors, we have changed mouse pointer using CSS when mouse hovers over “h3” element.
Adding Transition Effect
By adding structure and behavior, we have successfully created pure CSS horizontal accordion. It looks and works perfectly in all modern browsers including IE7+. Now to add transition effect. apply following CSS3 style to our panels (i.e., “li” element):
transition: width 0.3s ease-in-out; -moz-transition: width 0.3s ease-in-out; -webkit-transition: width 0.3s ease-in-out; -o-transition: width 0.3s ease-in-out;
CSS3 transition effect is currently available in Safari, Chrome and Opera. It will soon be available on Firefox with version 3.7. IE7 and IE8 will continue to display CSS accordion without any transition effect.
Complete Code
That’s it – we are done. This is how complete CSS file will look like (note: I have also added gradient effect to our panel head):
.horizontalaccordion>ul {
margin: 0;
padding: 0;
list-style:none;
height: 300px;
}
.horizontalaccordion>ul>li {
display:block;
overflow: hidden;
float:left;
margin: 0;
padding: 0;
list-style:none;
width:40px;
height: 300px;
/* Decorative CSS */
background:#f0f0f0;
/* CSS3 Transitions */
transition: width 0.3s ease-in-out;
-moz-transition: width 0.3s ease-in-out;
-webkit-transition: width 0.3s ease-in-out;
-o-transition: width 0.3s ease-in-out;
}
.horizontalaccordion>ul>li>h3 {
display:block;
float:left;
margin: 0;
padding:10px;
height:19px;
width:280px;
/* Decorative CSS */
border-left:#f0f0f0 1px solid;
font-family: Arial, Helvetica, sans-serif;
text-decoration:none;
text-transform:uppercase;
color: #000;
background:#cccccc;
/* CSS3 Transform Rotate & Translate */
white-space:nowrap;
-moz-transform: rotate(90.0deg) translate(-40px,0px); /* FF3.5+ */
-moz-transform-origin: 0 100%;
-o-transform: rotate(90.0deg) translate(-40px,0px); /* Opera 10.5 */
-o-transform-origin: 0 100%;
-webkit-transform: rotate(90.0deg) translate(-40px,0px); /* Saf3.1+, Chrome */
-webkit-transform-origin: 0 100%;
transform: rotate(90.0deg) translate(-40px,0px); /* Saf3.1+, Chrome */
transform-origin: 0 100%;
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1.0)
progid:DXImageTransform.Microsoft.gradient(startColorstr=#ff999999, endColorstr=#ffcccccc); /* IE6,IE7 */
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1.0)"
"progid:DXImageTransform.Microsoft.gradient(startColorstr=#ff999999, endColorstr=#ffcccccc)"; /* IE8 */
/* CSS3 Gradient Effect */
background: -moz-linear-gradient( top, #999999, #cccccc);
background: -webkit-gradient(linear, left top, left bottom, from(#999999), to(#cccccc));
}
.horizontalaccordion>ul>li>div {
display:none;
float:left;
overflow: auto;
position:relative;
top:-40px;
left:40px;
*top:0px; /* IE7 Hack */
*left:0px; /* IE7 Hack */
margin:0;
width:320px;
height:280px;
padding:10px;
}
.horizontalaccordion>ul>li:hover {
overflow: hidden;
width: 380px;
}
.horizontalaccordion:hover>ul>li:hover>div {
display:block;
}
.horizontalaccordion:hover>ul>li:hover>h3 {
/* Decorative CSS */
color:#fff;
background:#000000;
/* CSS3 Gradient Effect */
background: -moz-linear-gradient( top, #454545, #000000); /* FF, Flock */
background: -webkit-gradient(linear, left top, left bottom, from(#454545), to(#000000)); /* Safari, Chrome */
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1.0)
progid:DXImageTransform.Microsoft.gradient(startColorstr=#ff454545, endColorstr=#ff000000); /* IE 5.5 - IE 7 */
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1.0)"
"progid:DXImageTransform.Microsoft.gradient(startColorstr=#ff454545, endColorstr=#ff000000)"; /* IE 8 */
}
.horizontalaccordion>ul>li>h3:hover {
cursor:pointer;
}
Note:
- You must specify DOCTYPE in your web page in order for this CSS to work in IE.
- You can have more than one Accordion in a single page. If they have different properties, you can simply copy the above code, give different class name, and change the properties.
- If number of panels are different from our example, you will need to adjust “height” & “width” properties in the CSS accordingly.
- CSS3 gradient effect will work in all browsers except for Opera. You can also add a background image to display gradient effect, which will also work in Opera and older browsers. In this case you can also get rid of IE filters.
- Also note that IE filters must be grouped together in order to work, otherwise only the last filter is applied. This has forced me to use rotation again on mouse over. I personally like to keep structure and behavior separate – I have therefore provided two version of the horizontal accordion in the download file: one with gradient effect for IE and another one without it.
- This accordion uses CSS “hover” and works with a mouse. (Point added after reading concerns in comments below – Sorry for taking this point for-granted)
I hope you have enjoyed this post and found it to be useful. I am looking forward to reading your feedback, opinion and suggestions.



Nice article – shame it doesn’t work on the IPhone though ( seems there’s no way to trigger hover effects on a touch device, so both this and the vertical accordion you described rescently simply sits there with all panes permanently closed on such deviced)
When this design is used in an actual website the designer should have created a separate style sheet for small resolution devices or specifically for iphone devices. In that style sheet rather than hover, a regular click would be used to make it work as correctly. This is simply a tutorial to make it work in general. Making it work on other devices is not within the scope of the tutorial. Check out a tutorial on calling other style sheets based on screen resolution.
This is what most of us will be dealing with in near future, when more and more touch screen devices enter and capture the market.
You should take these solutions as a starting point – mix a little bit of JavaScript to find perfect solution that works everywhere.
I have seen this done before at http://www.aftenposten.no/nyheter/iriks/politikk/
Good example of how to implement CSS accordion in production. You can replicate their technique with our accordion by adjusting width of panel heads.
Thanks for sharing.
Excellent demo. Now just add the :focus pseudoselector and make it keyboard accessible to take it up a notch.
Looks good. I would definitely want to modify it to work onclick. The mouseover is a bit jarring.
great effect.
thank you for the nice tutorials.
Does it work with firefox and IE?
Hey, I use the JQuery Accordion on my FAQ page but I like the noScript capabilities of your CSS powered accordion. I’m working on combining your CSS and a click-able CSS that I found (link below).
What I’m trying to do is located at (http://www.whitelakeholidayresort.com/our-units-2.html). It’s a test page at this point, but I hope to make it the default so that our units can be looked at one by one, instead of how it currently looks.
I’ve found on http://bonrouge.com/br.php?page=cssonclickswitch
that it’s possible to use CSS and a click of the mouse to change something.
SO…I’m trying to incorporate what I’ve found with bonrouge.com and your site
http://www.w3avenue.com/2010/04/05/cross-browser-pure-css3-horizontal-accordion/ to make the panels clickable instead of hoverable!
I’m no expert, so if you have any ideas please send them my way.
Thanks, J
Not finished the new site yet but i love this thanks for sharing.
I love CSS3 and JavaScript i can’t wait till HTML5 CSS3 will be all we need to make dynamic websites. And all cross browser platforms .
Thanks again .You guys Rock!!!!
As a student still learning my craft, I would just like to say a great big thank you for the vertical accordian.
I’ve just designed a website incorporating this object, saving me lots of hours with what I had planned before I saw this article.
It works in all browsers except Opera 10.61 which relegates it to the background colour. I’m still learning svg and this is the only way apart from adding an image which I don’t want to do.
How do I get it to render on a touch phone, please?
Just a quick question, are you able to use the dead space when the accordian is closed? I would like to add a login feature, if at all possible.
I’ve played but at the moment, I can’t seem to get it right.
Any help appreciated.
This is a great tutorial! Everything works great. Thanks for sharing.
Nice. There is a plain vertical one done using pure CSS3 here: http://www.aplweb.co.uk/blog/css/pure-css3-accordion/