Un ejemplo práctico de un menú hamburguesa moderno que destaca por su refinada microinteracción. Al interactuar con él, las tres líneas características se transforman de manera fluida en una “X”, ofreciendo un feedback visual claro e intuitivo al usuario.
Esta animación se construye combinando de manera sencilla HTML, CSS y unas pocas líneas de JavaScript para la lógica de estado.
<!-- HTML -->
<button class="hamburger-menu" aria-label="Menu" aria-expanded="false">
<span class="line line-1"></span>
<span class="line line-2"></span>
<span class="line line-3"></span>
</button>/* CSS */
.hamburger-menu {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 48px;
height: 32px;
background: transparent;
border: none;
cursor: pointer;
padding: 0;
position: relative;
transition: transform 0.3s ease;
}
.hamburger-menu:focus-visible {
outline: 2px solid #3b82f6;
outline-offset: 6px;
border-radius: 4px;
}
.hamburger-menu:hover {
transform: scale(1.05);
}
.hamburger-menu .line {
display: block;
width: 100%;
height: 4px;
background-color: #1e293b;
border-radius: 9999px;
transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
transform-origin: center;
}
/* Estilo del estado activo (expandido) */
.hamburger-menu.active .line-1 {
transform: translateY(14px) rotate(45deg);
background-color: #ef4444;
}
.hamburger-menu.active .line-2 {
opacity: 0;
transform: translateX(-20px);
}
.hamburger-menu.active .line-3 {
transform: translateY(-14px) rotate(-45deg);
background-color: #ef4444;
}// JavaScript
const hamburger = document.querySelector('.hamburger-menu');
hamburger.addEventListener('click', function() {
// Cambio de la clase active
this.classList.toggle('active');
// Soporte de accesibilidad (actualización de aria-expanded)
const isExpanded = this.classList.contains('active');
this.setAttribute('aria-expanded', isExpanded);
}); cubic-bezier permite una animación mucho más natural y menos rígida que un simple ease o linear.aria-label y aria-expanded están correctamente implementados para informar a los lectores de pantalla sobre el estado del menú (abierto o cerrado). Además, se emplea :focus-visible para destacar el foco visual exclusivamente en la navegación por teclado.transform y opacity. Al no afectar el layout, evitan operaciones costosas de repintado (repaint/reflow) y garantizan 60fps constantes.