Animaciones Css

Ivan Martil

En anteriores artículos hemos visto lo necesario para realizar el menú de esta web sin hacer uso de jquery. Hoy vamos a ver desde el código javascript hasta las animaciones css.

Javascript

El primer paso es realizar un botón de acceso al menú. Las tres rayas son ya un estandard en la web. Partiremos con la siguiente estructura html.

    
    <header>
      <a class="button__nav" href="#">
        <span></span>
      </a>
      <nav class=".nav" >
        <ul>
          <li><a href="#">Inicio</a></li>
          <li><a href="#">Blog</a></li>
          <li><a href="#">Contacto</a></li>
        </ul>
      </nav>
    </header>
    

Code 1

Podríamos utilizar una webfont o una imágen para el menú. Pero con css siempre nos ahorraremos una petición y podremos animarlo con más facilidad.

 
    
    /*posicionamos donde queremos el boton de menu*/           
    .button__nav {
      position: absolute;
      right: 20px;
      top: 20px;
      z-index: 999;
      cursor: pointer;
      padding: 10px 35px 16px 0px; 
    }
      /*Eliminamos el boton si la pantalla es superior a 600px*/
      @media (min-width: 600px) {
      .button__nav {
      display: none; } 
      }
     /*Creamos dos pseudoelementos*/                              
    .button__nav span:before,
    .button__nav span:after {
      content: '';
    }
    /*los posicionamos y les damos height,width...*/              
    .button__nav span,
    .button__nav span:before,
    .button__nav span:after {
      position: absolute;
      right: 0;
      display: block;
      height: 5px;
      width: 35px;
      cursor: pointer;
      border-radius: 10px;
      background: black;
    }
    /*Separamos el before 10px hacia arriba*/                     
    .button__nav span:before {
      top: -10px; 
    }
    /*Separamos el after 10px hacia abajo*/                      
    .button__nav span:after {
      bottom: -10px;
    }
  

Code 2

Aplicando estos estilos hemos ocultado los ítems de menú y creado un botón de acceso que aparece solo en aquellos dispositivos con pantalla menor de 600px. Para animar sus propiedades necesitamos insertar una clase cuando el usuario presione el botón. Para ello haremos uso de los métodos vistos en artículos anteriores. AddEventListener(), querySelector() y classList().

    
     var btn= document.querySelector('.button__nav');
     var btnToggle=function(element){
      element.preventDefault();
      btn.classList.toggle('js-button__nav');

     }
     btn.addEventListener('click',btnToggle,false);
    

Code 3

Con esto logramos añadir la clase .js-button__nav de manera alterna al clicar sobre .button__nav y eliminamos el comportamiento por defecto de <a>. Ahora solo tenemos que utilizar la clase insertada para modificar los estilos del <span>. Pero eso lo veremos más adelante con el uso de la propiedad transition.

Bien ya tenemos una clase insertada que responde a un evento del usuario. Ahora falta añadir clases para mostrar o ocultar el nav con los enlaces del menú.

Podríamos añadir una sola clase al elemento <nav> y crear el movimiento del menú mediante transition. Pero en esta ocasión vamos ha realizar dos animaciones diferentes, una de entrada y otra de salida. Utilizaremos la propiedad de animación por excelencia en css, animation. Añadiremos una clase de entrada y otra de salida utilizando classList, comprobaremos si existe la clase .js-button__nav y añadiremos o eliminaremos una clase en consecuencia.

  
    var nav=document.querySelector('.nav');
    var btn= document.querySelector('.button__nav');
    var slideNav=function(){
      if(btn.classList.contains('js-button__nav')){
        nav.classList.remove('js-out');
        nav.classList.add('js-in');
      }else{
        nav.classList.remove('js-in');
        nav.classList.add('js-out');
      }
    }

    btn.addEventListener('click',slideNav,false);
  
    

code 4

Ya tenemos los eventos preparados y las clases insertadas así que vayamos con las animaciones del botón y el nav.

No entro en más detalle sobre el código javascript. En el artículo sobre querySelector y addEventListener , así como el dedicado a explicar classList  podréis aclarar dudas.

Animando con Transition

Anteriormente habíamos añadido estilos a .button__nav(ver code 2). Ahora cambiaremos los estilos del span cuando esté presente la clase .js-button__nav (ver code 3).

    

    /*El shortland transition es quien crea la animación*/
    .button__nav span,
    .button__nav span:before,
    .button__nav span:after {
      transition: all 100ms ease-in-out;
    }
    .button__nav.js-button__nav span {
      background-color: transparent;
    }
    .button__nav.js-button__nav span:before, 
    .button__nav.js-button__nav span:after {
      top: 0;  
    }   
    .button__nav.js-button__nav span:before { 
      transform: rotate(45deg);    
    }
    .button__nav.js-button__nav span:after {   
      transform:translateY(-10px) rotate(-45deg);  
      top: 10px; 
    }
      
    

Code 5

Una vez aplicadas las reglas css code5 logramas una bonita animación que convierte el símbolo de menú en uno de cierre. En la linea 6 de code 5 tenemos la propiedad responsable de la animación transition.

En nuestro código hacemos uso del ‘shorthand’ de la propiedad.

  
  transition: <property> <duration> <timing-function> <delay>;
   

Transition es una propiedad abreviada para simplificar la escritura css. Las propiedades de transition són:

  
    /*Especifica las propiedades afectadas*/
    transition-property:transform,top,bottom;
    /*Tiempo que durará transition*/
    transition-duration: 100ms;
    /*Tipo de animación*/
    transition-timing-function: ease-in-out;
    /*Tiempo de retardo antes de iniciar la transición*/
    transition-delay:0s;
  

Code 6

transition-property

Podemos nombrar todas aquellas propiedades compatibles con las animaciones en css o simplemente utilizar all para incluirlas a todas. Por cuestiones de rendimiento y sobretodo por control sobre nuestro código es aconsejable nombrar las propiedades.

transition-duration

Define el tiempo que dura la transición. Admite el valor en segundos(1s, 0.5s…) o milisegundos(100ms, 250ms …). Cuando definimos más de una propiedad podemos especificar un duration para cada propiedad. En caso de no definir un valor individual para cada propiedad los valores de duration se repiten hasta completar todas las propiedades.

 
    
  transition-property:transform,top,bottom, height;
  /*Un valor de duration para cada propiedad*/
  transition-duration: 100ms, 200ms, 240ms, 1s;
  /*
    Si escribimos menos valores duration que propiedades 
    se repiten hasta completar la lista de propiedades.
    La línia 10 se entendería como la 11
  */
  transition-duration:100ms,200ms;
  transition-duration:100ms,200ms,100ms,200ms;
  

Code 7

transition-timing-function

Define cómo se comportará la aceleración durante la animación. Existen diferentes funciones de aceleración o easing que podemos utilizar o bien definimos nosotros mismos como debe comportarse nuestra aceleración. En css tenemos dos maneras de definir la aceleración.

cubic-bezier()

Con la propiedad cubic-bezier establecemos la curva Bèzier de aceleración. Está compuesta de cuatro puntos:

    
     P0,P1,P2,P3
    
P0 y P3
representan el inicio y el final de la curva. P0 siempre inicia con un valor 0 y p3 con el valor 1
P1
controla la aceleración de inicio. Cuanto más alto sea el valor más rápido acelera al inicio.
P2
controla la aceleración del tramo final. Más cercano a uno más aceleración final.

Los valores deben estar entre 0 y 1. Si pasamos esos valores la función crea efectos rebote.

Parece más complicado de lo que realmente es. Existen muchas herramientas para facilitarnos la creación de nuestras curvas bezier.

steps()

Volvemos a tener una función capaz de darnos control sobre nuestras animaciones. Con steps() podemos dividir la animación en segmentos.

 
     
    steps(1, end);
    

