Skip to main content

Stacked Disclosure Pattern: An Accordion Variant

Introduction

The accordion widget pattern consists of a set of associated disclosure panels. Each panel can be opened or closed individually with the purpose of reducing the need to scroll through multiple sections on a page. Commonly, the accordion will typically limit it to only ONE panel open at a time. If a panel is open and the user opens another, the formerly open one closes. This comes off as a potential antipattern in that the accordion can prevent the user from comparing the content in different panels. The approach to accordions works if the panel contents are truly independent of each other. That is rarely the case.

While some accordion code examples include configuration to control how many panels can be open at a time, the accordion variation presented here is explicitly restricted. The stacked disclosure pattern explicitly prevents this antipattern by allowing any number of panels to be open (or closed at a time). Additionally, to support managing the panels, the stacked disclosure requires buttons to open or close all the panels at once.

This JavaScript library and supporting information are an open source project on GitHub released under the Mozilla Public License Version 2.0.

Example Stacked Disclosure

Example Stacked Disclosure Link

The example below, Cat Coat Patterns, showcases the basic features of the stacked disclosure in action. At the top of the widget is an <H3> that names the entire widget. To the right of this heading are the Open All and Close All button that show a tooltip on hover and focus. The three disclosure panels are controlled by three toggles which are buttons embedded inside <H4> headings that also label the toggled panels.

Cat Coat Patterns

Tuxedo cats refer to cats whose coats are a mix of only white and black, although there are dilute tuxedos who are gray and white. However, not all cats with black and white coats are "proper" tuxedos. A "true" tuxedo looks like they are in formal wear. They usually have a white belly that extends up to the next or face while the rest is black, just like a tuxedo shirt and coat. Quite often, they they will have more white on their face (including mustaches) as well as the very popular white socks at the end of their legs.

The calico cat is an amazing genetic circumstance that produces at tricolor cat of white, orange, and either gray or black. Because some coat colorings are sex-linked traits, it is extremely rare for a calico cat to be a male. In such cases, a male calico usually has some genetic anomalies such as being intersexed or having a chromosome duplication. The consequences are generally sterility but a beautiful coat.

A white cat is not necessarily albino, but there is a decent chance that the cat may have some degree of deafness. The degree of deafness is linked to eyecolor. White cats with blue eyes have a very high chance of being deaf, while other eye colors still have a higher chance of hearing issues compared to other cat coat patterns and colors.

HTML Structure

HTML Structure Link

The general HTML structure of any stacked disclosure follows a fixed pattern that begins with the top matter followed by toggles and panels:

Stacked Disclosure HTML
<div role="region" class="stacked-disclosure" aria-labelledby="ID-STACK-NAME">
	<div class="stack-top">
		<h3 class="stack-name" id="ID-STACK-NAME"> ... </h3>
		<button class="open-all">
			<span>Open All</span>
			<svg focusable="false"><use xlink:href="#icon-open-all"></use></svg>
		</button>
		<button class="close-all">
			<span>Close All</span>
			<svg focusable="false"><use xlink:href="#icon-close-all"></use></svg>
		</button>
	</div> <!-- end stack top -->
	
	<h4 class="panel-toggle" data-disclosure-expanded="true / false">
		<button class="toggle" aria-expanded="true / false">
			<svg focusable="false" class="plus"><use xlink:href="#icon-plus"></use></svg>
			<svg focusable="false" class="minus"><use xlink:href="#icon-minus"></use></svg>
			<div class="toggle-text"> ... </div>
		</button>
	</h4> <!-- end panel toggle -->
	<div class="panel">
		...
	</div> <!-- end panel -->
	
	<!-- repeat panel-toggle and panel -->
	
<div> <!-- end stacked disclosure -->

Note that headings should be used in the stacked disclosure for the .stack-name and the .panel-toggle elements. This benefits any users of assistive technologies. Note that the headings should be properly nested. For example, if an <h4> is used for the stack's name, the panel toggles need to be <h5> elements.

