Cross Browser Pure CSS3 Horizontal Accordion

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.

View Demo Now Download Files

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)
View Demo Now Download Files

I hope you have enjoyed this post and found it to be useful. I am looking forward to reading your feedback, opinion and suggestions.

Stay Updated

If you found this post useful, consider subscribing to our RSS Feed! You can also stay updated by following us on Twitter and Facebook or by subscribing to our FriendFeed.

Bookmark / Share

Bookmark and Share

Read More

SIMILAR/RELATED POSTS:

PREVIOUS POST:

NEXT POST:

Reader Comments

15 Responses to “Cross Browser Pure CSS3 Horizontal Accordion”
  1. Carl says:

    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)

    • Nathan Buchanan says:

      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.

  2. Saud Khan says:

    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.

    • Saud Khan says:

      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.

  3. Joe McCann says:

    Excellent demo. Now just add the :focus pseudoselector and make it keyboard accessible to take it up a notch.

  4. Ron Earl says:

    Looks good. I would definitely want to modify it to work onclick. The mouseover is a bit jarring.

  5. great effect.

    thank you for the nice tutorials.

  6. Sam says:

    Does it work with firefox and IE?

  7. Stuart says:

    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!!!!

  8. Cass says:

    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?

  9. Cass says:

    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.

  10. This is a great tutorial! Everything works great. Thanks for sharing.

  11. Andy says:

    Nice. There is a plain vertical one done using pure CSS3 here: http://www.aplweb.co.uk/blog/css/pure-css3-accordion/

Leave Comment

 
 

Stay Updated, Subscribe to RSS Feed

 
 
 
 

Blogroll

 

Sponsored Links

  • List MLS Multiple Listing Service
  • BlueHost coupon