How to Create a CSS3-Only Vertical Accordion Using the :target Selector
We recently created a CSS3-Only tab control which used the powerful :target selector. One of the major benefits of CSS is that we can restyle HTML how we like; so we’re going to transform our mark-up into a vertical accordion.
The solution works in IE9, Chrome, Firefox, Safari and Opera and doesn’t require JavaScript or images. It fails miserably in IE6, 7 and 8 so you could either use the selectivizr shim or hide the widget from those users and tell them to upgrade.
The HTML
Our HTML5 code is identical to that used by the tab control. I’ve only changed the article
class to “accordion” and renamed some of the IDs so it’s easier to understand what’s going on. There are also five sections since it looks a little better:
<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>
As before, the clickable section heading is contained within each section
as the initial h2
tag.
The CSS
First, we’ll style the article
container and section
elements. Each section starts in its closed state with a height of 2em (note that overflow is set to hidden):
article.accordion
{
display: block;
width: 30em;
padding: 0.5em 0.5em 1px 0.5em;
margin: 0 auto;
background-color: #666;
border-radius: 5px;
box-shadow: 0 3px 3px rgba(0,0,0,0.3);
}
article.accordion section
{
display: block;
width: 28em;
height: 2em;
padding: 0 1em;
margin: 0 0 0.5em 0;
color: #333;
background-color: #333;
overflow: hidden;
border-radius: 3px;
}
The section title is now styled to use all the available room in the closed state:
article.accordion section h2
{
font-size: 1em;
font-weight: bold;
width: 100%;
line-height: 2em;
padding: 0;
margin: 0;
color: #ddd;
}
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. We set a larger height and background color, then enlarge and re-color the title too:
article.accordion section:target
{
height: 15em;
background-color: #fff;
}
article.accordion section:target h2
{
font-size: 1.6em;
color: #333;
}
If necessary, you can set the section
height to auto
so it uses the minimum space it requires. However, that makes it impossible to add nice CSS3 transitions which smoothly resizes the element…
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;
}
If anything, this CSS is simpler than the tab control and looks better. But vertical accordions are easy — horizontal ones are far cooler!…