Transiciones y Animaciones en CSS
Aprende a crear efectos dinámicos y animaciones fluidas en tus sitios web utilizando las propiedades de transiciones y animaciones de CSS.
Cristian Escalante
Última actualización: 10 de abril de 2025
Transiciones y Animaciones en CSS
Las transiciones y animaciones en CSS permiten crear efectos visuales dinámicos sin necesidad de JavaScript, mejorando la experiencia del usuario y añadiendo interactividad a los sitios web. En este artículo, exploraremos cómo implementar y controlar estos efectos de manera eficiente.
Transiciones CSS
Las transiciones permiten cambiar los valores de las propiedades de manera suave durante un período determinado, en lugar de que los cambios ocurran instantáneamente.
Propiedades básicas de transición
transition-property
Define las propiedades CSS que serán animadas.
.elemento {
transition-property: background-color, transform;
/* También se puede usar "all" para transicionar todas las propiedades */
/* transition-property: all; */
}
transition-duration
Especifica cuánto tiempo durará la transición.
.elemento {
transition-duration: 0.3s; /* 300 milisegundos */
/* También se pueden usar milisegundos */
/* transition-duration: 300ms; */
}
transition-timing-function
Define cómo progresa la transición a lo largo de su duración.
.elemento {
/* Valores comunes */
transition-timing-function: ease; /* Por defecto */
/* transition-timing-function: linear; */
/* transition-timing-function: ease-in; */
/* transition-timing-function: ease-out; */
/* transition-timing-function: ease-in-out; */
/* Función cubic-bezier personalizada */
/* transition-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55); */
/* Función steps */
/* transition-timing-function: steps(5, end); */
}
transition-delay
Establece un retraso antes de que comience la transición.
.elemento {
transition-delay: 0.2s; /* Espera 200ms antes de comenzar */
}
Propiedad abreviada transition
Permite establecer todas las propiedades de transición en una sola declaración.
.elemento {
/* Sintaxis: transition: property duration timing-function delay */
transition: background-color 0.3s ease 0.1s, transform 0.5s ease-out;
/* Para aplicar la misma transición a todas las propiedades */
/* transition: all 0.3s ease; */
}
Ejemplo práctico de transiciones
<button class="btn">Hover me</button>
.btn {
padding: 10px 20px;
background-color: #3498db;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s ease, transform 0.2s ease, box-shadow 0.3s ease;
}
.btn:hover {
background-color: #2980b9;
transform: translateY(-3px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
.btn:active {
transform: translateY(1px);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
Animaciones CSS
Las animaciones permiten crear secuencias más complejas que las transiciones, definiendo múltiples estados intermedios y con mayor control sobre la secuencia de animación.
Definiendo keyframes
Los @keyframes
definen los estados de la animación en diferentes puntos.
@keyframes slide-in {
0% {
transform: translateX(-100%);
opacity: 0;
}
100% {
transform: translateX(0);
opacity: 1;
}
}
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
@keyframes rainbow {
0% { background-color: red; }
14% { background-color: orange; }
28% { background-color: yellow; }
42% { background-color: green; }
57% { background-color: blue; }
71% { background-color: indigo; }
85% { background-color: violet; }
100% { background-color: red; }
}
Propiedades de animación
animation-name
Especifica el nombre de la animación (definida con @keyframes
).
.elemento {
animation-name: slide-in;
}
animation-duration
Define cuánto tiempo durará un ciclo completo de la animación.
.elemento {
animation-duration: 1s;
}
animation-timing-function
Establece cómo progresa la animación a lo largo de cada ciclo.
.elemento {
animation-timing-function: ease-out;
}
animation-delay
Establece un retraso antes de que comience la animación.
.elemento {
animation-delay: 0.5s;
}
animation-iteration-count
Define cuántas veces se repetirá la animación.
.elemento {
animation-iteration-count: 3; /* Número específico */
/* animation-iteration-count: infinite; */ /* Se repite indefinidamente */
}
animation-direction
Establece si la animación debe alternar la dirección en cada ciclo.
.elemento {
/* Valores posibles */
animation-direction: normal; /* Por defecto */
/* animation-direction: reverse; */ /* De fin a inicio */
/* animation-direction: alternate; */ /* Alterna entre normal y reverse */
/* animation-direction: alternate-reverse; */ /* Alterna entre reverse y normal */
}
animation-fill-mode
Define cómo se aplican los estilos antes y después de la ejecución de la animación.
.elemento {
/* Valores posibles */
animation-fill-mode: none; /* Por defecto */
/* animation-fill-mode: forwards; */ /* Mantiene el estado final */
/* animation-fill-mode: backwards; */ /* Aplica el estado inicial antes de comenzar */
/* animation-fill-mode: both; */ /* Combina forwards y backwards */
}
animation-play-state
Permite pausar y reanudar la animación.
.elemento {
animation-play-state: running; /* Por defecto */
/* animation-play-state: paused; */ /* Pausa la animación */
}
.elemento:hover {
animation-play-state: paused; /* Pausa la animación al pasar el ratón */
}
Propiedad abreviada animation
Permite establecer todas las propiedades de animación en una sola declaración.
.elemento {
/* Sintaxis: animation: name duration timing-function delay iteration-count direction fill-mode play-state */
animation: slide-in 1s ease-out 0.2s 2 alternate forwards;
/* Múltiples animaciones separadas por comas */
/* animation: slide-in 1s ease, fade-in 1.5s ease-in; */
}
Ejemplo práctico de animaciones
<div class="card">
<h2 class="card-title">Título animado</h2>
<p class="card-content">Contenido con animación</p>
<button class="card-button">Acción</button>
</div>
.card {
width: 300px;
padding: 20px;
border-radius: 8px;
background-color: white;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
animation: slide-in 0.6s ease-out;
}
@keyframes slide-in {
0% {
transform: translateY(50px);
opacity: 0;
}
100% {
transform: translateY(0);
opacity: 1;
}
}
.card-title {
animation: fade-in 0.8s ease-out 0.2s both;
}
.card-content {
animation: fade-in 0.8s ease-out 0.4s both;
}
.card-button {
animation: fade-in 0.8s ease-out 0.6s both;
}
@keyframes fade-in {
0% {
opacity: 0;
transform: translateY(20px);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
.card-button {
padding: 8px 16px;
background-color: #3498db;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.card-button:hover {
animation: pulse 0.8s infinite;
}
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.05);
}
100% {
transform: scale(1);
}
}
Técnicas avanzadas
Animaciones basadas en scroll
Usando IntersectionObserver
con CSS:
<div class="scroll-animation">Aparece al hacer scroll</div>
.scroll-animation {
opacity: 0;
transform: translateY(30px);
transition: opacity 0.6s ease, transform 0.6s ease;
}
.scroll-animation.visible {
opacity: 1;
transform: translateY(0);
}
// JavaScript para detectar cuando el elemento está en el viewport
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
}
});
}, { threshold: 0.1 });
document.querySelectorAll('.scroll-animation').forEach(el => {
observer.observe(el);
});
Animaciones con variables CSS
:root {
--animation-speed: 1s;
--animation-distance: 50px;
--primary-color: #3498db;
--secondary-color: #2ecc71;
}
.elemento {
animation: slide-in var(--animation-speed) ease;
}
@keyframes slide-in {
0% {
transform: translateY(var(--animation-distance));
opacity: 0;
}
100% {
transform: translateY(0);
opacity: 1;
}
}
.elemento:hover {
--animation-speed: 0.5s;
--animation-distance: 20px;
}
Animaciones secuenciales
Para animar elementos uno tras otro:
<ul class="list">
<li class="list-item">Elemento 1</li>
<li class="list-item">Elemento 2</li>
<li class="list-item">Elemento 3</li>
<li class="list-item">Elemento 4</li>
<li class="list-item">Elemento 5</li>
</ul>
.list-item {
opacity: 0;
transform: translateX(-20px);
animation: fade-in 0.5s ease forwards;
}
.list-item:nth-child(1) { animation-delay: 0.1s; }
.list-item:nth-child(2) { animation-delay: 0.2s; }
.list-item:nth-child(3) { animation-delay: 0.3s; }
.list-item:nth-child(4) { animation-delay: 0.4s; }
.list-item:nth-child(5) { animation-delay: 0.5s; }
@keyframes fade-in {
to {
opacity: 1;
transform: translateX(0);
}
}
Animaciones con transformaciones 3D
.card-3d {
transition: transform 0.6s ease;
transform-style: preserve-3d;
}
.card-3d:hover {
transform: rotateY(15deg) rotateX(5deg);
}
.parallax-element {
transform: translateZ(50px);
transition: transform 0.3s ease;
}
Optimización de rendimiento
Propiedades que se animan eficientemente
Para obtener el mejor rendimiento, prioriza animar estas propiedades:
transform
opacity
filter
Estas propiedades no requieren recalcular el layout y pueden ser aceleradas por GPU.
/* Bueno para el rendimiento */
.elemento {
transition: transform 0.3s ease, opacity 0.3s ease;
}
.elemento:hover {
transform: scale(1.1);
opacity: 0.8;
}
/* Menos eficiente */
.elemento-ineficiente {
transition: width 0.3s ease, height 0.3s ease, margin 0.3s ease;
}
.elemento-ineficiente:hover {
width: 110%;
height: 110%;
margin-top: -5%;
}
will-change
Informa al navegador qué propiedades cambiarán, permitiéndole optimizar de antemano.
.elemento {
will-change: transform, opacity;
}
Usa will-change
con moderación, ya que puede consumir recursos si se aplica en exceso.
Accesibilidad en animaciones
Reducción de movimiento
Respeta las preferencias del usuario para reducir el movimiento:
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.001s !important;
transition-duration: 0.001s !important;
}
/* O para animaciones específicas */
.animated-element {
animation: none !important;
transition: none !important;
}
}
Alternativa con JavaScript
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
// Aplicar alternativas con menos movimiento
document.querySelectorAll('.animated-element').forEach(el => {
el.classList.add('reduced-motion');
});
}
Compatibilidad con navegadores
La mayoría de los navegadores modernos soportan transiciones y animaciones CSS. Para navegadores más antiguos, considera usar prefijos de proveedor o herramientas como Autoprefixer.
.elemento {
-webkit-animation: slide-in 1s ease;
animation: slide-in 1s ease;
}
@-webkit-keyframes slide-in {
/* definición de keyframes */
}
@keyframes slide-in {
/* definición de keyframes */
}
Conclusión
Las transiciones y animaciones CSS son herramientas poderosas para mejorar la experiencia del usuario y añadir interactividad a los sitios web. Al utilizarlas de manera estratégica y con consideración por el rendimiento y la accesibilidad, puedes crear interfaces más atractivas y efectivas sin depender excesivamente de JavaScript.