Toggle menu

Tabs

Tabs are designed to organise content into easily navigable sections, letting users switch between them without leaving the page.

Tab components make it easy to organise content into separate sections while keeping the interface clean and user-friendly. They let users quickly switch between content areas without navigating away from the page. Additionally, tabs can include labels that clearly describe each section, providing users with an efficient way to access the information.

When to use Tabs

Tabs are best used when you need to organise related content into distinct sections within the same page. They are ideal for scenarios where displaying all the content at once would overwhelm a user, such as product details, settings panels, or content categories. Tabs work well when users need quick access to multiple sections without excessive scrolling or page reloading.

Examples in GOSS products

  • The Panel template and Impact theme tabs layout panel.
  • The Chill theme's homepage
  • The Chill theme's mobile menu
  • The Cruise theme's homepage Services block

 

Accessibility considerations

Accessibility is key to making tabs usable for everyone, including those using assistive technologies. Proper roles like tablist, tab, and tabpanel help screen readers understand the structure and link tabs to their corresponding content, creating a smoother experience.

Tabs should also support easy keyboard navigation. Users should be able to move between tabs with arrow keys and activate them with Enter or Space. Focus should shift logically to the content, so navigating without a mouse is simple and intuitive.

Visible focus indicators and logical tab order are also essential. Clear focus states help users know which tab is selected, while a predictable tab sequence ensures smooth navigation.

Basic tabs

A basic tabs component with the minimum required attributes of var, items, and aria-label, plus the recommended id is set.

The default behaviour of the tabs panel is to display the first item as open.

Tabs panels should always include a collection of items in the items attribute, along with a var attribute to reference each item during iteration. For example, you might use a list of related articles to show five items in a panel.

It's also important to include an aria-label. This ensures screen readers can label the tabs panel clearly, making it easier for everyone to navigate and understand the content.

First item Second item Third item
First item text content
Second item text content
Third item text content
HTML Java .NET
<div id="c_24796689281241" class="gi-tabs gi-tabs--nojs">
	<div role="tablist" aria-label="A tabs panel of three simple items" class="gi-tabs__tablist">
		<button id="c_24796689281241_item0_tab" role="tab" aria-selected="true" aria-controls="c_24796689281241_item0" class="gi-tabs__tab" hidden="">First item</button>
		<a href="#c_24796689281241_item0" class="gi-tabs__fallback">First item</a>
		<button id="c_24796689281241_item1_tab" role="tab" aria-selected="false" aria-controls="c_24796689281241_item1" class="gi-tabs__tab" hidden="" tabindex="-1">Second item</button>
		<a href="#c_24796689281241_item1" class="gi-tabs__fallback">Second item</a>
		<button id="c_24796689281241_item2_tab" role="tab" aria-selected="false" aria-controls="c_24796689281241_item2" class="gi-tabs__tab" hidden="" tabindex="-1">Third item</button>
		<a href="#c_24796689281241_item2" class="gi-tabs__fallback">Third item</a>
	</div>
	<div tabindex="0" role="tabpanel" id="c_24796689281241_item0" aria-labelledby="c_24796689281241_item0_tab" class="gi-tabs__panel">First item text content</div>
	<div tabindex="0" role="tabpanel" id="c_24796689281241_item1" aria-labelledby="c_24796689281241_item1_tab" class="gi-tabs__panel">Second item text content</div>
	<div tabindex="0" role="tabpanel" id="c_24796689281241_item2" aria-labelledby="c_24796689281241_item2_tab" class="gi-tabs__panel">Third item text content</div>
</div>
<script>
	gi.tabs.initialiseTabs("c_24796689281241", false, 0);
</script>
<comp:tabs var="tabItem" items="#{article.relatedArticles.visible}" ariaLabel="Related articles">
	<ui:define name="tabbutton">#{tabItem.articleHeading}</ui:define>
	<ui:define name="tabpanel">#{tabItem.articleSummary}</ui:define>
</comp:tabs>
@{
	Func<string> getUrl = () => "";
	var tabsModel = new TabsModel()
			{
				Tabs = Model.Model.ThreeSimpleArticles.Select(x => new TabModel
				{
					RenderButton = () => RenderTabButton(x),
					RenderPanel = () => RenderTabPanel(x),
					TabModifiers = new string[] { },
					PanelModifiers = new string[] { }

				}).ToList(),
				Id = "",
				AriaLabel = "Related articles",
				GetUrl = getUrl,
				Closed = false,
				Modifiers = new string[] { },
			};
}
@helper RenderTabButton(Article article){
@article.ArticleHeading
}

@helper RenderTabPanel(Article article){
@article.ArticleSummary
}

@{
	Html.Tabs(tabsModel);
}

Closed tabs

A tabs component with the closed attribute set to true.

gi.tabs.initialiseTabs("tabdemo2", true);

