Skip to contentSkip to footer
Give feedbackv3.0.2

Tabs

This pattern is referring to in-page tabs, as a way for users to manage what content is visible on screen. The optimum number of tabs is 3-4, as this indicates the amount of content on the page won't be overwhelming.

Tabs should:

  • have short, accurate labels
  • have information that is logically sorted
  • only appear on a single row
  • have a title inside each tab

Tabs shouldn't:

  • have information that needs to be seen simultaneously
  • rely on the label as it's title

Accessibility

Tabs have been built using aria attributes, to enable navigation with keyboard (arrows and tabbing) and voiceover assisted technologies.

Progressive enhancement

Without javascript and on mobile devices, the tabs stack as content blocks, and remove the tab labels.

Tab one

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sit amet nibh sed magna sollicitudin ultricies.

<ul role="tablist" class="tablist">
	<li id="tab1" aria-controls="panel1" aria-selected="true" role="tab" tabindex="0" class="tab">One</li>
	<li id="tab2" aria-controls="panel2" role="tab" aria-selected="false" tabindex="0" class="tab">Two</li>
	<li id="tab3" aria-controls="panel3" role="tab" aria-selected="false" tabindex="0" class="tab">Three</li>
</ul>
<div id="panel1" aria-labelledby="tab1" role="tabpanel" aria-hidden="false" class="tab-panel">
	<h3>Tab one</h3>
	<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sit amet nibh sed magna sollicitudin ultricies.</p>
</div>
<div id="panel2" aria-labelledby="tab2" role="tabpanel" aria-hidden="true" class="tab-panel">
	<h3>Tab two</h3>
	<p>Morbi velit arcu, molestie blandit mi sit amet, laoreet accumsan elit. Etiam quis ullamcorper nibh, pulvinar congue neque. Duis porttitor tellus enim, porta sagittis dui consequat non.</p>
</div>
<div id="panel3" aria-labelledby="tab3" role="tabpanel" aria-hidden="true" class="tab-panel">
	<h3>Tab three</h3>
	<p>Aliquam pharetra feugiat velit, sed gravida tortor consequat vel.</p>
</div>
$("li[role='tab']").click(function(){
	$("li[role='tab']").attr("aria-selected","false"); // deselect all tabs
	$("div[role='tabpanel']").attr("aria-hidden","true"); // hide all panels
	$(this).attr("aria-selected","true"); // select this tab
	$("#"+($(this).attr("aria-controls"))).attr("aria-hidden","false"); // show this panel
});
// Return keyboard functionality
$("li[role='tab']").keydown(function(ev) {
	if (ev.which ==13) {
		$(this).click();
	}
});
// Left/right keyboard functionality
$("li[role='tab']").keydown(function(ev) {
	var selected= $(this).attr("aria-selected");
	if (ev.which ==39) {
		if ($(this).next().length) {
			$("li[role='tab']").attr("aria-selected","false"); // deselect all tabs
			$("div[role='tabpanel']").attr("aria-hidden","true"); // hide all panels
			$(this).attr("aria-selected","false").next().attr("aria-selected","true").focus();
			var tabpanid= $("li[aria-selected='true']").attr("aria-controls");
			$("div[role='tabpanel']").attr("aria-hidden","true");
			$("#"+tabpanid).attr("aria-hidden","false");
		}
	} else if (ev.which ==37) {
		if ($(this).prev().length) {
			$("li[role='tab']").attr("aria-selected","false"); // deselect all tabs
			$("div[role='tabpanel']").attr("aria-hidden","true"); // hide all panels
			$(this).attr("aria-selected","false").prev().attr("aria-selected","true").focus();
			var tabpanid= $("li[aria-selected='true']").attr("aria-controls");
			$("div[role='tabpanel']").attr("aria-hidden","true");
			$("#"+tabpanid).attr("aria-hidden","false");
		}
	}
});