Tab interface component styles, for aria based tab interface
Demos
Horizontal Tabs
A standard tabbed interface with labels positioned horizontally above the content.
This is the general information about the product or service. It covers the core value propositions and high-level features.
Technical specifications and detailed measurements are listed here for professional review.
Customer feedback and ratings provide real-world insights from our community of users.
<div class="tabs">
<div role="tablist" data-ulu-tablist='{ "equalHeights": true }'>
<button role="tab" id="tab-1" aria-selected="true" aria-controls="panel-1">General Info</button>
<button role="tab" id="tab-2" aria-selected="false" aria-controls="panel-2">Specifications</button>
<button role="tab" id="tab-3" aria-selected="false" aria-controls="panel-3">Reviews</button>
</div>
<div role="tabpanel" id="panel-1" aria-labelledby="tab-1">
<p>This is the general information about the product or service. It covers the core value propositions and high-level features.</p>
</div>
<div role="tabpanel" id="panel-2" aria-labelledby="tab-2" hidden>
<p>Technical specifications and detailed measurements are listed here for professional review.</p>
</div>
<div role="tabpanel" id="panel-3" aria-labelledby="tab-3" hidden>
<p>Customer feedback and ratings provide real-world insights from our community of users.</p>
</div>
</div>Vertical Tabs
Using the `tabs--vertical` modifier to place tab labels in a sidebar layout on larger screens.
Manage your personal information, profile picture, and contact details.
Control who can see your activity and how your data is used across the platform.
Customize which alerts you receive via email, push notification, or SMS.
<div class="tabs tabs--vertical">
<div role="tablist" data-ulu-tablist='{ "vertical": true, "equalHeights": true }'>
<button role="tab" id="v-tab-1" aria-selected="true" aria-controls="v-panel-1">Account Profile</button>
<button role="tab" id="v-tab-2" aria-selected="false" aria-controls="v-panel-2">Privacy Settings</button>
<button role="tab" id="v-tab-3" aria-selected="false" aria-controls="v-panel-3">Notification Preferences</button>
</div>
<div role="tabpanel" id="v-panel-1" aria-labelledby="v-tab-1">
<p>Manage your personal information, profile picture, and contact details.</p>
</div>
<div role="tabpanel" id="v-panel-2" aria-labelledby="v-tab-2" hidden>
<p>Control who can see your activity and how your data is used across the platform.</p>
</div>
<div role="tabpanel" id="v-panel-3" aria-labelledby="v-tab-3" hidden>
<p>Customize which alerts you receive via email, push notification, or SMS.</p>
</div>
</div>Sticky Horizontal Tabs
Using the `tabs--sticky` modifier to keep the horizontal tab labels visible at the top of the viewport when scrolling through long panel content.
Scroll down to see the sticky behavior.
This is section 2 content.
This is section 3 content.
<div class="tabs tabs--sticky">
<div role="tablist" data-ulu-tablist='{ "equalHeights": false }'>
<button role="tab" id="sh-tab-1" aria-selected="true" aria-controls="sh-panel-1">Section 1</button>
<button role="tab" id="sh-tab-2" aria-selected="false" aria-controls="sh-panel-2">Section 2</button>
<button role="tab" id="sh-tab-3" aria-selected="false" aria-controls="sh-panel-3">Section 3</button>
</div>
<div role="tabpanel" id="sh-panel-1" aria-labelledby="sh-tab-1">
<p>Scroll down to see the sticky behavior.</p>
<div style="height: 400px; background-image: repeating-linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc), repeating-linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc); background-position: 0 0, 10px 10px; background-size: 20px 20px; opacity: 0.1; margin-top: 1rem;"></div>
</div>
<div role="tabpanel" id="sh-panel-2" aria-labelledby="sh-tab-2" hidden>
<p>This is section 2 content.</p>
<div style="height: 400px; background-image: repeating-linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc), repeating-linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc); background-position: 0 0, 10px 10px; background-size: 20px 20px; opacity: 0.1; margin-top: 1rem;"></div>
</div>
<div role="tabpanel" id="sh-panel-3" aria-labelledby="sh-tab-3" hidden>
<p>This is section 3 content.</p>
</div>
</div>Sticky Vertical Tabs
Using both `tabs--vertical` and `tabs--sticky` modifiers. On large screens, the tab labels stick within their grid column as you scroll the adjacent panel. On smaller screens, they behave like sticky horizontal tabs.
Scroll down to see the vertical tablist stick to the top.
This is chapter 2 content.
This is chapter 3 content.
<div class="tabs tabs--vertical tabs--sticky">
<div role="tablist" data-ulu-tablist='{ "vertical": true, "equalHeights": false }'>
<button role="tab" id="sv-tab-1" aria-selected="true" aria-controls="sv-panel-1">Chapter 1</button>
<button role="tab" id="sv-tab-2" aria-selected="false" aria-controls="sv-panel-2">Chapter 2</button>
<button role="tab" id="sv-tab-3" aria-selected="false" aria-controls="sv-panel-3">Chapter 3</button>
</div>
<div role="tabpanel" id="sv-panel-1" aria-labelledby="sv-tab-1">
<p>Scroll down to see the vertical tablist stick to the top.</p>
<div style="height: 400px; background-image: repeating-linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc), repeating-linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc); background-position: 0 0, 10px 10px; background-size: 20px 20px; opacity: 0.1; margin-top: 1rem;"></div>
</div>
<div role="tabpanel" id="sv-panel-2" aria-labelledby="sv-tab-2" hidden>
<p>This is chapter 2 content.</p>
<div style="height: 400px; background-image: repeating-linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc), repeating-linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc); background-position: 0 0, 10px 10px; background-size: 20px 20px; opacity: 0.1; margin-top: 1rem;"></div>
</div>
<div role="tabpanel" id="sv-panel-3" aria-labelledby="sv-tab-3" hidden>
<p>This is chapter 3 content.</p>
</div>
</div>Variables
$config
Module Settings
$config: (
"margin" : (2rem 0),
"print-margin" : 1.5em,
"tablist-divider" : true,
"tablist-divider-width" : 1px,
"indicator-size" : 3px,
"indicator-color" : "selected",
"indicator-transition-duration" : 200ms,
"indicator-transition-timing" : ease-out,
"indicator-scale-start" : 0,
"tab-color" : "type-tertiary",
"tab-color-hover" : "type",
"tab-color-focus": null,
"tab-background-color-focus": "selected-background",
"tab-hide-native-focus": true,
"tab-color-selected" : "type",
"tab-background-color-selected" : null,
"tab-font-weight" : true,
"tab-padding" : (0.75em),
"tab-gap" : 1em,
"tabpanel-background-color" : #f6f6f6,
"tabpanel-padding" : (2rem),
"vertical-tablist-width" : minmax(15rem, 30%),
"vertical-tab-padding" : (0.25em 0.75em),
"vertical-divider-width" : 0px,
"vertical-tab-gap" : 0.75em,
"vertical-indicator-left" : true,
"vertical-breakpoint" : true,
"horizontal-tab-wrap" : false,
"full-width-tablist-background-color" : null,
"full-width-tabpanel-background-color" : transparent,
"sticky-top" : cssvar.use-ulu("sticky-offset-top"),
"sticky-vertical-top" : cssvar.add(cssvar.use-ulu("sticky-offset-top"), 1em),
"sticky-background-color" : "background",
"sticky-z-index" : 2,
);
File Information
- File: _tabs.scss
- Group: tabs
- Type: variable
- Lines (comments): 34-68
- Lines (code): 70-105
Map Properties
| Name | Type | Default | Description |
|---|---|---|---|
| margin | Dimension | (2rem, 0) | The margin for the tabs container |
| print-margin | Dimension | 1.5em | Margin between tabs when stacked for print |
| tablist-divider | CssValue | true | The border separating the tabs from the panels. By default (true) will use element rule light style |
| tablist-divider-width | Dimension | 1px | The width of the divider |
| tabpanel-background-color | Color | rgb(245, 245, 245) | The tabpanel background color. |
| tabpanel-padding | Dimension | (2rem,) | Padding for the tabpanel |
| indicator-size | Dimension | 0.25em | The size of the tab's active border/indicator |
| indicator-color | Color | currentColor | The color of the indicator |
| indicator-transition-duration | Color | 200ms | The transition duration for indicator |
| indicator-scale-start | Color | 0 | The starting scale for the indicator (set to 1 to disable expanding on click) |
| tab-color | Color | link | The type color for the tabs. This uses color.scss, so the value of this options should be a variable from color.scss. |
| tab-color-hover | Color | link-hover | The type color for the tabs when hovered. This uses color.scss, so the value of this options should be a variable from color.scss. |
| tab-color-focus | Color | null | null |
| tab-background-color-focus | Color | #eeeeee | The background color for a tab when it has keyboard focus. |
| tab-hide-native-focus | Boolean | true | Hides the default browser outline on focused tabs. |
| tab-color-selected | Color | selected | The tab type color when selected. This uses color.scss, so the value of this options should be a variable from color.scss. |
| tab-background-color-selected | Color | null | The tab background color when selected |
| tab-font-weight | CssValue | true | The font weight for the tab, defaults to typography "font-weight-semibold" |
| tab-padding | Dimension | 0.75em 0.1em 0.75em 0.1em | Padding for the tab |
| tab-gap | Dimension | 1em | Gap between tabs |
| vertical-tablist-width | Dimension | minmax(15rem, 30%), | The width of the tablist column when tabs are layout is vertical |
| vertical-tab-padding | Dimension | (0.25em 0.75em) | Tab padding when vertical |
| vertical-divider-width | Dimension | 0px | Divider between tabs and panels when vertical |
| vertical-tab-gap | Dimension | 0.75em | The gap between tabs when vertical |
| vertical-indicator-left | Boolean | true | The indicator for selected tab should be on the left when vertical (false will be on right/inside) |
| vertical-breakpoint | Boolean | true | Set the breakpoint when the vertical tabs should switch to horizontal (defaults to breakpoint 'default') |
| horizontal-tab-wrap | Boolean | false | Set to true to allow line wrapping when the tabs are in horizontal orientation, vertical is always allowed to wrap |
| full-width-tablist-background-color | Color | null | Optional background color for full-width tabs tablist |
| full-width-tabpanel-background-color | Color | transparent | Optional background color for full-width tabs tabpanel |
| sticky-top | Dimension | cssvar.use-ulu("sticky-offset-top") | The top offset when the sticky modifier is applied |
| sticky-vertical-top | Dimension | cssvar.add(cssvar.use-ulu("sticky-offset-top"), 1em) | The top offset when the sticky modifier is applied in vertical layout |
| sticky-background-color | Color | background | The background color for the tablist when sticky |
| sticky-z-index | Number | 2 | The z-index for the tablist when sticky |
Mixins
set()
Change modules $config
File Information
- File: _tabs.scss
- Group: tabs
- Type: mixin
- Lines (comments): 107-110
- Lines (code): 112-114
Examples
@include ulu.component-tabs-set(( "property" : value ));
Parameters
| Name | Type | Description |
|---|---|---|
| $changes | Map |
Map of changes |
Require
styles()
Output component stylesheet
File Information
- File: _tabs.scss
- Group: tabs
- Type: mixin
- Lines (comments): 126-128
- Lines (code): 130-307
Examples
@include ulu.component-tabs-styles();
Require
Functions
get()
Get a config option
File Information
- File: _tabs.scss
- Group: tabs
- Type: function
- Lines (comments): 116-119
- Lines (code): 121-124
Examples
@include ulu.component-tabs-get("property");
Parameters
| Name | Type | Description |
|---|---|---|
| $name | Map |
Name of property |