Tab
The Tab component allows users to organize content into multiple panels, each accessible by clicking on a tab label. It supports both horizontal and vertical layouts, and provides a clean way to display related content in a compact space.
Description #
The Tab component is an interactive element that allows users to switch between multiple content panels within the same area. It now supports dynamic positioning using the data-tab-list-position attribute, giving developers full control over where the tab labels appear.
-
data-tab-list-position="top" – Tab labels appear above the content (default).
-
data-tab-list-position="bottom" – Tab labels appear below the content.
-
data-tab-list-position="left" – Tab labels appear on the left side of the content.
-
data-tab-list-position="right" – Tab labels appear on the right side of the content.
The active tab displays its corresponding content while hiding others. Tabs help organize related content, reduce clutter, and improve user experience by providing a clean and intuitive way to navigate between sections.
Examples and Classes #
Basic Tab
Photo
Music
Video
Tab 1 content
Tab 2 content
Tab 3 content
<div class="tab">
<div class="tab-list ">
<div class="tab-label active">Photo</div>
<div class="tab-label">Music</div>
<div class="tab-label">Video</div>
</div>
<div class="tab-contents">
<div class="tab-content active">Tab 1 content</div>
<div class="tab-content">Tab 2 content</div>
<div class="tab-content">Tab 3 content</div>
</div>
</div>
Tab with position
Photo
Music
Video
Tab 1 content
Tab 2 content
Tab 3 content
<div class="tab" data-tab-list-position="left">
<div class="tab-list ">
<div class="tab-label active">Photo</div>
<div class="tab-label">Music</div>
<div class="tab-label">Video</div>
</div>
<div class="tab-contents">
<div class="tab-content active">Tab 1 content</div>
<div class="tab-content">Tab 2 content</div>
<div class="tab-content">Tab 3 content</div>
</div>
</div>
Tab with slider
<div class="tab tab-list-slider" data-tab-list-position="bottom">
<div class="tab-list ">
<div class="tab-label active">Photo</div>
<div class="tab-label">Music</div>
<div class="tab-label">Video</div>
</div>
<div class="tab-contents">
<div class="tab-content active">Tab 1 content</div>
<div class="tab-content">Tab 2 content</div>
<div class="tab-content">Tab 3 content</div>
</div>
</div>
Available Classes
| Class | Description |
|---|---|
| .tab | Main wrapper for the tab component. Controls the layout and spacing of tab labels and content panels. |
| .tab-list-slider | If you want have actived with animation you give this class to tab and style it with $tab-list-slider sass variable |
| .tab-list | Container for tab labels. Can be arranged in a row or column for horizontal or vertical tabs. |
| .tab-label | Individual tab label. Clicking switches the visible content panel. .active highlights the selected tab. |
| .tab-contents | Wrapper for all tab content panels. Only the active panel is shown. |
| .tab-content | Individual content panel for each tab. .active makes the panel visible. |
| .active | Applied to the selected tab label and visible content panel. |
Layout Variations
The Tab component supports flexible layout variations using the
data-tab-list-position attribute, allowing you to control the position of the tab labels.
- data-tab-list-position="top" : Tab labels appear above the content (default layout)
- data-tab-list-position="bottom" : Tab labels appear below the content
- data-tab-list-position="left" : Tab labels appear on the left side of the content
- data-tab-list-position="right" : Tab labels appear on the right side of the content
- Multiple Tab Groups: You can include multiple independent tab containers on the same page
File Locations #
| File | Path | Description |
|---|---|---|
| index.html | miz/themes/mizoon/components/tab/index.html | Example implementation and documentation |
| _index.scss | miz/themes/mizoon/components/tab/_index.scss | SCSS styles and variables |
| script.js | miz/themes/mizoon/components/tab/script.js | JavaScript functionality |
SCSS Variables #
$tab-custom-classes : ".gap-2";
$tab-list: ".bg-tab-list-color, .text-color, .w-fit-content, .radius-all-normal, .py-1, .px-1, .gap-1";
$tab-label: ".p-1, .radius-all-small, .z-index-2";
$tab-list-slider : ".bg-on-secondary-color, .h-70, .w-80";
$tab-label-transition: 0.2s linear;
$tab-label-hover-custom-classes: ".opacity-5";
$tab-label-active-custom-classes: ".title-text-color";
$tab-contents: ".w-100, .bg-on-secondary-color, .py-3, .px-2, .radius-all-medium";
$tab-content: ".w-100, .py-3, .px-2, .title-text-color";
$tab-content-active: ".bg-on-primary";
JavaScript Implementation #
Class Structure
| Method/Property | Type | Description |
|---|---|---|
| tabContainers | Property | NodeList of all tab-container elements |
| tabLabels | Property | NodeList of all tab-label elements within a container |
| tabContents | Property | NodeList of all tab-content elements within a container |
| Event: click | Event | Switches the active tab and content panel on click |
Implementation Example
document.addEventListener('DOMContentLoaded', () => {
const tabContainers = document.querySelectorAll('.tab');
tabContainers.forEach(container => {
const tabList = container.querySelector('.tab-list');
const labels = container.querySelectorAll('.tab-label');
const contents = container.querySelectorAll('.tab-content');
// Set layout based on data-tab-list-position
const position = container.getAttribute('data-tab-list-position');
if (position === 'bottom' || position === 'top' ) {
container.style.flexDirection = 'column';
} else if (position === 'left' || position === 'right') {
container.style.flexDirection = 'row';
tabList.style.flexDirection = 'column';
}
// Create slider if needed
if (container.classList.contains('tab-list-slider')) {
let slider = tabList.querySelector('.tab-slider');
if (!slider) {
slider = document.createElement('div');
slider.classList.add('tab-slider');
tabList.appendChild(slider);
}
}
const slider = tabList.querySelector('.tab-slider');
function moveSlider(activeLabel) {
if (!slider) return;
const rect = activeLabel.getBoundingClientRect();
const parentRect = activeLabel.parentElement.getBoundingClientRect();
if (position === 'left' || position === 'right') {
const height = rect.height;
const top = rect.top - parentRect.top;
slider.style.height = `${height}px`;
slider.style.transform = `translateY(${top}px) translateX(-50%)`;
slider.style.left = `50%`;
slider.style.top = `0%`;
} else {
const width = rect.width;
const left = rect.left - parentRect.left;
slider.style.width = `${width}px`;
slider.style.transform = `translateX(${left}px) translateY(-50%)`;
slider.style.top = `50%`;
slider.style.left = `0%`;
}
}
labels.forEach((label, idx) => {
label.addEventListener('click', () => {
labels.forEach(l => l.classList.remove('active'));
contents.forEach(c => c.classList.remove('active'));
label.classList.add('active');
contents[idx].classList.add('active');
moveSlider(label);
});
});
const activeLabel = container.querySelector('.tab-label.active');
if (activeLabel) moveSlider(activeLabel);
});
});
Include the MIZCHIN JavaScript file in your page.