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

Craig Buckler

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.

View the demonstration page…

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.


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 id="acc2">
		<h2><a href="#acc2">Title Two</a></h2>
		<p>This content appears on page 2.</p>
	<section id="acc3">
		<h2><a href="#acc3">Title Three</a></h2>
		<p>This content appears on page 3.</p>
	<section id="acc4">
		<h2><a href="#acc4">Title Four</a></h2>
		<p>This content appears on page 4.</p>
	<section id="acc5">
		<h2><a href="#acc5">Title Five</a></h2>
		<p>This content appears on page 5.</p>



The CSS is a little more complex but it’s worth it. First we style our outer article container:

	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;

View the demonstration page…

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.