Cómo crear un botón o menú tipo hamburguesa animado con CSS y un poco de HTML

- Andrés Cruz

EN In english

Cómo crear un botón o menú tipo hamburguesa animado con CSS y un poco de HTML

Los menús de tipo hamburguesa no son más que pequeños botones formados por las clásicas tres líneas horizontales que todos hemos visto cientos de veces, sobre todo en aplicaciones móviles. En Android, por ejemplo, este icono se usa para mostrar el Navigation Drawer o menú lateral, y hoy en día es casi un estándar en interfaces responsive.

Siempre he visto el menú hamburguesa no solo como un disparador de navegación, sino como un icono animable y reutilizable, capaz de transformarse en una X, una flecha u otras formas con muy poco código. En este artículo te voy a mostrar cómo crear un botón o menú tipo hamburguesa animado con CSS, partiendo de una estructura mínima y explotando al máximo transform, transition y los pseudo-elementos.

Por supuesto, el uso de las transiciones en CSS para cambios suaves lo usamos también en este experimento.

Qué es un botón o menú tipo hamburguesa y cuándo usarlo

Diferencia entre icono hamburguesa y menú de navegación

Conviene aclarar algo desde el principio:
el botón hamburguesa es solo el icono (las tres líneas), mientras que el menú hamburguesa es el sistema completo que se despliega al interactuar con él.

Aquí nos vamos a centrar sobre todo en el icono, ya que es la parte que realmente se anima y se transforma con CSS.

Ventajas y desventajas del menú hamburguesa en UX

Este tipo de menú:

  • Limpia mucho el diseño
  • Reduce ruido visual
  • Funciona especialmente bien en móvil

Pero también es menos intuitivo que un menú visible. Por eso conviene usarlo cuando el espacio es limitado o cuando el diseño lo pide, no por defecto.

Cómo crear un botón hamburguesa con HTML mínimo

Los menús de tipo hamburguesa no son más que pequeños botones con las típicas 3 líneas arriba como podemos ver en la siguiente imagen:

En mi experiencia, ese enfoque termina generando más ajustes “parche” que soluciones reales.

hamburgers menu

Estos botones de tipo hamburguesa son empleados mucho en la actualidad sobre todo en aplicaciones móviles como en el caso de Android cuyas 3 líneas paralelas de manera horizontal son empleadas para mostrar un Navigation Drawer (menú lateral) en Android entre otros sistemas o aplicaciones.

Realizar este botón es sencillo con HTML, empleando tres contenedores como lo son divs o spans o empleando los contenedores extras a partir de un solo contenedor (div, span, etc) que podemos crear con los selectores after y before sobre un mismo contenedor; en esta entrada veremos cómo crear un menú tipo hamburguesa animando el mismo con un poco de CSS al momento de interactuar con el mismo.

Haciendo alusión al título de esta entrada solo necesitaremos un par de divs y unas cuantas reglas CSS para obtener el siguiente botón:

 

Estructura HTML base reutilizable

Uno de los patrones que más utilizo es reducir el HTML al mínimo indispensable. En este caso, basta con dos contenedores:

<div class="hamburger">
    <div class="hamburger-inner"></div>
</div>

Por qué usar un solo contenedor y pseudo-elementos

Consiste en emplear múltiples contenedores a raíz de uno solo con ayuda de los selectores before y after.

En lugar de crear tres div o span, prefiero generar las líneas extra con ::before y ::after. Este truco lo he reutilizado muchas veces en otros efectos CSS porque:

  • Reduce el marcado
  • Hace el componente más limpio
  • Facilita las transformaciones conjuntas

Construyendo las líneas del menú con CSS (::before y ::after)

Posicionamiento y dimensiones de las líneas

Partimos de un contenedor base y creamos las tres líneas a partir de él:

.hamburger {
    min-height: 30px;
    max-width: 50px;
}
.hamburger-inner, .hamburger-inner:after, .hamburger-inner:before {
    background-color: blue;
    position: absolute;
    width: 40px;
    height: 4px;
    border-radius: 5px;
    content: '';
    transition-timing-function: ease;
    transition-duration: .2s;
    transition-property: transform,opacity;
}
.hamburger-inner:before {
    top: 10px;
}
.hamburger-inner:after {
    top: 20px;
}

Aquí simplemente estamos creando tres líneas delgadas y desplazándolas para que no se solapen.

Evitar solapamientos y mantener el código limpio

El secreto está en pensar el icono como un pequeño sistema geométrico. Cada línea tiene su posición y luego, al animar, solo modificamos esas coordenadas.

Animar el botón hamburguesa con CSS

Uso de transform, translate y rotate

Para animar el botón necesitamos un estado, normalmente una clase .open. En mi caso suelo añadirla con un JavaScript mínimo.

Cómo ves solo creamos unas delgadas líneas y los desplazamos para que no se solapen; ahora falta animarlo; para esto primero emplearemos un JavaScript para incluir/remover la clase open que indica si el botón está abierto o cerrado:

// Seleccionamos el elemento
const hamburger = document.querySelector('.hamburger');

// Añadimos el evento de clic
hamburger.addEventListener('click', function() {
    // Alternamos la clase 'open'
    this.classList.toggle('open');
});
La función toggleClass hace exactamente lo mencionado, si la clase especificada como parámetro existe, entonces la remueve del elemento, caso contrario agrega la clase al elemento.

Transiciones y timing functions para animaciones suaves

A partir de aquí, todo es CSS. Cuando el botón está abierto, modificamos las transformaciones:

Demo 1

