Cómo crear nuestro propio botón tipo hamburguesa animado con CSS y un par de divs
- Andrés Cruz
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:
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 div
s o span
s 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 div
s y unas cuantas reglas CSS para obtener el siguiente botón:
El código HTML es el siguiente y será el mismo empleado en todos los ejemplos:
<div class="hamburger"> <div class="hamburger-inner"></div> </div>
Empleando contenedores "extras" para construir las líneas del menú de hamburguesa
Este pequeño truco ya lo hemos realizado de manera recurrente en varias entradas anteriores:
- Cómo hacer una simple nube en CSS
- Cómo crear una tabla con resaltado en columnas y filas (vertical y horizontal)
- Cómo crear un menú de opciones tipo rueda
Y consiste en emplear múltiples contenedores a raíz de uno solo con ayuda de los selectores before
y after
:
.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; }
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:
$('.hamburger').click(function () { $('.hamburger').toggleClass('open'); });
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.Conversión de menú de tipo hamburguesa a X
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:
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.
Puedes encontrar estos y más menús de tipo hamburguesa en el siguiente enlace:
Tasty CSS-animated hamburgersDesarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter