Icono animado estilo hamburguesa sólo con CSS

Hamburguesa publicitada en autobús
Imagen de torbakhopper

En plenas fechas navideñas y después de días y días de comilonas, turrones y mazapanes, brindis y más brindis, creo que es un buen momento para parar, centrar la cabeza (y también el estómago), hacer balance y aprovechar para publicar el último post del año, para inevitablemente volver a la rueda de brindis y más brindis.

Como queda bien poco para Fin de Año, hoy voy a abordar uno de esos posts de los que realmente me gustan, un post que sirva para algo más que llenar páginas, un post útil (o al menos eso voy a intentar). Vamos a crear un botón estilo hamburgesa, el típico botón para un menú oculto, que además será animado, y para ello sólo vamos a usar CSS. ¡Ahí es na!

El botón que vamos a crear tendrá dos posiciones, una será una hamburguesa y la otra una X, dos posiciones bien reconocibles para mostrar u ocultar un menú. Cuando nos encontramos con un caso así lo primero que echamos en falta en CSS es la posibilidad de memorizar un estado, por ello en la mayoría de las ocasiones se termina recurriendo a una solución Javascript o similar. Sin embargo en CSS hay casi de todo, y las etiquetas de CSS se pueden usar de otras formas para las que inicialmente no fueron concebidas.

Para memorizar el estado en el que se encuentra nuestro botón vamos a usar una checkbox. Sí, a fin de cuentas una checkbox tiene dos estados, seleccionada y deseleccionada, así que valiéndonos de esta propiedad y apoyándonos en una simple etiqueta label podemos pasar por alto el uso de un lenguaje de programación web. El marcado inicial en HTML es, como verás, bien sencillo:


<label id="hamburger">
  <input type="checkbox" name="button-flag" value="flag" id="flag">
  <span></span>
</label>

La etiqueta label tiene una peculiaridad que nos viene muy bien, y es la de activar o desactivar una checkbox cuando esta es hija suya o si está asociada a ella. En nuestro caso la etiqueta input es hija de la etiqueta label, con la cual ya la tenemos asociada. Ahora lo que vamos a hacer es convertir la etiqueta label en nuestro botón y dibujar la hamburguesa valiéndonos de la etiqueta span (también hija de la etiqueta label) y los pseudoelementos before y after. Evidentemente ocultaremos la checkbox, ya que sólo nos es útil como memoria binaria:


#flag {
    display: none;
}

#hamburger {
    position: relative;
    display: block;
    width: 4em;
    height: 4em;
    cursor: pointer;
    background: #ff9700;
}

#hamburger span {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    width: 3em;
    height: .4em;
    margin: auto;
    background: #fff;
}

#hamburger span:before,
#hamburger span:after {
    position: absolute;
    width: inherit;
    height: inherit;
    content: '';
    background: #fff;
}

#hamburger span:before {
    top: -1em;
}

#hamburger span:after {
    bottom: -1em;
}

Ahora lo que nos queda es animarla. La animación consta de dos partes: primero juntamos las líneas que forman la hamburgesa y ocultamos la línea central justo en el momento en que se juntan. En segundo lugar giramos las dos líneas restantes 45 y -45 grados para dibujar una X. Para ello tenemos que tener en cuenta el tiempo que queremos que dure cada animación y hacer que se vayan concatenado en secuencia. Para volver al estado inicial (pasar de X a hamburguesa) sólo tenemos que invertir la animación. Para todo ello nos apoyaremos en la checkbox para saber el estado en el que estamos, suena complicado, pero no lo es tanto:


#hamburger span {
    transition: background 0s .25s;
}

#hamburger span:before,
#hamburger span:after {
    transition-delay: .25s, 0s;
    transition-duration: .25s, .25s;
}

#hamburger span:before {
    transition-property: top, -webkit-transform;
    transition-property: top, transform;
}

#hamburger span:after {
    transition-property: bottom, -webkit-transform;
    transition-property: bottom, transform;
}

#flag:checked + span {
    background: none;
}

#flag:checked + span:before {
    top: 0;
    -webkit-transform: rotate(45deg);
            transform: rotate(45deg);
}

#flag:checked + span:after {
    bottom: 0;
    -webkit-transform: rotate(-45deg);
            transform: rotate(-45deg);
}

#flag:checked + span:before,
#flag:checked + span:after {
    transition-delay: 0s, .25s;
}

Con esto ya tenemos creado nuestro icono hamburgesa y tan sólo hemos usado CSS. Para este minitutorial he creado también un Pen para que veas el resultado que da el código y además puedas trastear con él todo lo que quieras, pues personalmente creo que es la mejor forma de aprender y ver como funcionan realmente las cosas:

See the Pen Pure CSS animated hamburger button by amram (@amram1977) on CodePen.

Espero que al menos el tutorial te haya sido útil, que en esencia era la base para hacerlo, y por si nadie te lo ha dicho (cosa que dudo horrores), ¡feliz Navidad y próspero 2016!