How to Create a CSS3-Only Horizontal Accordion Using the :target Selector
The CSS3 :target selector is incredibly powerful and allows us to create attractive widgets which would have required ninja-like JavaScript skills a few years ago. We’ve already built a tab control and a vertical accordion. In this post, we’ll create a horizontal accordion using the same HTML5 markup.
The solution works in IE9, Chrome, Firefox, Safari and Opera and doesn’t require JavaScript or images. Again, it fails miserably in IE6, 7 and 8 so you either need a JavaScript shim such as selectivizr or some other fallback.
The HTML
Here’s a reminder of the HTML5 code. It’s identical to our vertical accordion: there are a number of section
elements with clickable headings contained in the initial h2
tag:
<article class="accordion">
<section id="acc1">
<h2><a href="#acc1">Title One</a></h2>
<p>This content appears on page 1.</p>
</section>
<section id="acc2">
<h2><a href="#acc2">Title Two</a></h2>
<p>This content appears on page 2.</p>
</section>
<section id="acc3">
<h2><a href="#acc3">Title Three</a></h2>
<p>This content appears on page 3.</p>
</section>
<section id="acc4">
<h2><a href="#acc4">Title Four</a></h2>
<p>This content appears on page 4.</p>
</section>
<section id="acc5">
<h2><a href="#acc5">Title Five</a></h2>
<p>This content appears on page 5.</p>
</section>
</article>
The CSS
The CSS is a little more complex but it’s worth it. First we style our outer article
container:
article.accordion
{
display: block;
width: 43em;
margin: 0 auto;
background-color: #666;
overflow: auto;
border-radius: 5px;
box-shadow: 0 3px 3px rgba(0,0,0,0.3);
}
Each section starts in its closed state; they’re floated to the left and have a width of 2em. Overflow is set to hidden and we’re also making the text color the same as the background so they effectively look like solid blocks without content:
article.accordion section
{
position: relative;
display: block;
float: left;
width: 2em;
height: 12em;
margin: 0.5em 0 0.5em 0.5em;
color: #333;
background-color: #333;
overflow: hidden;
border-radius: 3px;
}
Now for some nasty prefixed CSS3! Each h2
title is rotated 90° counter-clockwise using a transform and absolutely positioned over the closed section
:
article.accordion section h2
{
position: absolute;
font-size: 1em;
font-weight: bold;
width: 12em;
height: 2em;
top: 12em;
left: 0;
text-indent: 1em;
padding: 0;
margin: 0;
color: #ddd;
-webkit-transform-origin: 0 0;
-moz-transform-origin: 0 0;
-ms-transform-origin: 0 0;
-o-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-transform: rotate(-90deg);
-moz-transform: rotate(-90deg);
-ms-transform: rotate(-90deg);
-o-transform: rotate(-90deg);
transform: rotate(-90deg);
}
article.accordion section h2 a
{
display: block;
width: 100%;
line-height: 2em;
text-decoration: none;
color: inherit;
outline: 0 none;
}
We can now ‘open’ the active section using the :target selector. The section
width and colors are changed and the title is moved back to the top:
article.accordion section:target
{
width: 30em;
padding: 0 1em;
color: #333;
background-color: #fff;
}
article.accordion section:target h2
{
position: static;
font-size: 1.3em;
text-indent: 0;
color: #333;
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
That’s fine, but a CSS3 transition makes it look fantastic:
article.accordion section,
article.accordion section h2
{
-webkit-transition: all 1s ease;
-moz-transition: all 1s ease;
-ms-transition: all 1s ease;
-o-transition: all 1s ease;
transition: all 1s ease;
}
It’s a shame IE6, 7 and 8 users can’t use the widget. IE9 users won’t see animation either. But you’d need a lot of time and patience to achieve the same effect using JavaScript! Have fun with it.