Ir directamente al contenido de esta página
Los menús desplegables son una interfaz de navegación muy común. Hasta ahora con CSS podíamos hacer que los vínculos de las subsecciones aparecieran sin necesidad de JavaScript, pero si queríamos hacer que el efecto de dicha aparición fuera progresivo, no nos quedaba más opción que programar una animación. Con CSS3, podemos definir el efecto en la hoja de estilo.
Hace ya casi tres años publiqué una prueba de -webkit-transition, una propiedad que permitía especificar tiempos y modos de transición entre dos valores. Los experimentos de Webkit fueron la base del modulo de transiciones de CSS nivel 3, con el que podemos crear pequeñas animaciones.
Lo que hacen los navegadores que soportan el módulo de transición es interpolar los pasos intermedios entre el valor de una o varias propiedades de CSS aplicadas a un elemento —o los pseudoelementos :before y :after— y el valor asignado al mismo cuando se cumplen las condiciones que hayamos elegido, por ejemplo, cuando un usuario interactúa con el elemento y se cambia la propiedad en :hover.
La propiedades de transición —que, por cierto, no se heredan— son las siguientes:
transition-property: indica la propiedad de CSS que queremos animar. No todas las propiedades pueden someterse a transiciones, pero ésta es la lista de las que sí. Su valor por defecto es all, es decir, que si no se especifica ninguna propiedad, la transición se aplicará a todas las del elemento.transition-duration: indica el tiempo que debe durar la animación, y se puede indicar en segundos (s) o milisegundos (ms). Si no se indica una duración, la transición es instantánea.transition-timing-function: indica la manera en la que deben calcularse los valores intermedios de la transición, y se expresa por medio de una curva cúbica de Bézier, con el valor cubic-bezier(a,b,c,d), donde a, b, c y d son las coordenadas de P1 y P2, con valores entre 0 y 1; P0 y P3 son siempre (0,0) y (1,1) respectivamente.
No obstante, con buen criterio, la especificación ya define las más comunes por medio de palabras clave:
ease: el valor por defecto, equivalente a cubic-bezier(0.25,0.1,0.25,1.0). Traducido quiere decir que la animación es un poco más lenta al comienzo y al final.linear: equivalente a cubic-bezier(0.0,0.0,1.0,1.0), la progresión del valor de la propiedad animada es aritmética, por lo que la transición es uniforme.ease-in: equivale a cubic-bezier(0.42,0,1.0,1.0); la animación acelera su velocidad a medida que progresa.ease-out: equivale a cubic-bezier(0,0,0.58,1.0); la animación decelera su velocidad a medida que progresa.ease-in-out: equivale a cubic-bezier(0.42,0,0.58,1.0); la animación primero acelera hasta la mitad de su duración y luego decelera. Se diferencia de ease en que esta última acelera al principio, se mantiene un intervalo constante y luego decelera.transition-delay: si no queremos que la animación comience inmediatamente, podemos asignarle un retraso inicial, medido también en segundos (s) o milisegundos (ms).Además, contamos con una propiedad abreviada, que es transition, donde podemos indicar todos estos valores separados por espacios. Por ejemplo, en esta declaración:
transition: background-color 0.5s linear 0.25s;
los valores corresponden a la propiedad a animar, la duración de la animación, su tipo y el retraso inicial.
Genial. Pero antes de pasar a explicar cómo podemos emplear todo esto para hacer un menú desplegable, vamos a indicar unos cuantos puntos a tener en cuenta al trabajar con animaciones.
Primero y más importante, las propiedades de transición se deben especificar en el elemento que va a sufrirlas. Parece obvio, pero al principio puede ser un tanto contraintuitivo.
Imaginemos que tenemos un vínculo en una barra de navegación y que queremos que su color de fondo cambie de manera progresiva cuando el usuario pase el ratón sobre él. Estas reglas…
a{
background-color: #D0D0D0;
}
a:hover{
background-color: #FF4040;
transition-duration: .5s;
}
…no funcionan. Las correctas son estas:
a{
background-color: #D0D0D0;
transition-duration: .5s;
}
a:hover{
background-color: #FF4040;
}
Sí, de varias formas, dependiendo de lo que resulte más cómodo para el autor.
Primero, podemos especificar cada propiedad con los distintos valores separados por comas:
a{
color: #FFF;
background: #333;
transition-property: color, background;
transition-duration: .5s, .75s;
transition-timing-function: ease-in-out;
transition-delay: .25s, 0;
}
Los valores se asignan en el orden en que se indican. Si faltan valores —como aquí en transition-timing-function— estos se asignan por orden a las propiedades hasta agotarse y los restantes reciben los valores por defecto.
La segunda opción es especificar las dos transiciones abreviadas:
a{
color: #FFF;
background: #333;
transition: color .5s ease-in-out .25s;
transition: background .75s;
}
En este caso no especificamos para el fondo ni el tipo de animación ni el retardo, dado que sus valores son los aplicados por defecto.
Y, por último, podemos especificar todos los valores en una sola transición, separando cada animación por comas:
a{
color: #FFF;
background: #333;
transition: color .5s ease-in-out .25s, background .75s;
}
En el momento en que escribo, ninguno de los navegadores actuales ha implementado las propiedades estándar del módulo de transiciones, pero algunos sí soportan las versiones experimentales con los prefijos propietarios:
| Prefijo | Desde la versión | |
|---|---|---|
| Firefox | -moz- |
4 |
| Safari | -webkit- |
3.1 |
| Safari (iOS) | -webkit- |
3.2 |
| Chrome | -webkit- |
4.0 |
| Opera | -o- |
10.5 |
| Explorer | De momento no hay soporte alguno | |
El menú de navegación consta de una serie de listas anidadas con los vínculos. En el ejemplo hemos empleado muchas otras propiedades de CSS3, pero vamos a ceñirnos estrictamente a la animación del menú:
#navegacion li ul{
height:0;
overflow:hidden;
-moz-transition-duration:.3s;
-webkit-transition-duration:.3s;
-o-transition-duration:.3s;
transition-duration:.3s;
position:absolute;
}
#navegacion li:hover ul{
height:17em;
}
Simplemente variamos la altura, de 0 a 17em. ¿Y por qué no simplemente cambiar el valor a auto? Buena pregunta. En un principio es lo que probamos, pero parece que la animación no funciona si no se especifica un valor en alguna de las unidades de medida.
En la especificación hay una sección que indica cuando no debe iniciarse una animación, pero no parece que deba ser aplicable en este caso. Tal vez se trate de un bug —ya está reportado como tal en Bugzilla—, pero lo cierto es que ninguno de los navegadores que soportan transiciones animan el elemento con height:auto.
Hace años ya que hay cierta controversia sobre si una animación pertenece a la capa de presentación o a la de comportamiento —este artículo de Jonathan Snook es de 2007—. Personalmente entiendo que la capa de comportamiento, léase JavaScript, tiene que ver con la funcionalidad que añade a una página —validación de formularios, manipulación del DOM, etc.—, y no tanto con la interpolación entre dos valores relativos al aspecto de la presentación de un elemento. Incluso el W3C las define así: «Transitions are a presentational effect».
Pero no sólo se trata de una cuestión más o menos académica: las transiciones de CSS son más eficientes. Al soportarlas el navegador de forma nativa las animaciones pueden beneficiarse de la aceleración por hardware del disposivo en el que el navegador esté instalado, reducen el consumo de recursos por parte del motor de JavaScript y, lo más importante, como este lenguaje es «mono-hilo» (single-threaded) el efecto no interfiere con otras funciones.
Así pues, viendo que además degrada muy elegantemente, no hay motivo para no empezar a utilizar las transiciones ya mismo.
Somos un pequeño estudio fundado en 2007 por tres amigos y que actualmente cuenta con un nutrido grupo de colaboradores, todos ellos profesionales con entre ocho y once años de experiencia en diversos aspectos del desarrollo y la programación web.
Además, Digital Icon, S.L. (N.I.F.: B84622927) es una empresa inscrita en el Registro Mercantil de Madrid, Tomo 22 436, Libro 0, Folio 20, Sección 8, Hoja M-400861, Inscripción 1, conforme a los artículos 18 del Código de Comercio y 6 del Reglamento del Registro Mercantil.
Si quiere conocer un poco mejor cómo trabajamos, puede descargar una copia del contrato que firmamos con nuestros clientes o seguirnos en Google+:
Cliente: La Fábrica
División: MovilizaWeb
Nuestro trabajo: PHP, HTML5, CSS
Cliente: Ana del Val
División: EidoWeb
Nuestro trabajo: PHP, XHTML, CSS, JavaScript
Cliente: Guiomar González
División: EidoWeb
Nuestro trabajo: PHP, HTML5, CSS, jQuery
© Digital Icon, S.L., 2007 – 2012
Comentarios
Muy bien explicado, por fin encontré una página con los detalles que necesitaba. Gracias.
Excelente blog, muy bien explicado. Si hay alguna manera de ayudar para difundir tu blog no dudes en hacérmelo saber.
¿Algún comentario?