Disclosure button design pattern: <span> element

This disclosure button is created using the <span> element, with scripting to provide the expected behaviour. Additional semantic information is provided using ARIA.

It is better to use the <button> element to create a disclosure button because the browser will automatically provide keyboard support and most semantic information.



Makes me happy!


Uses the HTML tabindex attribute with a value of 0. This places the <span> into the tab order based on its location in the source code. The visual appearance of the button changes when focus moves to it.

Uses the ARIA role attribute with a value of button. This instructs the browser to expose the <span> element as a button through its accessibility API. This information is used by assistive technologies to inform users what they're dealing with.

Keyboard interaction for the button control is handled through scripting. Both enter and space key events are captured, and used to trigger the button's expected behaviour.

The aria-expanded attribute is used to indicate the state of the disclosure widget. It is applied to the <span> so that assistive technologies can determine the state of the widget whether it is expanded or collapsed. The aria-expanded attribute is set to false (collapsed) initially, then scripted to toggle between true and false whenever the button is activated.

The aria-controls attribute is used to create a relationship between the <span> and the <div> that contains the content. It takes the idref of the <div> as its value. This enables assistive technologies to provide specific commands for moving focus from the <span> to the <div>.

The hidden attribute indicates the state of the <div> containing the content. It is used to hide the content both visually and from assistive technologies. The hidden attribute is added initially, then scripted to be added or removed whenever the button is activated.

The visible style of the <button> when pressed is hooked to the aria-expanded attribute. Similarly the visibility of the <div> is hooked to the aria-hidden attribute using CSS selectors. This has no direct impact on accessibility, but it creates a cleaner separation between structure and design.

Note: There is an issue with Firefox, where content with aria-hidden is exposed to assistive technologies when inside a <button> or an element with role="button" applied. Refer to bug 1147359 for more information.