How to Create a CSS3-Only Vertical Accordion Using the :target Selector

Craig Buckler
Share

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.

View the demonstration page…

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;
}

View the demonstration page…

If anything, this CSS is simpler than the tab control and looks better. But vertical accordions are easy — horizontal ones are far cooler!…

CSS Master, 3rd Edition