This attribute overrides the default behaviour, starting all tabs in a closed state. This allows tabs to be toggled, enabling users to return to the panel's initial state if needed.

First item Second item Third item
First item text content
Second item text content
Third item text content
HTML Java .NET
<div id="c_25427534635485" class="gi-tabs gi-tabs--nojs">
	<div role="tablist" aria-label="A tabs panel of three simple items" class="gi-tabs__tablist">
		<button id="c_25427534635485_item0_tab" role="tab" aria-selected="true" aria-controls="c_25427534635485_item0" class="gi-tabs__tab" hidden="">First item</button>
		<a href="#c_25427534635485_item0" class="gi-tabs__fallback">First item</a>
		<button id="c_25427534635485_item1_tab" role="tab" aria-selected="false" aria-controls="c_25427534635485_item1" class="gi-tabs__tab" hidden="" tabindex="-1">Second item</button>
		<a href="#c_25427534635485_item1" class="gi-tabs__fallback">Second item</a>
		<button id="c_25427534635485_item2_tab" role="tab" aria-selected="false" aria-controls="c_25427534635485_item2" class="gi-tabs__tab" hidden="" tabindex="-1">Third item</button>
		<a href="#c_25427534635485_item2" class="gi-tabs__fallback">Third item</a>
	</div>
	<div tabindex="0" role="tabpanel" id="c_25427534635485_item0" aria-labelledby="c_25427534635485_item0_tab" class="gi-tabs__panel">First item text content</div>
	<div tabindex="0" role="tabpanel" id="c_25427534635485_item1" aria-labelledby="c_25427534635485_item1_tab" class="gi-tabs__panel">Second item text content</div>
	<div tabindex="0" role="tabpanel" id="c_25427534635485_item2" aria-labelledby="c_25427534635485_item2_tab" class="gi-tabs__panel">Third item text content</div>
</div>
<script>
	gi.tabs.initialiseTabs("c_25427534635485", true, 0);
</script>
<comp:tabs var="tabItem" items="#{article.relatedArticles.visible}" ariaLabel="Related articles" closed="true">
	<ui:define name="tabbutton">#{tabItem.articleHeading}</ui:define>
	<ui:define name="tabpanel">#{tabItem.articleSummary}</ui:define>
</comp:tabs>
@{
	Func<string> getUrl = () => "";
	var tabsModel = new TabsModel()
			{
				Tabs = Model.Model.ThreeSimpleArticles.Select(x => new TabModel
				{
					RenderButton = () => RenderTabButton(x),
					RenderPanel = () => RenderTabPanel(x),
					TabModifiers = new string[] { },
					PanelModifiers = new string[] { }

				}).ToList(),
				Id = "",
				AriaLabel = "Related articles",
				GetUrl = getUrl,
				Closed = true,
				Modifiers = new string[] { },
			};
}
@helper RenderTabButton(Article article){
@article.ArticleHeading
}

@helper RenderTabPanel(Article article){
@article.ArticleSummary
}

@{
	Html.Tabs(tabsModel);
}

Starting tab index

This attribute overrides the tabs default behaviour of starting with the first item open.

First item Second item Third item
First item text content
Second item text content
Third item text content
HTML Java .NET
<div id="c_25553595471278" class="gi-tabs gi-tabs--nojs">
	<div role="tablist" aria-label="A tabs panel of three simple items" class="gi-tabs__tablist">
		<button id="c_25553595471278_item0_tab" role="tab" aria-selected="false" aria-controls="c_25553595471278_item0" class="gi-tabs__tab" hidden="" tabindex="-1">First item</button>
		<a href="#c_25553595471278_item0" class="gi-tabs__fallback">First item</a>
		<button id="c_25553595471278_item1_tab" role="tab" aria-selected="true" aria-controls="c_25553595471278_item1" class="gi-tabs__tab" hidden="">Second item</button>
		<a href="#c_25553595471278_item1" class="gi-tabs__fallback">Second item</a>
		<button id="c_25553595471278_item2_tab" role="tab" aria-selected="false" aria-controls="c_25553595471278_item2" class="gi-tabs__tab" hidden="" tabindex="-1">Third item</button>
		<a href="#c_25553595471278_item2" class="gi-tabs__fallback">Third item</a>
	</div>
	<div tabindex="0" role="tabpanel" id="c_25553595471278_item0" aria-labelledby="c_25553595471278_item0_tab" class="gi-tabs__panel">First item text content</div>
	<div tabindex="0" role="tabpanel" id="c_25553595471278_item1" aria-labelledby="c_25553595471278_item1_tab" class="gi-tabs__panel">Second item text content</div>
	<div tabindex="0" role="tabpanel" id="c_25553595471278_item2" aria-labelledby="c_25553595471278_item2_tab" class="gi-tabs__panel">Third item text content</div>
