Widget:Tabber
<!DOCTYPE html> <html lang="pt-BR"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Componente de Abas - MediaWiki</title>
<style>
/* Container principal responsivo */
.mw-tabber-container {
width: 100%;
max-width: 100%;
margin: 20px 0;
border: 1px solid #a7d7f9;
border-radius: 4px;
background-color: #f8f9fa;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
/* Container das abas */
.mw-tabber-tabs {
display: flex;
flex-wrap: wrap;
background-color: #eaecf0;
border-bottom: 2px solid #a7d7f9;
padding: 0;
margin: 0;
list-style: none;
}
/* Estilo individual de cada aba */
.mw-tabber-tab {
flex: 1 1 auto;
min-width: 100px;
padding: 12px 20px;
cursor: pointer;
background-color: #eaecf0;
border: none;
border-right: 1px solid #c8ccd1;
text-align: center;
font-size: 14px;
font-weight: 500;
color: #0645ad;
transition: all 0.2s ease;
user-select: none;
position: relative;
}
.mw-tabber-tab:last-child {
border-right: none;
}
/* Hover nas abas */
.mw-tabber-tab:hover {
background-color: #f8f9fa;
color: #0b0080;
}
/* Aba ativa */
.mw-tabber-tab.active {
background-color: #ffffff;
color: #0645ad;
border-bottom: 3px solid #0645ad;
font-weight: 600;
}
/* Container do conteúdo */
.mw-tabber-content {
padding: 20px;
background-color: #ffffff;
min-height: 200px;
}
/* Painel de conteúdo individual */
.mw-tabber-panel {
display: none;
animation: fadeIn 0.3s ease;
}
.mw-tabber-panel.active {
display: block;
}
/* Animação de fade in */
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(5px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Responsividade para tablets */
@media (max-width: 768px) {
.mw-tabber-tabs {
flex-direction: column;
}
.mw-tabber-tab {
border-right: none;
border-bottom: 1px solid #c8ccd1;
width: 100%;
}
.mw-tabber-tab.active {
border-bottom: 3px solid #0645ad;
border-right: none;
}
.mw-tabber-content {
padding: 15px;
}
}
/* Responsividade para mobile */
@media (max-width: 480px) {
.mw-tabber-tab {
padding: 10px 15px;
font-size: 13px;
}
.mw-tabber-content {
padding: 12px;
min-height: 150px;
}
}
</style>
</head> <body>
- Aba 1
- Aba 2
- Aba 3
Conteúdo da Aba 1
Este é o conteúdo da primeira aba. Você pode adicionar qualquer HTML aqui.
Conteúdo da Aba 2
Este é o conteúdo da segunda aba. A troca entre abas é instantânea!
Conteúdo da Aba 3
Este é o conteúdo da terceira aba. O componente é totalmente responsivo.
<script>
(function() {
'use strict';
// Inicializa todos os componentes de abas na página
function initTabbers() {
const tabbers = document.querySelectorAll('[data-tabber]');
tabbers.forEach(function(tabber) {
const tabs = tabber.querySelectorAll('.mw-tabber-tab');
const panels = tabber.querySelectorAll('.mw-tabber-panel');
tabs.forEach(function(tab) {
tab.addEventListener('click', function() {
const targetTab = this.getAttribute('data-tab');
// Remove classe active de todas as abas
tabs.forEach(function(t) {
t.classList.remove('active');
});
// Remove classe active de todos os painéis
panels.forEach(function(p) {
p.classList.remove('active');
});
// Adiciona classe active na aba clicada
this.classList.add('active');
// Adiciona classe active no painel correspondente
const targetPanel = tabber.querySelector('[data-panel="' + targetTab + '"]');
if (targetPanel) {
targetPanel.classList.add('active');
}
});
});
});
}
// Inicializa quando o DOM estiver pronto
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initTabbers);
} else {
initTabbers();
}
// Suporte para MediaWiki (quando o conteúdo é carregado dinamicamente)
if (typeof mw !== 'undefined' && mw.hook) {
mw.hook('wikipage.content').add(function() {
initTabbers();
});
}
})();
</script>
</body> </html> <style> /* Conserta o header das abas para um fundo fixo único e altura consistente */ .mw-tabber-tabs {
display: flex; flex-wrap: wrap; background-color: #eaecf0; border-bottom: 2px solid #a7d7f9; padding: 0; margin: 0; list-style: none; position: relative; min-height: 48px; /* Altura fixa para evitar 'tremida' */ box-sizing: border-box;
}
/* Todas as abas: altura fixa e alinhamento centralizado */ .mw-tabber-tab {
flex: 1 1 auto; min-width: 100px; padding: 12px 20px; cursor: pointer; background-color: transparent; border: none; border-right: 1px solid #c8ccd1; text-align: center; font-size: 14px; font-weight: 500; color: #0645ad; transition: color 0.2s ease, background-color 0.2s; user-select: none; position: relative; height: 48px; /* Altura igual à do container do header */ line-height: 24px; display: flex; align-items: center; justify-content: center; box-sizing: border-box;
}
.mw-tabber-tab:last-child {
border-right: none;
}
/* Corrige background do header nas abas no hover/active para não sobrescrever o container */ .mw-tabber-tab.active {
background-color: transparent; color: #0645ad; border-bottom: 3px solid #0645ad; font-weight: 600; z-index: 2;
}
.mw-tabber-tab:hover:not(.active) {
background-color: rgba(248,249,250, 0.4); color: #0b0080;
}
/* CONTEÚDO: Mantém altura fixa para evitar 'tremida' do layout principal */ .mw-tabber-content {
position: relative; padding: 20px; background-color: #ffffff; min-height: 200px; /* Mantém altura mínima e transição só no conteúdo */ transition: opacity 0.24s;
}
/* Painéis: Transição suave para fade-in/fade-out, ocupa mesmo espaço sempre */ .mw-tabber-panel {
opacity: 0; pointer-events: none; position: absolute; left: 0; right: 0; top: 0; bottom: 0; width: 100%; transition: opacity 0.24s; z-index: 0;
}
.mw-tabber-panel.active {
opacity: 1; pointer-events: auto; position: relative; z-index: 1;
}
/* Garante altura estável do conteúdo, mesmo com tamanhos distintos nos painéis */ .mw-tabber-content {
min-height: 200px; /* Você pode definir uma altura máxima se desejar */ /* max-height: 400px; */ overflow: auto; position: relative; /* isola contexto de painéis absolutos */
}
/* Para evitar "pulo" do conteúdo, força height igual a maior painel (opcional, ideal JS dinâmico) */ </style>