Tutorial: Pure CSS3 Accordion

We all know that content is king (Thank you, Mr. Gates), but as designers we sometimes struggle with finding enough space to fit all that glorious content in. One of my favorite ways to display a lot of content in a small space is with an accordion. An accordion allows readers to go through several sections of content without ever moving their scroll bar. Equally as important, an accordion is interactive–that is, it keeps your reader engaged in your site while reading through that precious content you’ve created. Today, we’re going to build a simple CSS-powered accordion that you can use to do just this.

An accordion is essentially a series of inputs grouped with a series of pieces of content. We then use the magic of CSS to hide or display the appropriate content when the user selects its input. Let’s start by creating a div for our accordion and nesting a div for each accordion panel inside of it.

<div class="accordion">
	<!-- Panel 1 -->

	<!-- Panel 2 -->

	<!-- Panel 3 -->

	<!-- Panel 4 -->

	<!-- Panel 5 -->

A lot of the accordions I’ve seen out there are wrapped in a section element. This is incorrect and here’s why: The HTML5 spec states that the section element is not a generic container element and that when an element is needed for styling purposes or as a convenience for scripting, we should stick with the div element. In the case of our accordion, we’re using that div with class=”accordion” for styling purposes. Therefore, it is not recommended by the HTML5 spec that a section be used here.

Now we can add our inputs and content inside each of our nested divs.

<input id="panel1" type="checkbox" />
<label for="panel1">Tyrannosaurus Rex</label>
	<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras gravida nisi sed elit posuere eleifend. In dapibus convallis sem vel rhoncus. Donec bibendum eros non purus lacinia lacinia. Vivamus fermentum erat ut ornare placerat. Suspendisse quis enim imperdiet, tincidunt nisi non, venenatis mi. Proin commodo in augue et scelerisque. Integer id lacus at leo gravida iaculis non eget libero. Donec egestas malesuada est sit amet bibendum. Pellentesque lacinia id neque id tincidunt.</p>

In this instance, I’m using checkboxes as my inputs. This will allow the user to open multiple accordion panels simultaneously. If you’re really working with restricted area for your content, you may opt for radio buttons here. In using radio buttons, an open panel will close when another is opened, just as a selected radio button is deselected when another is clicked in a normal radio button group.

You may also notice that we’re using the HTML5 element article instead of a div for the content of the accordion panels. Earlier I explained why we shouldn’t be using an HTML5 element in place of a div, so I suppose it’s only fair that I explain my hasty change of heart. The HTML5 spec states that we should use the article element for content that is self-contained within a page, such as a forum post, a magazine or newspaper article, a blog entry, or user-submitted content. Since the content of each accordion panel is to be treated as independent pieces of content and the element is not being solely used for styling purposes, this is an excellent time to use our shiny new HTML5 elements.

With your panels constructed and filled with delicious content, we can move on to styling. There are infinite possibilities when it comes to creatively styling an accordion. I’ve chosen a simple, flat green theme for my labels and a gentle inset box shadow to separate my panels and give them some depth.

.accordion {
	width: 500px;
	font-family: Arial, sans-serif;
.accordion label {
	position: relative;
	display: block;
	padding: 5px 20px;
	height: 40px;
	border-top: 1px solid rgba(0, 0, 0, 0.1);
	background: #29bb67;
	color: #fff;
	text-align: center;
	text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.5);
	font-weight: bold;
	line-height: 40px;
	cursor: pointer;
.accordion label:hover {
	background: #27ae60;
.accordion input:checked + label,
.accordion input:checked + label:hover {
	background: #27ae60;
.accordion input {
	display: none;
.accordion article {
	position: relative;
	overflow: hidden;
	height: 0;
	box-shadow: inset 0 0 15px 1px rgba(0, 0, 0, 0.2);
	transition: height 0.5s ease-in-out;
.accordion input:checked ~ article {
	height: 180px;
.accordion article p {
	margin: 0;
	padding: 20px;
	font-size: 14px;
	line-height: 20px;

Alongside our styling, we have some very simple CSS making our accordion work properly. This is done with the CSS3 pseudo-class :checked. As you can see, the article elements have a height of 0. When the corresponding input is checked, they have a fixed height you can assign depending on the size of your content. A height of auto will not work here due our use of CSS transitions to make things fun and pretty. If you want to set the height of the panels to auto, simply remove the height transition.

This simple CSS accordion will work in all modern browsers, including IE10.

Click here for a working demo of this simple, pure CSS3 accordion.


DesignLoud is a web development & digital marketing agency located in Wilmington, NC. Our team takes great pleasure in teaching others how to build and market their websites to see higher returns.

Leave a Comment