Pure CSS Tab Panel

Published on (01-22-2016).

Most Tab Panel widgets rely on a list of jump links followed by "sections". These links are styled as tabs, while the sections are styled as panels.

The problem with this approach is that semantically it is not the best fit, which forces screen-reader users to create a complex mental model. WAI-ARIA roles may help these users to make sense of that markup but still, I think it would be much better if POSH (Plain Old Semantic HTML) was used to convey the pairing of “tabs” and “panels”…

TL;DR: Pure CSS Tab Panel on codepen

KIS (Keep It Simple)

A simple succession of headings and divs should lead users to assume - rightly - that those headings are followed by their respective section (by the content they "introduce"). This alone is enough for screen-reader users to make sense of the markup—after all, when it comes to content, this is the most common markup pattern on the Web.

Progressive Enhancement

From there, the challenge is to create a Tab Panel without breaking the experience of SR users along the way. We can use extra markup and all the CSS we want, but we do not want to create "meaningless" tab stops or actionable contols (i.e. "buttons" to show/hide panels).

Going JS-less

As is often the case with CSS, the solution relies on a combination of specific markup and styles. Radio buttons are used as selectors to "show/hide" the panels and because they are pratically impossible to style, we use associated labels with these controls.


The logic:

The markup

With the extra markup required to make things work, it looks like this:

<label  for="tab-1" tabindex="0"></label>
<input  id="tab-1" 
<h2>Tab 1</h2>
<div>Panel 1</div>

What and why:



Note: the last point above would not have made the list if browsers were not broken when it comes to label and tabindex. Because all browsers fail to create actionnable tab-stop, sighted keyboard users cannot easily navigate between panels.

See the Pen Pure CSS Tab panel by Thierry (@thierry) on CodePen.