Con la clase open, podemos definir un CSS específico para que tome al momento que esté se le aplique un clic al menú de tipo hamburguesa y de esta forma cambie de estado; el CSS es:

.hamburger.open .hamburger-inner {
    transform: translate3d(0,10px,0) rotate(45deg);
}
.hamburger.open .hamburger-inner:after {
    transform: translate3d(0,-20px,0) rotate(-90deg);
}
.hamburger.open .hamburger-inner:before {
    transform: translate3d(0,-20px,0) rotate(90deg);
}

Con esto obtenemos el siguiente botón:

 

Demo 2

Aquí tenemos otra animación empleando empleando cubic-bezier que permite definir de una manera más personalizada la velocidad de una animación en CSS desde el arranque del mismo hasta el final; puedes ver más sobre las las curvas de béziers en una entrada posterior y empleamos las transformaciones para rotar, trasladar y escalar el menú de tipo hamburguesa a donde queramos:

.hamburger.open .hamburger-inner:after {
	top: 0;
	transform: translate3d(-10px, -9px, 0) rotate(-45deg) scale(0.7, 1);
	transition: top 0.1s ease, transform 0.1s 0.1s cubic-bezier(0.895, 0.03, 0.685, 0.22);
}
.hamburger.open .hamburger-inner:before {
	bottom: 0;
	transform: translate3d(-9px, 20px, 0) rotate(45deg) scale(0.7, 1);
	transition: bottom 0.1s ease, transform 0.1s 0.1s cubic-bezier(0.895, 0.03, 0.685, 0.22);
}

Conversión de menú de tipo hamburguesa a una flecha

Ahora con el código base anterior, podemos adaptar otras formas como la famosa flecha para volver a una sección anterior.

Demo 1

Una animación sencilla, que la podemos adaptar como queramos (por ejemplo) a una flecha; fíjese que ahora la rotación es de 45 grados en su eje positivo y negativo:

.hamburger.open .hamburger-inner:after {
    transform: translate3d(-8px,-2px,0) rotate(45deg) scaleX(.7);
    width: 35px;
}
.hamburger.open .hamburger-inner:before {
    transform: translate3d(-8px,2px,0) rotate(-45deg) scaleX(.7);
    width: 35px;
}

Y obtenemos:

 

Ajustes finos de escala y desplazamiento

Aquí es donde entra la experimentación. En mi experiencia, cambiar ligeramente la escala o el desplazamiento horizontal puede marcar la diferencia entre una flecha “forzada” y una que se siente natural.

Demo 2

El último demo que realizaremos es otra variación del presentado anteriormente:

.hamburger.open .hamburger-inner {
	transform: rotate(-180deg);
}
.hamburger.open .hamburger-inner:after {
	transform: translate3d(8px, 0, 0) rotate(-45deg) scale(0.7, 1);
}
.hamburger.open .hamburger-inner:before {
	transform: translate3d(8px, 0, 0) rotate(45deg) scale(0.7, 1);
}

Como puedes ver la lógica es sencilla, con la propiedad translate3d le aplicamos una serie de operaciones geométricas a cada una de las líneas que conforman el menú de tipo hamburguesa, en específico se afectan las líneas creadas por los contenedores extras creada mediante los selectores before y after; también rotamos todo el menú de tipo hamburguesa con el selector .hamburger.open .hamburger-inner lo que da un interesante efecto.

Personalizar animaciones con cubic-bezier

Qué es cubic-bezier y cuándo usarlo

Cuando queremos más control sobre la velocidad de la animación, cubic-bezier es una herramienta brutal. Permite definir cómo arranca y termina el movimiento.

Ejemplo de animación personalizada

.hamburger.open .hamburger-inner::after {
 transition: top 0.1s ease,
             transform 0.1s 0.1s cubic-bezier(0.895, 0.03, 0.685, 0.22);
}

Este tipo de curvas da animaciones mucho más “orgánicas” que las transiciones por defecto.

Buenas prácticas al crear botones hamburguesa animados

  • Rendimiento y simplicidad del CSS
    • Menos HTML = mejor mantenimiento
    • Evita animar propiedades costosas
    • transform y opacity son tus aliados
  • Siempre que puedo, reutilizo el mismo componente y solo cambio las reglas CSS.
  • Accesibilidad y estados del botón
  • No olvides:
    • Cambiar el estado visual
    • Indicar si el menú está abierto o cerrado
    • Añadir cursor: pointer y, si procede, atributos ARIA

FAQs

  • ¿Se puede animar un menú hamburguesa sin JavaScript?
    • Sí, la animación puede hacerse 100% en CSS; JavaScript solo es necesario para cambiar el estado.
  • ¿Es mejor usar tres divs o pseudo-elementos?
    • Los pseudo-elementos permiten un HTML más limpio y suelen ser más fáciles de mantener.
  • ¿Qué propiedades CSS se usan para estas animaciones?
    • Principalmente transform, transition, opacity y cubic-bezier.

Conclusión

Crear un botón o menú tipo hamburguesa animado con CSS es mucho más sencillo de lo que parece si entiendes cómo funcionan las transformaciones geométricas. Con un HTML mínimo, pseudo-elementos y unas cuantas reglas bien pensadas, puedes obtener animaciones limpias, reutilizables y muy visuales.

En mi caso, este enfoque me ha permitido reutilizar el mismo icono en distintos proyectos, simplemente cambiando un par de transformaciones.

Se explica cómo crear un botones de tipo hamburguesa animado con CSS, HTML y una simple función de JavaScript, los botones se convierten una vez clickeados en flechas y/o X según sea el caso.

Acepto recibir anuncios de interes sobre este Blog.

Andrés Cruz

EN In english