If you wish to use the open all, close all, plus, or minus SVG icons used in this demo, include the following SVG code on your page. Note that this code intentionally hides the SVG from screen readers, meaning that any use of the icons should provide proper accessible naming of where it is used.

SVG Icon HTML
<svg hidden aria-hidden="true" focusable="false" id="icons" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
	<symbol id="icon-plus" viewBox="0 0 90 90">
		<g>
			<line stroke-width="20" stroke="currentColor" fill="none" y2="85" y1="5" x2="45" x1="45"/>
			<line stroke-width="20" stroke="currentColor" fill="none" y2="45" y1="45" x2="85" x1="5"/>
		</g>
	</symbol>
	<symbol id="icon-minus" viewBox="0 0 90 90">
		<g>
			<line stroke-width="20" stroke="currentColor" fill="none" y2="45" y1="45" x2="85" x1="5"/>
		</g>
	</symbol>
	<symbol id="icon-close-all" viewBox="0 0 200 200">
		<path stroke-width="10" stroke="currentColor" fill="transparent" style="fill: var(--top-fill-color, transparent); stroke: 	var(--top-stroke-color, currentColor)" d="M15 15h130v130H15z"/>
		<path fill="none" stroke="currentColor" stroke-width="20" style="stroke: var(--icon-color, currentColor)" d="M40 80h80"/>
		<path fill="none" stroke="currentColor" stroke-width="10" style="stroke: var(--stroke-color, currentColor)" d="M50 185h140M165 30v140"/>
		<path fill="none" stroke="currentColor" stroke-width="10" style="stroke: var(--stroke-color, currentColor)" d="M30 165h140M185 50v135"/>
		<g fill="none" stroke="transparent" style="stroke: var(--highlight-color, transparent)" stroke-width="10"  >
			<path d="M40 175h140M155 20v140M20 155h140M175 40v140"/>
		</g>
	</symbol>
	<symbol id="icon-open-all" viewBox="0 0 200 200">
		<path stroke-width="10" stroke="currentColor" fill="transparent" style="fill: var(--top-fill-color, transparent); stroke: var(--top-stroke-color, currentColor)" d="M15 15h130v130H15z"/>
		<path fill="none" stroke="currentColor" stroke-width="20" style="stroke: var(--icon-color, currentColor)" d="M80 40v80M40 80h80"/>
		<path fill="none" stroke="currentColor" stroke-width="10" style="stroke: var(--stroke-color, currentColor)" d="M50 185h140M165 30v140"/>
		<path fill="none" stroke="currentColor" stroke-width="10" style="stroke: var(--stroke-color, currentColor)" d="M30 165h140M185 50v135"/>
		<g fill="none" stroke="transparent" style="stroke: var(--highlight-color, transparent)" stroke-width="10"  >
			<path d="M40 175h140M155 20v140M20 155h140M175 40v140"/>
		</g>
	</symbol>
</svg>

Configuration Options

Configuration Options Link

Two configuration options are included with the stacked disclosures. The first is the optional display of tooltips on the open all and close all buttons. One can turn on the tooltips by including the tooltip class on the stacked disclosure outer element:

<div role="region" class="stacked-disclosure tooltip" aria-labelledby="ID-STACK-NAME">

The other option involves including the Screen Reader Messaging JavaScript library on your page. If this library is optionally loaded, the open all and close all buttons will inform screen readers that the panels were successful all opened or closed. This is arguably an accessibility improvement as these buttons otherwise give no indication if any panels are open or closed.

Design Specifications

Design Specifications Link

The Stacked Disclosure pattern was created to meet the specific needs of a client to ensure that all accordions performed consistently on a site. The design request specified:

Accessibility Features

Accessibility Features Link

As accessibility was a key goal of the stacked disclosure pattern, multiple design decisions were made to ensure accessibility. These decisions were informed by the WAI-ARIA accordion example but modified to meet the design specifications and current browser capabilities.