Tabs
Tabs consist of two or more tab items created for navigating between different sections of content.
Guidelines
When to use tabs
Each tab will display different sections within the same context. For example, tabs can display different sections of an article, different topics or different edit views.
Use Tabs to navigate between different sections of content on the page. For filtering information on the screen or switching between views, use a ToggleButtonGroup instead.
Specifications
The Tabs component always contains two or more Tab items.
Tabs include the following elements:
- Selected tab
Within the tabs component, only one tab item can be selected at a time. - Unselected tabs
The remaining tab items will remain unselected. Users can choose these tabs by clicking on them or navigating to them via the keyboard’s arrow keys. - Arrow button
When tabs become scrollable, one or two icon-only buttons will appear. The number of buttons to scroll tabs will vary based on the tabs' scroll position. Users can utilize these buttons to navigate through the scrollable tabs.
Component limitations
Each Tabs component will contain a minimum of 2 tab items. There is no maximum limit to the number of tab items per Tabs.
The maximum width for each tab item is @size-1600
(equivalent to 256px
in the default Codex theme), with an ellipsis appearing if the text exceeds this length.
When there is not enough space to display all tabs, scrolling will be activated. When the scroll is enabled, the positions of the tabs will be indicated by arrow buttons:
- Initial position: Due to the tabs being in the first position, only the end arrow button will be visible at the end to scroll the tabs.
- Middle position: Both the start and end arrow buttons will be visible.
- End position: As scrolling reaches the end, only the start arrow will be visible in order to scroll the tabs from the end to the beginning.
Refer to the Tabs component in Codex Figma.
Types
Depending on the tabs' style and where they are employed, there are two types of tabs:
Quiet tabs
These tabs feature a transparent background with a Gray400 underline to delineate the tabs base. The selected tab is highlighted in blue with a blue line underneath. These tabs are intended for use on open white backgrounds, and it is not recommended to use them within boxes or modules.
Framed tabs
These tabs have a Gray100 background in light mode, with the selected tab appearing in white. They are designed to be used within boxes or modules, where the gray background serves as a head for the box. It is not recommended to use framed tabs outside of a box context; in such cases, use the quiet tabs instead.
Interaction states
The Tabs component itself does not have distinct states. Instead, individual states will be attributed to each Tab item.
Best practices
Consider the following recommendations when using Tabs.
- Use Tabs to navigate between various sections of related content.
- Use Tabs to structure content meant to be consumed sequentially, like the sections within an article page.
- Use Tabs to navigate between different sections of content on the page.
- Use Tabs to filter information on the screen or switch between views.
Content
Tabs allow a reader to access contained, structured content blocks that make pages easier to read. To make the UI effective and consistent, keep tab names short and descriptive.
- Mix verbs and nouns for the labels. Consistent & Clear
Keyboard navigation
Key | Function |
---|---|
Tab | It moves the focus to the next interactive element in tab order. |
Shift + Tab | It moves the focus to the previous interactive element. |
Left arrow / Right arrow | When focusing on a Tab item, the arrow keys navigate between the rest of Tab items. |
Demos
Basic Example
Two stylistic variants are available, quiet (the default) and framed.
Name | Value |
---|---|
Props | |
framed | |
View | |
Reading direction |
Header row scroll
When the width of the header row exceeds the width of its container, arrow buttons will appear to enable scrolling through tab names.
Content for tab1
This is the content for the First Tab
Name | Value |
---|---|
Props | |
framed | |
View | |
Reading direction |
Dynamic replacement of slot content
The Tabs component will re-render if the provided slot content changes. Clicking the button below will replace the initial tabs with a new set; the header row will update to match.
Content for tab1
This is the content for the First Tab
Vue usage
One or more Tab components must be provided in the default slot of the Tabs component. Each child Tab component must have a name
property. By default, the first tab will be active when the component renders.
Optional 2-way binding of active tab
Optionally, the active tab can be bound in the parent scope using v-model:active
. This is useful in situations where the Tabs need the ability to render with a Tab other than the first in the active state and is recommended if tabs are meant to respond to URL params. The value of v-model:active
should correspond to the name
property of the active tab.
Props
Prop name | Description | Type | Default |
---|---|---|---|
active | The name of the currently active Tab in the layout.This prop is optional; if it is provided, it should be bound using a v-model:active directive in the parent component. Two-way binding the active tab is only necessary if some tab other than the first should be active as soon as the component renders (such as in cases where the active tab is bound to URL params). If this prop is not provided, then the first tab will be active by default. Regardless, the active tab can be changed normally by user interaction (clicking on tab headings) or by using the exposed methods "select", "next", and "prev". | string | null |
framed | Whether or not the component should be displayed in a framed visual style. | boolean | false |
Methods
Method name | Description | Signature |
---|---|---|
select | Programmatically select a tab based on its "name" prop | Params:
void |
next | Set the next tab to active, if one exists | Params:
void |
prev | Set the previous tab to active, if one exists | Params:
void |
Events
Event name | Properties | Description |
---|---|---|
update:active | active string - The name of the current active tab | Emitted whenever the active tab changes, assuming that an active prop has been provided in the parent. |
Slots
Name | Description | Bindings |
---|---|---|
default | One or more Tab components must be provided here |
CSS-only version
Markup structure
The non-JS version of the Tabs component should be seen as a navigational tool. It relies on HTML form submission to trigger a change in the current active tab. When the user clicks on a tab button (or hits Enter while tab button is focused), the browser will load a new page.
Basic setup:
- The outermost element should be a
<div>
element with the class"cdx-tabs"
. - The
cdx-tabs__header
element should be a<form>
with the following attributes:method="get"
: we will send the form with a GET requestaction="myURL"
: The value ofaction
should be whatever URL the form data will be sent to; in this example it's simply the same URL as the page, but appended with a different URL query parameter based on the user's tab selection. In a real-world use-case, this might be a URL that can accept query parameters (say for performing a different kind of search based on which tab the user selects).
- Within the
tablist
element, every tab label is represented by a<button>
element (this is the same as in the Vue version). However, since we are submitting the data as a form, each tab button must contain aname
and avalue
attribute. In a real application, this might correspond to key-value pairs used for a given query parameter. - The tab corresponding to the current view should contain the
aria-selected="true"
attribute. All other tabs should havearia-selected="false"
. If you are using a server-side templating language like Mustache, this should be set there. - Each tab should also have an
aria-controls
attribute with a value of the ID of the correspondingtabpanel
. - Don't mess with
<button>
tabindex
– since the CSS-only version of this component has no way to bind left and right arrow keys to handler methods, the user is going to need to rely on the mouse or the tab key to navigate between tabs. - To disable a tab, simply add a
disabled
attribute to that tab's<button>
in the tablist.
The tabs below have long labels, making the tab list too long for its container. When this happens, you can horizontally scroll to reach the rest of the tabs list.
WARNING
Keyboard navigation between tabs can only be done via the Tab key. Arrow keys will not work here.