El primer parámetro define el numero de secciones. El segundo parámetro es opcional y nos indica la dirección de la animación. Admite dos valores, End y Start:

End
Define una animación continua desde la derecha de modo que el final del último step es el final de la animación. Es el valor por defecto.
Start
Define una animación continua desde la izquierda, el inicio del último step sería el fin de la animación.

Veamos el código siguiente para entender mejor cómo funciona:

 
     
        .ejemplo-step{
          height: 50px;
          width: 50px;
          background:blue;

        }
        .ejemplo-step:hover{
            width: 250px;
            transition-property: width;
            transition-duration: 4s;
            transition-timing-function: steps(4,end);
        }
    

code 8

Ejemplos en vivo:

See the Pen BKegVa by Ivan Martil (@IvanMartil) on CodePen.

Las reglas css mostradas en el code 8 están aplicadas sobre el pequeño div azul que vemos en el ejemplo en vivo.

Si ponemos el ratón encima del div se activa el nuevo valor de width en 250px. Como tenemos la propiedad width como propiedad con transition (línea 10) este cambio se realizará de manera animada. La duración de la animación será de 4s (línea 11) y la animación se realizará en 4 pasos con un inició de animación al final de cada step (línea 12).

Podemos entender los steps como fotogramas de una película. En esta ocasión hemos creado 4 fotogramas (4 steps). Como el aumento de tamaño es en 200px debemos dividir el aumento entre el número de fotogramas (steps).

200/4=50

Al tener el tiempo de la animación en 4s y solo 4 fotogramas (steps) mostraremos por pantalla un fotograma cada segundo. Es decir, al recibir el hover, el div aumentará 50px cada segundo.

En los ejemplos en vivo tenemos diferentes valores de steps y directions. Los bloques grises tiene el valor de la segunda propiedad en end, mientras que los verdes la tienen en start.

Al hacer hover sobre cualquiera de los verdes vemos como la animación empieza de inmediato. Esto es debido a que su dirección establece la animación desde el inicio de cada step. Los bloques grises tienen un retardo. Es justo el tiempo que transcurre hasta llegar al final del primer step. Desde allí empezará su animación. Es decir si cada step tiene 25px los primeros 25px se recorren sin animación porque es al final del step cuando se inician las animaciones.

Animation

Ya creamos los eventos y las clases para mostrar el menú de navegación ver code 4. Ahora debemos darle estilos a cada clase y generar una animación con animation

    
     .js-in{
       display:block;
       animation:slideInLeft 0.5s linear;     
     }
     .js-out{
       display:block;
       animation:slideOutUp 0.5s linear;
       animation-fill-mode: both;    
     }
     
    
    

code 9

En code 9 tenemos los estilos de las clases insertadas con javascript. Hacemos uso de un shorthand para otorgar los valores a las propiedades de animation. Veremos más adelante las diferentes propiedades de animation, ahora veamos que son los nombres slideInLeft y SlideOutUp a los que hacemos referencia en en el código.

@Keyframes

Podríamos definir el keyframe como la regla que define los fotogramas clave. Con él podemos establecer los diferentes valores en cada estado de la animación. Controlaremos la velocidad y los estilos creando diferentes puntos intermedios.

    

@keyframes slideInLeft {
    0% {
      opacity:0;
      transform: translateX(-100%);
    }
    
    90%{
      transform: translateX(0%);
    }
    
    100% {
      opacity:1;
    }
}

@keyframes slideOutUp {
     0% {
     opacity:1;
     transform: translateY(0%);
     }
     
     100% {
     opacity:0;
     transform: translateY(-100%);   
     }
}

code 10

