Grids
Visual layout should be efficient and consistent, without impeding document structure and accessibility
- Version:
- 0.1.0
- Status:
- Published
Introduction
The following guidance builds upon GEL's Grid specification with progressive enhancements to capitalize on recent CSS layout developments.
Recommended markup
Necessarily, a grid is composed of individual grid items that together form a set, or group. Sometimes the items should be perceived as related, and in other cases they are only grouped together in order to achieve a visual layout.
A sighted user is typically afforded visual cues that two or more adjacent grid items belong to a set, such as a disparity in style and layout. A blind user instead has to rely on the semantics, or lack thereof, communicated by their screen reader software.
Should grid items represent arbitrary containers, solely used to place items in a grid formation, the <div>
element can be used.
✕ Bad example
(Table semantics are inappropriate since the content is not tabular.)
<table>
<tr class="gel-layout">
<td class="gel-layout__item gel-1/2">One item</td>
<td class="gel-layout__item gel-1/2">Another unrelated item to the right</td>
</tr>
</table>
✓ Good example
<div class="gel-layout">
<div class="gel-layout__item gel-1/2">One item</div>
<div class="gel-layout__item gel-1/2">Another unrelated item to the right</div>
</div>
The <div>
element is not represented in the browser accessibility tree[1] and therefore presents the user with no undue or unexpected semantic information. Only the contents of the items, where semantic HTML is provided, will be interpreted.
In some cases, the items will have independent semantics to express. In which case, use the appropriate semantic elements for the grid items. In the following example, a tangentially related <main>
and <aside>
form a wider content column and a narrower sidebar.
✕ bad example
(CSS classes, which do not communicate semantic information to accessibility APIs, are used to differentiate the elements.)
<div class="gel-layout">
<div class="main gel-layout__item gel-2/3">Content</div>
<div class="sidebar gel-layout__item gel-1/3">Sidebar</div>
</div>
✓ Good example
(The correct landmark elements are employed.)
<div class="gel-layout">
<main class="gel-layout__item gel-2/3">Content</main>
<aside class="gel-layout__item gel-1/3">Sidebar</aside>
</div>
Grids as lists
If items belong thematically to a set, the standard is to mark them up as a list. Doing so fulfills WCAG2.1 1.3.1 Info and Relationships[2].
Lists are identified by assistive technologies, and their items are enumerated. Many screen readers also provide shortcuts to traverse list items, such as the i key in NVDA.
A grid of scheduled programmes can be considered a thematic set, because each item is of the class "programme".
<ul class="gel-layout">
<li class="gel-layout__item gel-1/4">Doctor Who</li>
<li class="gel-layout__item gel-1/4">Miranda</li>
<li class="gel-layout__item gel-1/4">Holby City</li>
<li class="gel-layout__item gel-1/4">Springwatch</li>
</ul>
Lists that contain children that are not list items are invalid, and liable to cause inconsistent output in browsers. Such parsing issues are considered a failure under WCAG2.1 4.1.1 Parsing[3].
The correct way to incorporate row wrappers into a list is, therefore, to use WAI-ARIA:
<div role="list">
<div role="presentation" class="gel-layout">
<div role="listitem" class="gel-layout__item gel-1/4">Doctor Who</div>
<div role="listitem" class="gel-layout__item gel-1/4">Miranda</div>
<div role="listitem" class="gel-layout__item gel-1/4">Holby City</div>
<div role="listitem" class="gel-layout__item gel-1/4">Springwatch</div>
</div>
<div role="presentation" class="gel-layout">
<div role="listitem" class="gel-layout__item gel-1/4">Dragon's Den</div>
<div role="listitem" class="gel-layout__item gel-1/4">Blue Peter</div>
<div role="listitem" class="gel-layout__item gel-1/4">Daily Politics</div>
<div role="listitem" class="gel-layout__item gel-1/4">Robot Wars</div>
</div>
</div>
In the example, the grid is defined using role="list"
. Children are explicitly removed from the accessibility tree using role="presentation"
, and items are marked with role="listitem"
. The outcome is that assistive technologies correctly report one list encapsulating eight list items.
Copyright © 2021 BBC. This content is published under the Open Government Licence, unless otherwise noted.