CS169 a11y Collapsible Demo - JSFiddle
Look here for one example https://www.w3.org/TR/wai-aria-practices/examples/disclosure/disclosure-faq.html
by Michael Ball
HTML
<h1>ARIA Demo for CS169</h1>
<br>
<p>
Example 1 is something you might find on a completely inaccessible site. Examples 4 and 5 are the best and what you should follow.
In this example of collapsible content we want to control two main things: using the keyboard to toggle the panel, and conveying the toggled state to a screen reader.
</p>
<hr/>
<div class="panel">
<div class="panel-heading"
onclick="TogglePanel('panel-1')">
1: A panel (inaccessible)
</div>
<div id="panel-1" class="panel-body">
This panel "works", but only with a mouse.
</div>
</div>
<hr/>
<div class="panel">
<div class="panel-heading"
tabIndex="0"
onkeypress="TogglePanel('panel-2')"
onclick="TogglePanel('panel-2')">
2: Keyobard-accessible Header
</div>
<div id="panel-2" class="panel-body">
This panel uses ARIA to become more accessible, but takes some shortcuts.
<br>
You can toggle this by pressing ANY key on the keyboard, which is not desired.
</div>
</div>
<hr/>
<div class="panel">
<a class="panel-heading"
href="#panel-3"
onclick="TogglePanel('panel-3')">
3: Link Heading (Mostly accessible)
</a>
<div id="panel-3" class="panel-body">
This panel a link more accessible, but the state isn't conveyed to a screen reader at all.
</div>
</div>
<hr/>
<div class="panel">
<a class="panel-heading"
href="#panel-4"
onclick="TogglePanelARIA(this, 'panel-4')"
aria-expanded="false"
aria-controls="panel-4">
4: Heading Link With ARIA
</a>
<div id="panel-4" class="panel-body">
This panel uses ARIA to become more accessible, but controlling it isn't clear.
</div>
</div>
<hr/>
<div class="panel">
<button
class="panel-heading"
onclick="TogglePanelARIAAndFocus(this)"
aria-expanded="false"
aria-controls="panel-5">
5: A button heading
</button>
<div id="panel-5" class="panel-body" tabIndex="-1">
This panel uses ARIA to become more accessible, and is...
SCSS
body {
background-color: white;
padding: 10px;
}
.panel {
border-radius: 6px;
background-color: #EEE;
border: 1px solid gray;
padding: 4px;
}
.panel-heading {
font: 18px 'Open Sans';
font-weight: bold;
&:hover {
background-color: #CCC;
}
}
.panel-body {
border-top: 1px solid gray;
display: none;
}
.open {
display: block;
}
JavaScript
function TogglePanel(panelId) {
var panel = document.getElementById(panelId);
toggleClass(panel.classList, 'open');
}
function toggleClass(classList, className) {
if (classList.contains(className)) {
classList.remove(className);
} else {
classList.add(className);
}
}
function TogglePanelARIA(elm) {
var panel = document.getElementById(elm.getAttribute('aria-controls'));
toggleClass(panel.classList, 'open');
elm.setAttribute('aria-expanded',
(elm.getAttribute('aria-expanded') == "false").toString());
}
function TogglePanelARIAAndFocus(elm) {
var panel = document.getElementById(elm.getAttribute('aria-controls'));
toggleClass(panel.classList, 'open');
elm.setAttribute('aria-expanded',
(elm.getAttribute('aria-expanded') == "false").toString());
panel.focus()
}