En code 10 tenemos los Keyframes para nuestro menú. Para que un keyframe sea válido debe tener como mínimo reglas en el 0% y en el 100%. El resto de pasos es optativo y podemos crear tantos como necesitemos. Hay que tener presente que no todo es animable. La lista de propiedades compatibles es la misma que para transition. La sintaxi es la siguiente:

    
    @Keyframe  {
    /*La palabra from es equivalente a 0%*/
    from{
      left:10px;
      top:0px;
      animation-timing-function:linear;

    }
    50%{
      left:200px;
      animation-timing-function:ease-out;

    }
    /*La palabra to es equivalente al 100%*/
    to{
      top:90px;
      left:700px;

    }

    }
      
    
    

code 11

animation-timing-function es la única propiedad de animation que podemos establecer en los keyframe. En code 11 definimos una función de aceleración desde 0% hasta el 50% como linear. Desde  el 50% hasta que complete la animación la función de aceleración será ease-out. De este modo controlamos con más exactitud el ritmo de nuestra animación.

Propiedades de animation

Veamos con más detalle quién es quién en cada propiedad de animation.

animation-name
Especifica la lista de animaciones que se aplicarán al elemento. Cada nombre de animación indica una regla @Keyframes
animation-duration
Específica el tiempo que durará un ciclo de animación
animation-timing-function
Especifíca como será la acceleración durante la animación. Podemos definirlo en la regla css y afectará a toda la animación o bien en el @Keyframe y afectaría solo a ese tramo de @Keyframe.
animation-delay
Especifíca el tiempo de retardo hasta que se inicie la animación.Por defecto es 0.
animation-iteration-count
Especifíca el número de veces que la animación debe repetirse. Admite cualquier valor númerico y infinite para no parar nunca la animación.
animation-direction
Define como debe comportarse la animación despues de cada repetición. admite los valores:

normal
Cada ciclo la animación se reinicia a su estado inicial y comienza desde el principio de nuevo. Es el valor por defecto.
alternate
La animación invierte su animación al terminar un ciclo. No solo la animación se invierte, también lo hacen las funciones de tiempo.
reverse
cada cilo de animación se produce al reves. Cuando acaba un ciclo vuelve a repetirse empezando desde el final.
alternte-reverse
Es como alternate pero animandose al reves. Comienza a reproducirse al reves y cada ciclo cambia de dirección.
animation-fill-mode
Especifica como la animación aplica los estilos css. Los valores soportados son:

none
La animación no aplicará los estilos ni antes ni después de la ejecución. Es decir si en la animación declaramos un color de fondo este no se aplicaría al elemento al finalizar la animación.
forwards
Los estilos que se establezcan en los @Keyframe durante la animación quedarán en el elemento al finalizar la misma. Si establecemos un color de fondo durante la animacón este quedará en el elemento al finalar la misma.
backwards
La animación aplicara los estilos definidos en el primer @Keyframe.
both
la animación seguirá las reglas de las opciones forwards y backwards, aplicando y manteniendo los estilos que se encuentre durante la animación.
animate-play-state
Determina si una animación esta en ejecución o en pausa. Puede ser consultada para saber el estado de la animación o establecer un valor para detener o ejecutar la animación. Al reanudar una animación empieza desde donde fue pausada. Admite los valores:

paused
la animación esta pausada.
running
la animación se esta ejecutando.Podríamos por ejemplo detener una animación al hacer :hover y reanudarla al salir del :hover sobre el elemento.

Con lo visto aquí debemos de ser capaces de animar cualquier elemento con css. Recordar que la compatibilidad es casi total con cualquier navegador. Explorer en sus versiones 8 y 9 no soportan animation y el 11 no soporta animaciones dentro de media queries. De todos modos, poco queda ya para dejar de lidiar con explorer y edge parece que generará menos problemas.

Las bases para realizar un menú responsive ya están consolidades. Ahora es cosa de cada uno maquetarlo a su gusto o indagar para hacer variaciones en las animaciones o el código.

Comentarios 0

Nadie ha comentado nada aún. Te animas ha ser el primero!! ;)

Opina libremente

Tu dirección de correo electrónico no será publicada.Todos los campos son obligatorios.