Transitional Accordion

First Accordion heading
Second Accordion heading
Third Accordion heading

- 4 min read

The accordion pattern was created as a means to deal with vertical (sub) navigation patterns. Slowly, it began to appear as a form of progressive disclosure to politically manage vast amounts of content that were straight copies from printed brochures and documents.

The main assumption driving the pattern was that people don’t scroll, and even though we had data to the contrary available to us - that assumption pushed the accordion pattern (and many other patterns like Carousels) forward.

Also driving this pattern were popular javascript libraries like Mootools, Scriptaculous, and jQuery.

It had difficulties with breaking the back button, in that people couldn’t link directly to content within the accordions. Accordions have a tendency to increase interaction cost - and increase cognitive load. Thus making them a very expensive interface component, and should be used in specific cases with very clear accompanying titles.

jQuery for designers Accordion example
An example of what not to do: This jQuery for designers take on the sliding drawer pattern is an example where using this for navigation could frustrate people because hiding navigation items makes them less discoverable and requiring motor control to get to those navigation items gets in the way of people.
A List Apart Accordion example
A List Apart pattern library is a good of example of where to use the pattern to disclose code if you need it. The pattern works well where the need for the content fits a specific use case like a FAQ, or revealing a detail that only some people will interact with.

The accordion pattern has served to aid us where we've needed to progressively disclose information - to shorten pages where people only might want to know very specific information, dashboard interfaces and expanding on examples or pieces of reference information, such as documentation, are just some examples of where the pattern is actually useful.

Twitter Accordion example
Twitter uses the Accordion pattern to disclose information that's not immediately vital for you to know.

The experiment

I wanted to explore adding some motion to interface components, the aim of adding motion to this component is to make the component action visually make more sense, rather than jolt from it’s default state to it’s open state with no visual hinting.

CSS animating height

I’d originally thought that animating height without the aid of javascript was impossible as height is not an animatable property.

It wasn’t until I’d seen John Allsopp’s talk at WDS13 where he was using Max-height instead of height. The major problem with this is you can’t have an ‘auto’ - the animation can’t be smart and automatically size a different sized component. You need to know a ‘maximum’ boundary of height.

						
	/* The accordion default state */
	.d-accordionItem {

		/* Magic number,
			you need to know the size of the content
			with this method
		*/
  		max-height:50em;
		transition:max-height 1s;

	}
	/* The class that's applied with javascript to collapse */
	.is-collapsed {

    	max-height:0;

	}


						
					

Beyond Max-height: Collapsing the box

I experimented with other ways to achieve this. Using a transform is difficult because it still leaves the bounding box behind. By switching between display:none and display:block animation will appear to jolt.

I tried animating the font-size, but ultimately animating line-height to collapse the box appeared to be the best solution beyond max-height - this has some problems in that it looks ugly when it is animated down to 0. So you need to add opacity, to fade it before you see all of the type mushed together.

If you have padding within the animated component then it won’t collapse beyond the padding, so you need to either have no padding or animate the padding as well. By animating another property it will become a more costly animation to frame rate. So this is worth keeping in mind if you want to depart from max-height animation.

						
	/* The accordion default state */
	.d-accordionItem {

		/*
		   The line height of the content won't change depending
		   on how much content there is, so in this approach
		   the content can be any size.
		   This is more transportable but comes with a downside
		   you need to hide the type, with opacity, before it hits 0
		   or it will look terrible. If there's any padding,
		   we'll need to collapse that too, which makes it expensive.

		*/

  		line-height:1.6;
  		opacity:1;
		transition: line-height 1s, padding 1s, opacity 0.5s;

	}
	/* The class that's applied with javascript to collapse */
	.is-collapsed {

    	line-height:0;
    	opacity:0;
    	padding:0;

	}


						
					

Inspiration for the animation

A picture of a real world accordion
Looking at the real world object can sometimes help us determine how the abstraction should behave. Photo Credit: bernat... via Compfight cc

To animate the opening and closing of the accordion, the first step was to actually look at how a real accordion works - It collapses and expands with a slight rotation as it collapses and folds inwards, this is where the concept of skeumorphism makes sense to the animation design and allows the animation to aid the action. To do this with CSS we use 3d transforms, scale, and opacity together.

Dealing with the navigation problem

Today, we have a number of ways of dealing with the back button / navigation problem - the CSS :target pseudo, supported IE9+, means we can style elements based on the #hashtag at the end of the URL fragment and allows you to link directly to any open pane. We also have the HTML History API available for IE10+ to allow us to do this with Javascript.

Progressive enhancement

We need to make sure that if we use a CSS animation to create a state change that we can also provide that same effect (of being open) if the browser doesn't possess the CSS animations feature, but also an always open default if there is no Javascript or CSS animation present. You can use a library like Modernizr to manage this.

Showing state changes

We know icons alone can be problematic for usability, they can be interpreted a number of different ways - their meanings can differ by culture or region, or by mental model. Icons are, however, a helpful device for dealing with showing state changes to colourblind users, and by allowing people to mentally group actions together. Anytime you need to demonstrate a state change, it’s worth thinking about how this would be interpreted if you couldn’t use colour to demonstrate them, and how quickly can they associate the icon itself with the action.

For the demo I chose the ‘+’ to illustrate the possible expansion of the element because we can provide feedback to the user - and say 'hey, the accordion is animating,' by rotating the icon. There are a number of approaches to what icons you can use in this situation - but generally it seems to either be something which hints at being able to be expanded, or an arrow which changes to face down or toward the title depending on the state.

Accessibility

Even if we choose to use css :target to change state, we still need to use some Javascript to allow us to change Aria-Roles to demonstrate to screen readers that a hidden piece of content is now visible.

Rediscovering motion

Adding motion to interfaces helps frame the steps between state changes and has the potential to reduce cognitive load, but a word of caution - our aim is to hint and create a scent rather than to distract and get in the way. For the moment, we should always provide fallbacks and always keep accessibility in mind. It’s important to remember that components like these have very specific use - and aren’t always an appropriate solution just because they might animate nicely.