</div>
<script>
	gi.tabs.initialiseTabs("c_25553595471278", false, 1);
</script>
<comp:tabs var="tabItem" items="#{article.relatedArticles.visible}" ariaLabel="Related articles" startingTabIndex="1">
	<ui:define name="tabbutton">#{tabItem.articleHeading}</ui:define>
	<ui:define name="tabpanel">#{tabItem.articleSummary}</ui:define>
</comp:tabs>
@{
	Func<string> getUrl = () => "";
	var tabsModel = new TabsModel()
			{
				Tabs = Model.Model.ThreeSimpleArticles.Select(x => new TabModel
				{
					RenderButton = () => RenderTabButton(x),
					RenderPanel = () => RenderTabPanel(x),
					TabModifiers = new string[] { },
					PanelModifiers = new string[] { }

				}).ToList(),
				Id = "",
				AriaLabel = "Related articles",
				GetUrl = getUrl,
				Closed = false,
				Modifiers = new string[] { },
				StartingTabIndex = 1
			};
}
@helper RenderTabButton(Article article){
@article.ArticleHeading
}

@helper RenderTabPanel(Article article){
@article.ArticleSummary
}

@{
	Html.Tabs(tabsModel);
}

Tabs modifiers, tabModifiers and panelModifiers

These attributes allow CSS BEM modifier values to be applied to the whole component, and the tabs and panels separately.

First item Second item Third item
First item text content
Second item text content
Third item text content
HTML Java .NET
<div id="c_1840813702566000" class="gi-tabs gi-tabs--blue gi-tabs--nojs">
	<div role="tablist" aria-label="Related articles" class="gi-tabs__tablist gi-tabs__tablist--blue">
		<button id="c_1840813702566000_item0_tab" role="tab" aria-selected="true" aria-controls="c_1840813702566000_item0" class="gi-tabs__tab gi-tabs__tab--large" hidden="">First item</button>
		<a href="#c_1840813702566000_item0" class="gi-tabs__fallback gi-tabs__fallback--large">First item</a>
		<button id="c_1840813702566000_item1_tab" role="tab" aria-selected="false" aria-controls="c_1840813702566000_item1" class="gi-tabs__tab gi-tabs__tab--large" hidden="" tabindex="-1">Second item</button>
		<a href="#c_1840813702566000_item1" class="gi-tabs__fallback gi-tabs__fallback--large">Second item</a>
		<button id="c_1840813702566000_item2_tab" role="tab" aria-selected="false" aria-controls="c_1840813702566000_item2" class="gi-tabs__tab gi-tabs__tab--large" hidden="" tabindex="-1">Third item</button>
		<a href="#c_1840813702566000_item2" class="gi-tabs__fallback gi-tabs__fallback--large">Third item</a>
	</div>
	<div tabindex="0" role="tabpanel" id="c_1840813702566000_item0" aria-labelledby="c_1840813702566000_item0_tab" class="gi-tabs__panel gi-tabs__panel--rounded">First item text content</div>
	<div tabindex="0" role="tabpanel" id="c_1840813702566000_item1" aria-labelledby="c_1840813702566000_item1_tab" class="gi-tabs__panel gi-tabs__panel--rounded">Second item text content</div>
	<div tabindex="0" role="tabpanel" id="c_1840813702566000_item2" aria-labelledby="c_1840813702566000_item2_tab" class="gi-tabs__panel gi-tabs__panel--rounded">Third item text content</div>
</div>
<script>
	gi.tabs.initialiseTabs("c_1840813702566000", false, 0);
</script>
<comp:tabs var="tabItem" items="#{article.relatedArticles.visible}" ariaLabel="Related articles" modifiers="blue" tabModifiers="large" panelModifiers="rounded">
	<ui:define name="tabbutton">#{tabItem.articleHeading}</ui:define>
	<ui:define name="tabpanel">#{tabItem.articleSummary}</ui:define>
</comp:tabs>
@{
	Func<string> getUrl = () => "";
	var tabsModel = new TabsModel()
			{
				Tabs = Model.Model.ThreeSimpleArticles.Select(x => new TabModel
				{
					RenderButton = () => RenderTabButton(x),
					RenderPanel = () => RenderTabPanel(x),
					TabModifiers = new string[] { "large" },
					PanelModifiers = new string[] { "rounded" }

				}).ToList(),
				Id = "",
				AriaLabel = "Related articles",
				GetUrl = getUrl,
				Closed = false,
				Modifiers = new string[] { "blue" },
			};
}
@helper RenderTabButton(Article article){
@article.ArticleHeading
}

@helper RenderTabPanel(Article article){
@article.ArticleSummary
}

@{
	Html.Tabs(tabsModel);
}

Share this page

Facebook icon Twitter icon email icon

Print

print icon