Tabbed Content
Very simple solution for creating tabbed content. Not much more to say…
HTML
<div class="tabs" data-tabs-id="1">
<div class="tabs__nav" role="tablist" aria-label="Content description goes here">
<button class="tabs__btn | tabs__btn--active" role="tab" aria-selected="true" aria-controls="tab-panel-1" id="tab-1">Tab A</button>
<span class="tabs__separator" aria-hidden="true"></span>
<button class="tabs__btn" role="tab" aria-selected="false" aria-controls="tab-panel-2" id="tab-2">Tab B</button>
</div>
<div class="tabs__panel tabs__panel--active" role="tabpanel" id="tab-panel-1" aria-labelledby="tab-1">
<div class="tabs__panel__img">
<img src="https://images.unsplash.com/photo-1625602812206-5ec545ca1231?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=1740" width="1000" alt="">
</div>
</div>
<div class="tabs__panel" role="tabpanel" id="tab-panel-2" aria-labelledby="tab-2">
<div class="tabs__panel__img">
<img src="https://plus.unsplash.com/premium_photo-1686231456293-65507f75a48a?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=1740" width="1000" alt="">
</div>
</div>
</div>
CSS
// ***********************************
// Reset
// ***********************************
body {
margin-top: 4rem;
}
img {
width: 100%;
}
// ***********************************
// Tabs
// ***********************************
.tabs {
margin-inline: auto;
width: min(1200px, 100%);
}
// ***********************************
// Tabs - Nav
// ***********************************
.tabs__nav {
display: flex;
}
// ***********************************
// Tabs - Buttons
// ***********************************
.tabs__btn {
background-color: #0A6281;
border: 1px solid #0A6281;
border-bottom: none;
border-top-left-radius: 1rem;
border-top-right-radius: 1rem;
color: #fff;
cursor: pointer;
flex-grow: 1;
font-size: clamp(1rem, 2vw, 1.25rem);
font-weight: 700;
padding-block: clamp(0.5rem, 2vw, 1rem);
padding-inline: 0.5rem;
}
.tabs__btn--active {
background-color: #fff;
color: #000;
border-color: #B5B5B5;
}
.tabs__separator {
align-self: end;
background-color: #B5B5B5;
display: block;
height: 1px;
width: clamp(0.75rem, 2vw, 1.25rem);
}
// ***********************************
// Tabs - Panels
// ***********************************
.tabs__panel {
display: none;
}
.tabs__panel--active {
display: block;
}
.tabs__panel {
background-color: #fff;
border: 1px solid #B5B5B5;
border-bottom-left-radius: 1rem;
border-bottom-right-radius: 1rem;
border-top: none;
padding-block: clamp(1rem, 4vw, 3.125rem);
padding-inline: clamp(1rem, 4vw, 3.5rem);
}
.tabs__panel__img {
img {
border: 1px solid #B5B5B5;
margin-inline: auto;
}
}
JavaScript
const tabs= () => {
document.addEventListener('DOMContentLoaded', function () {
const tabsContainers = document.querySelectorAll('.tabs[data-tabs-id]');
tabsContainers.forEach(tabsContainer => {
const tabButtons = tabsContainer.querySelectorAll('.tabs__btn');
const tabPanels = tabsContainer.querySelectorAll('.tabs__panel');
tabButtons.forEach(button => {
button.addEventListener('click', () => {
// Deactivate all buttons and panels within this tabs instance
tabButtons.forEach(btn => {
btn.classList.remove('tabs__btn--active');
btn.setAttribute('aria-selected', 'false');
});
tabPanels.forEach(panel => {
panel.classList.remove('tabs__panel--active');
});
// Activate the clicked button
button.classList.add('tabs__btn--active');
button.setAttribute('aria-selected', 'true');
// Activate the corresponding panel (scoped to this tabs instance)
const panelId = button.getAttribute('aria-controls');
const panel = tabsContainer.querySelector(`#${panelId}`);
if (panel) {
panel.classList.add('tabs__panel--active');
}
});
});
});
});
}
tabs();