May 12, 2011

Horizontal accordion using CSS3 (Cross browser)

Now you can build a horizontal accordion just by using CSS3 transition effects, and filters for IE. We will continue to use ":hover" instead of ":target" pseudo class to cater Internet Explorer and other usability issues.

Accordion Markup

<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

.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

.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

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;

VIEW DEMO
DOWNLOAD







No comments:

Post a Comment

Test post after a long time

i want to see the post