<div class="min-h-screen flex items-center justify-center p-4">
<div class="w-full max-w-2xl" style="display: flex;flex-direction: column;justify-content: flex-start;align-items: flex-start">
<div class="tabs-container">
<div class="tabs-nav" role="tablist">
<button class="tab-button active" role="tab" aria-controls="panel-1" data-tab="1">
Aperçu
</button>
<button class="tab-button" role="tab" aria-controls="panel-2" data-tab="2">
Détails
</button>
<button class="tab-button" role="tab" aria-controls="panel-3" data-tab="3">
Paramètres
</button>
</div>
<section class="tab-panel active" id="panel-1" role="tabpanel" aria-labelledby="tab-1">
<div class="p-8">
<h2 class="text-2xl font-semibold text-slate-900 mb-4">Aperçu</h2>
<p class="text-slate-600 leading-relaxed">
Ceci est un système d'onglets épuré et minimaliste.
Chaque onglet contient un contenu unique avec une transition fluide. coucou
</p>
</div>
</section>
<section class="tab-panel" id="panel-2" role="tabpanel" aria-labelledby="tab-2">
<div class="p-8">
<h2 class="text-2xl font-semibold text-slate-900 mb-4">Détails</h2>
<p class="text-slate-600 leading-relaxed">
Cette section contient des informations détaillées sur le système.
Les onglets sont accessibles et respectent les standards WCAG.
</p>
</div>
</section>
<section class="tab-panel" id="panel-3" role="tabpanel" aria-labelledby="tab-3">
<div class="p-8">
<h2 class="text-2xl font-semibold text-slate-900 mb-4">Paramètres</h2>
<p class="text-slate-600 leading-relaxed">
Les paramètres de ce système sont facilement configurables via le fichier SCSS.
Modifiez les couleurs et les fontes selon vos besoins.
</p>
</div>
</section>
</div>
</div>
</div>
$color-primary: #1e293b;
$color-primary-hover: #0f172a;
$color-border: #e2e8f0;
$color-text: #475569;
$color-bg: #ffffff;
$font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif;
$font-size-base: 16px;
$font-weight-regular: 400;
$font-weight-semibold: 600;
.tabs-container {
background-color: $color-bg;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.tabs-nav {
display: flex;
border-bottom: 1px solid $color-border;
}
.tab-button {
position: relative;
margin: 0;
padding: 16px 24px;
width: auto;
height: auto;
font-family: $font-family;
font-size: $font-size-base;
font-weight: $font-weight-regular;
color: $color-text;
background-color: transparent;
border: none;
cursor: pointer;
transition: all 0.3s ease;
&:hover:not(.active) {
color: $color-primary;
background-color: rgba(30, 41, 59, 0.05);
}
&.active {
color: $color-primary;
font-weight: $font-weight-semibold;
&::after {
content: '';
position: absolute;
bottom: -1px;
left: 0;
width: 100%;
height: 2px;
background-color: $color-primary;
}
}
}
.tab-panel {
display: none;
opacity: 0;
animation: fadeOut 0.2s ease;
&.active {
display: block;
opacity: 1;
animation: fadeIn 0.3s ease;
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@media (max-width: 640px) {
.tabs-nav {
flex-wrap: wrap;
}
.tab-button {
padding: 12px 16px;
font-size: 14px;
flex: 1 1 auto;
text-align: center;
}
.tab-panel {
padding: 16px;
}
}
class TabSystem {
constructor(containerSelector = '.tabs-container') {
this.container = document.querySelector(containerSelector);
this.buttons = this.container.querySelectorAll('.tab-button');
this.panels = this.container.querySelectorAll('.tab-panel');
this.init();
}
init() {
this.buttons.forEach(button => {
button.addEventListener('click', () => this.selectTab(button));
button.addEventListener('keydown', (e) => this.handleKeyboard(e, button));
});
}
selectTab(button) {
const tabId = button.getAttribute('data-tab');
this.buttons.forEach(btn => {
btn.classList.remove('active');
btn.setAttribute('aria-selected', 'false');
});
this.panels.forEach(panel => {
panel.classList.remove('active');
});
button.classList.add('active');
button.setAttribute('aria-selected', 'true');
const activePanel = this.container.querySelector(`#panel-${tabId}`);
if (activePanel) {
activePanel.classList.add('active');
}
}
handleKeyboard(e, button) {
const buttons = Array.from(this.buttons);
const currentIndex = buttons.indexOf(button);
if (e.key === 'ArrowRight') {
e.preventDefault();
const nextIndex = (currentIndex + 1) % buttons.length;
this.selectTab(buttons[nextIndex]);
} else if (e.key === 'ArrowLeft') {
e.preventDefault();
const prevIndex = (currentIndex - 1 + buttons.length) % buttons.length;
this.selectTab(buttons[prevIndex]);
} else if (e.key === 'Home') {
e.preventDefault();
this.selectTab(buttons[0]);
} else if (e.key === 'End') {
e.preventDefault();
this.selectTab(buttons[buttons.length - 1]);
}
}
}
document.addEventListener('DOMContentLoaded', () => {
new TabSystem('.tabs-container');
});