Diferencia entre transition y animation en CSS

Diferencia entre transition y animation en CSS

Cuando empezamos a añadir movimiento a una interfaz web, es muy habitual encontrarnos con dos propiedades que parecen hacer algo parecido: transition y animation. Ambas permiten animar elementos con CSS, ambas ayudan a que una interfaz se sienta más fluida y ambas pueden mejorar la experiencia de usuario cuando se usan con intención.

Pero aunque a simple vista puedan parecer intercambiables, no sirven exactamente para lo mismo.

La diferencia entre transition y animation en CSS está en cómo se activa el movimiento, cuánto control tenemos sobre los pasos intermedios y qué tipo de comportamiento queremos conseguir. Dicho de forma sencilla: una transition anima el cambio entre dos estados, mientras que una animation permite crear una secuencia de movimiento más completa mediante @keyframes.

Esta diferencia parece pequeña, pero en la práctica cambia mucho la forma de trabajar. No es lo mismo suavizar el cambio de color de un botón al hacer hover que crear un loader, una entrada animada de tarjetas, una ilustración en movimiento o un efecto que se repite en bucle.

En este artículo vamos a ver cuándo usar transition y cuándo usar animation en CSS, con ejemplos claros, comparaciones prácticas y recomendaciones para tomar mejores decisiones en proyectos reales.

Si estás empezando a trabajar con movimiento en interfaces, también puede resultarte útil complementar esta lectura con la guía de animaciones CSS para crear interfaces con más vida, donde se explican conceptos base para entender mejor cómo aplicar animaciones sin caer en el exceso.

Qué es una transition en CSS

Una transition en CSS permite animar el cambio de una propiedad cuando un elemento pasa de un estado a otro. Es decir, CSS detecta que una propiedad ha cambiado y, en lugar de aplicar ese cambio de golpe, lo interpola suavemente durante un tiempo determinado.

Por ejemplo, imagina un botón que cambia de color cuando el usuario pasa el ratón por encima. Sin transition, el color cambia de forma inmediata. Con transition, ese cambio se suaviza.

.button {
  background-color: #cc2b5e;
  color: white;
  transition: background-color 0.3s ease, transform 0.3s ease;
}

.button:hover {
  background-color: #753a88;
  transform: translateY(-2px);
}

En este caso, la transición se produce porque hay un cambio de estado: el botón pasa de su estado normal a su estado :hover.

La idea importante es esta: una transition necesita que algo cambie. Ese cambio puede estar provocado por una pseudoclase como :hover, :focus-visible o :active, por una clase añadida con JavaScript o por un cambio en el DOM.

Por eso las transiciones son tan habituales en botones, enlaces, campos de formulario, tarjetas interactivas, menús desplegables y otros componentes de interfaz.

Cómo funciona una transition

Una transición suele componerse de cuatro partes principales:

transition-property: background-color;
transition-duration: 0.3s;
transition-timing-function: ease;
transition-delay: 0s;

También podemos escribirlo en formato abreviado:

transition: background-color 0.3s ease 0s;
  • transition-property indica qué propiedad se va a animar.
  • transition-duration define cuánto tarda el cambio.
  • transition-timing-function controla el ritmo de la transición.
  • transition-delay añade un retraso antes de iniciar el efecto.
.card {
  opacity: 0.8;
  transform: scale(1);
  transition: opacity 0.25s ease, transform 0.25s ease;
}

.card:hover {
  opacity: 1;
  transform: scale(1.03);
}

Aquí estamos animando dos propiedades: opacity y transform. Ambas son buenas candidatas para animaciones porque suelen ofrecer buen rendimiento en navegador.

Cuándo usar transition CSS

Conviene usar transition cuando queremos animar un cambio simple entre dos estados. Es especialmente útil en elementos interactivos de una interfaz.

  • Botones que cambian de color al hacer hover.
  • Enlaces que muestran un subrayado suave.
  • Tarjetas que se elevan ligeramente al pasar el cursor.
  • Campos de formulario que cambian el borde al recibir foco.
  • Menús que se despliegan al añadir una clase.
  • Modales que aparecen con un cambio de opacidad.
.input {
  border: 2px solid #ddd;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.input:focus {
  border-color: #cc2b5e;
  box-shadow: 0 0 0 4px rgba(204, 43, 94, 0.15);
}

En este caso, la transición mejora la experiencia sin llamar demasiado la atención. El usuario entiende que el campo está activo, pero el efecto no compite con el contenido.

Este tipo de detalle es especialmente importante en componentes accesibles. Por ejemplo, cuando trabajamos estados de foco, conviene cuidar tanto el movimiento como la visibilidad del indicador. Si quieres profundizar en esta parte, puedes leer el artículo sobre focus visible y navegación con teclado.

Qué es una animation en CSS

Una animation en CSS permite definir una secuencia de movimiento usando @keyframes. A diferencia de transition, no se limita a pasar de un estado inicial a un estado final. Puede tener varios pasos intermedios, repetirse, alternarse, pausarse o ejecutarse automáticamente.

@keyframes float {
  0% {
    transform: translateY(0);
  }

  50% {
    transform: translateY(-12px);
  }

  100% {
    transform: translateY(0);
  }
}

.icon {
  animation: float 3s ease-in-out infinite;
}

Aquí no estamos esperando a que el usuario haga hover ni a que cambie una clase. La animación empieza por sí misma y se repite indefinidamente.

Este es uno de los puntos clave en la comparación transition vs animation CSS: las animaciones con @keyframes no necesitan necesariamente una interacción para ejecutarse. Pueden iniciarse al cargar la página, al añadir una clase, al entrar un elemento en pantalla o cuando lo decidamos mediante JavaScript.

Cómo funciona animation CSS

Una animación CSS suele componerse de dos partes. Primero, definimos los pasos de la animación con @keyframes:

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(24px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

Después, aplicamos esa animación a un elemento:

.article-card {
  animation: fadeInUp 0.6s ease both;
}

La propiedad abreviada animation puede incluir varios valores:

animation: fadeInUp 0.6s ease 0.2s 1 normal both;

Ese código equivale, aproximadamente, a esto:

animation-name: fadeInUp;
animation-duration: 0.6s;
animation-timing-function: ease;
animation-delay: 0.2s;
animation-iteration-count: 1;
animation-direction: normal;
animation-fill-mode: both;

La propiedad animation-fill-mode es especialmente importante. Cuando usamos both, el elemento respeta los estilos del primer y último fotograma antes y después de ejecutarse la animación. Esto ayuda a evitar saltos visuales extraños.

Cuándo usar animation CSS

Conviene usar animation cuando necesitamos más control sobre el movimiento o cuando el efecto no depende únicamente de un cambio entre dos estados.

  • Loaders o spinners.
  • Elementos que entran en pantalla.
  • Ilustraciones animadas.
  • Efectos decorativos que se repiten.
  • Animaciones con varios pasos intermedios.
  • Microinteracciones más elaboradas.
  • Secuencias temporizadas.
  • Skeleton loaders.
  • Indicadores de atención, como un icono que pulsa suavemente.
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.loader {
  width: 32px;
  height: 32px;
  border: 4px solid #f8e0ea;
  border-top-color: #cc2b5e;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

Este sería un mal caso para transition, porque no hay realmente un cambio puntual entre dos estados. Queremos un movimiento continuo, repetitivo y autónomo. Ahí animation encaja mucho mejor.

Las animaciones también son muy útiles cuando trabajamos con ilustraciones CSS. Si te interesa este tipo de enfoque visual, puedes continuar con el artículo sobre cómo dibujar formas básicas con CSS o con la guía sobre pseudo-elementos en CSS para crear ilustraciones más complejas.

Diferencia entre transition y animation en CSS

La diferencia principal entre transition y animation en CSS puede resumirse así: transition anima un cambio de estado; animation define una secuencia de movimiento.

Una transición necesita que una propiedad cambie. Por ejemplo, un botón cambia su color en :hover. En cambio, una animación puede ejecutarse aunque no haya interacción del usuario, porque sus pasos están definidos dentro de @keyframes.

Comparativa rápida: transition vs animation CSS

Criteriotransitionanimation
Uso principalCambios simples entre dos estadosSecuencias de movimiento más complejas
Necesita cambio de estadoNo siempre
Usa @keyframesNo
Puede repetirse en bucleNo de forma naturalSí, con infinite
Control de pasos intermediosLimitadoAlto
Ideal para hover/focusNo suele ser necesario
Ideal para loadersNo
ComplejidadBajaMedia o alta
LegibilidadMuy directaRequiere más estructura

Esta tabla ayuda, pero no debería entenderse como una regla rígida. En CSS casi siempre hay varias formas de resolver un mismo efecto. Lo importante es elegir la herramienta que haga el código más claro, mantenible y coherente con la intención del movimiento.

Ejemplo comparativo con transition

Supongamos que queremos que una tarjeta se eleve cuando el usuario pasa el cursor por encima.

.card {
  transform: translateY(0);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.card:hover {
  transform: translateY(-6px);
  box-shadow: 0 16px 36px rgba(0, 0, 0, 0.14);
}

Este es un caso perfecto para transition. Hay un estado inicial y un estado final. No necesitamos pasos intermedios. Tampoco necesitamos que la tarjeta se mueva sola. La interacción del usuario activa el cambio.

Ejemplo comparativo con animation

Ahora imaginemos que queremos que esa misma tarjeta aparezca suavemente al cargar la página.

@keyframes cardEntrance {
  0% {
    opacity: 0;
    transform: translateY(24px) scale(0.98);
  }

  60% {
    opacity: 1;
    transform: translateY(-4px) scale(1.01);
  }

  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

.card {
  animation: cardEntrance 0.7s ease both;
}

Aquí animation tiene más sentido porque estamos creando una secuencia. La tarjeta no solo pasa de invisible a visible; tiene un pequeño movimiento intermedio que da sensación de entrada natural.

Cuándo usar transition y cuándo usar animation

La pregunta práctica no es solo qué diferencia hay entre ambas, sino cuándo conviene usar cada una. En proyectos reales, elegir bien evita código innecesario, mejora la experiencia de usuario y facilita el mantenimiento.

Usa transition para microinteracciones simples

Las transiciones son ideales para microinteracciones discretas. Por ejemplo, cuando un usuario interactúa con un botón, una tarjeta, un enlace o un campo de formulario.

.link {
  color: #753a88;
  text-decoration-color: transparent;
  transition: color 0.2s ease, text-decoration-color 0.2s ease;
}

.link:hover {
  color: #cc2b5e;
  text-decoration-color: currentColor;
}

Este tipo de efecto no necesita @keyframes. Sería excesivo crear una animación para algo tan simple.

Cuando ocurra esto, quiero que esta propiedad cambie suavemente.

Si esa frase describe lo que necesitas, probablemente estás ante un buen caso para usar transition.

Usa animation para movimientos autónomos o secuenciales

Las animaciones CSS son mejores cuando necesitas una secuencia con más intención. Por ejemplo, cuando un elemento entra, sale, vibra, rota, pulsa, flota o se repite.

@keyframes pulse {
  0%, 100% {
    transform: scale(1);
    opacity: 1;
  }

  50% {
    transform: scale(1.08);
    opacity: 0.75;
  }
}

.notification-dot {
  animation: pulse 1.5s ease-in-out infinite;
}

Este efecto sería incómodo de resolver con transition, porque no depende de un único cambio de estado. Queremos que el punto tenga vida propia y se repita.

Quiero que este elemento siga una secuencia de movimiento.

Si esa frase describe mejor tu intención, lo más probable es que necesites animation.

Regla sencilla para decidir

Una forma muy práctica de decidir es esta: si hay dos estados, normalmente usa transition. Si hay una secuencia, usa animation.

Si hay dos estados, usa transition

  • normal / hover
  • cerrado / abierto
  • visible / invisible
  • activo / inactivo
  • enfocado / no enfocado

Si hay una secuencia, usa animation

  • aparecer con rebote
  • rotar indefinidamente
  • parpadear varias veces
  • entrar desde abajo y estabilizarse
  • moverse siguiendo varios pasos
  • repetir un efecto decorativo

Propiedades animables: un detalle importante

No todas las propiedades CSS se animan igual de bien. Tanto con transition como con animation, es recomendable priorizar propiedades que el navegador pueda procesar de forma eficiente.

Las más recomendables suelen ser:

transform
opacity

También se pueden animar propiedades como background-color, color, border-color o box-shadow, aunque algunas pueden tener más coste visual o de rendimiento según el caso.

En cambio, conviene tener cuidado con propiedades que afectan al layout, como:

width
height
top
left
margin
padding

No significa que estén prohibidas, pero pueden provocar recalculado de layout y afectar al rendimiento, especialmente si hay muchos elementos en pantalla.

/* Menos recomendable */
.box {
  position: relative;
  top: 0;
  transition: top 0.3s ease;
}

.box:hover {
  top: -10px;
}

/* Más recomendable */
.box {
  transform: translateY(0);
  transition: transform 0.3s ease;
}

.box:hover {
  transform: translateY(-10px);
}

La segunda opción suele ser más fluida y predecible.

Este mismo criterio también se aplica cuando diseñamos efectos visuales más complejos. Si trabajas con composiciones CSS, fondos decorativos o ilustraciones adaptables, puedes complementar esta parte con el artículo sobre dibujar con CSS responsive.

Transition CSS con JavaScript: cambio de clases

Aunque muchas transiciones se activan con pseudoclases como :hover, también es muy común activarlas añadiendo o quitando clases con JavaScript.

.sidebar {
  transform: translateX(-100%);
  transition: transform 0.3s ease;
}

.sidebar.is-open {
  transform: translateX(0);
}
const sidebar = document.querySelector('.sidebar');
const button = document.querySelector('.menu-button');

button.addEventListener('click', () => {
  sidebar.classList.toggle('is-open');
});

Este patrón es muy útil porque mantiene la animación en CSS y deja a JavaScript solo la responsabilidad de cambiar el estado.

Aquí vuelve a encajar transition, porque el elemento tiene dos estados claros: cerrado y abierto.

Animation CSS con clases: controlar cuándo empieza

Las animaciones también pueden activarse mediante clases. Esto es útil cuando no queremos que una animación se ejecute siempre al cargar la página, sino en un momento concreto.

@keyframes reveal {
  from {
    opacity: 0;
    transform: translateY(16px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.section {
  opacity: 0;
}

.section.is-visible {
  animation: reveal 0.6s ease both;
}

Este enfoque puede combinarse con IntersectionObserver para animar elementos cuando entran en el viewport.

const sections = document.querySelectorAll('.section');

const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      entry.target.classList.add('is-visible');
    }
  });
});

sections.forEach((section) => observer.observe(section));

En este caso, animation tiene sentido porque queremos una entrada definida con @keyframes. Si la entrada fuera muy simple, una transición también podría servir.

Errores comunes al elegir entre transition y animation

A veces el problema no está en conocer las propiedades, sino en usarlas en el contexto equivocado. Veamos algunos errores frecuentes.

Usar animation para cualquier hover

Si solo quieres cambiar el color, la escala o la sombra de un botón al hacer hover, normalmente no necesitas animation.

/* Excesivo para un simple hover */
@keyframes buttonHover {
  from {
    transform: scale(1);
  }

  to {
    transform: scale(1.04);
  }
}

Sería más simple así:

.button {
  transform: scale(1);
  transition: transform 0.2s ease;
}

.button:hover {
  transform: scale(1.04);
}

Menos código, misma intención y mejor legibilidad.

Usar transition para un loader

Un loader necesita repetición. Por tanto, animation es mucho más adecuada.

@keyframes loading {
  to {
    transform: rotate(360deg);
  }
}

.loader {
  animation: loading 1s linear infinite;
}

Aquí una transición no sería natural, porque no hay un único cambio de estado que queramos suavizar.

Animar demasiadas cosas a la vez

El movimiento debe ayudar, no distraer. Una interfaz llena de elementos que se mueven constantemente puede aumentar la carga cognitiva y hacer que el usuario pierda el foco.

  • Para guiar la atención.
  • Para reforzar una acción.
  • Para comunicar cambio de estado.
  • Para hacer más comprensible una transición entre vistas.
  • Para dar sensación de continuidad.

Si la animación no aporta nada, probablemente sobra.

Accesibilidad: cuidado con el exceso de movimiento

Al hablar de transition CSS y animation CSS, es importante mencionar la accesibilidad. Algunas personas pueden experimentar molestias con animaciones intensas, movimientos bruscos, parpadeos o desplazamientos constantes.

CSS permite respetar la preferencia del usuario mediante prefers-reduced-motion.

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

Este patrón reduce drásticamente el movimiento para usuarios que así lo han configurado en su sistema.

@media (prefers-reduced-motion: reduce) {
  .decorative-shape {
    animation: none;
  }

  .button {
    transition: none;
  }
}

No se trata de eliminar todo el diseño, sino de ofrecer una experiencia más cómoda. Una buena animación no debería ser imprescindible para entender la interfaz.

Además del movimiento, conviene cuidar el contraste, la jerarquía visual y la legibilidad. Si estás trabajando esta parte en tus interfaces, puedes revisar la guía sobre contraste y tipografía en accesibilidad visual.

Buenas prácticas para usar transition y animation en CSS

Mantén las transiciones breves

Las transiciones de interfaz suelen funcionar bien entre 150ms y 300ms. Si son demasiado rápidas, apenas se perciben. Si son demasiado lentas, la interfaz parece pesada.

.button {
  transition: transform 0.2s ease, background-color 0.2s ease;
}

Para cambios más complejos, como abrir un panel o mostrar un modal, puedes usar duraciones algo mayores, por ejemplo 300ms o 400ms.

Usa easing con intención

La función de tiempo cambia mucho la sensación del movimiento. ease suele funcionar bien para muchos casos, pero también puedes usar ease-in, ease-out, ease-in-out o cubic-bezier().

transition: transform 0.3s ease;
animation: fadeInUp 0.6s ease-out both;

Evita animaciones infinitas innecesarias

Las animaciones infinitas deben usarse con cuidado. Un loader tiene sentido porque comunica que algo está pasando. Pero un fondo lleno de elementos moviéndose sin parar puede distraer.

¿Este movimiento ayuda al usuario o solo decora?

Si solo decora, quizá deba ser muy sutil o no existir.

Nombra bien tus keyframes

Los nombres de @keyframes deberían describir la intención del movimiento.

@keyframes fadeInUp {}
@keyframes spin {}
@keyframes pulse {}
@keyframes slideInFromLeft {}

Evita nombres genéricos como animacion1, effect o move. Cuando el proyecto crece, los nombres claros facilitan mucho el mantenimiento.

Ejemplo final: usando transition y animation juntas

No siempre hay que elegir una u otra. De hecho, es muy común usar ambas en un mismo componente, cada una para una responsabilidad distinta.

Imaginemos una tarjeta que aparece al cargar y, además, tiene una interacción al hacer hover.

@keyframes cardReveal {
  from {
    opacity: 0;
    transform: translateY(20px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.card {
  opacity: 0;
  transform: translateY(20px);
  animation: cardReveal 0.6s ease both;
  transition: box-shadow 0.25s ease, transform 0.25s ease;
}

.card:hover {
  transform: translateY(-4px);
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.12);
}

Aquí usamos animation para la entrada inicial y transition para la interacción posterior. La animación define cómo aparece la tarjeta; la transición suaviza cómo responde al usuario.

Este tipo de combinación es muy habitual en interfaces modernas. La clave está en no mezclar responsabilidades sin necesidad.

FAQs sobre transition vs animation CSS

¿Cuál es la principal diferencia entre transition y animation en CSS?

La principal diferencia es que transition anima el cambio entre dos estados, mientras que animation permite crear una secuencia de movimiento mediante @keyframes. Si quieres suavizar un hover, un focus o un cambio de clase, normalmente usarás transition. Si necesitas una animación con varios pasos, repetición o movimiento autónomo, usarás animation.

¿Es mejor usar transition o animation para mejorar el rendimiento?

No depende tanto de usar transition o animation, sino de qué propiedades estás animando. En general, transform y opacity suelen ser las opciones más recomendables para conseguir animaciones fluidas. En cambio, animar propiedades como width, height, top, left o margin puede ser más costoso porque afecta al layout.

¿Puedo usar transition y animation en el mismo elemento?

Sí, puedes usar ambas en el mismo elemento. Por ejemplo, puedes usar animation para que una tarjeta aparezca al cargar la página y transition para suavizar su comportamiento al hacer hover. Lo importante es que cada una tenga una función clara y que no entren en conflicto animando la misma propiedad al mismo tiempo.

Elegir bien el movimiento también es diseñar mejor

La diferencia entre transition y animation en CSS no es solo una cuestión técnica. También es una cuestión de diseño, experiencia de usuario y claridad de intención.

Una transition es perfecta cuando queremos que un cambio de estado se sienta más natural. Es directa, sencilla y muy útil para microinteracciones. Una animation, en cambio, nos da más control para crear secuencias, entradas, loaders, efectos decorativos o movimientos que se repiten.

La clave está en no elegir por costumbre. Antes de escribir CSS, conviene preguntarse qué queremos comunicar con ese movimiento. Si solo hay dos estados, probablemente una transición sea suficiente. Si hay una secuencia, varios pasos o repetición, entonces una animación será más adecuada.

En definitiva, transition y animation no compiten entre sí. Son herramientas complementarias. Usarlas bien permite crear interfaces más fluidas, más comprensibles y más agradables, sin caer en el exceso de movimiento ni complicar el código innecesariamente.

MJML vs HTML tradicional para emails: ventajas y limitaciones

Crear un email responsive parece sencillo hasta que intentas que se vea bien en Gmail, Outlook, Apple Mail, Yahoo, clientes móviles y aplicaciones de escritorio al mismo tiempo. En una página web, normalmente trabajamos con HTML, CSS moderno, media queries, Flexbox, Grid y un ecosistema de navegadores bastante predecible. En email, en cambio, entramos en un terreno mucho más delicado.

El desarrollo de emails tiene sus propias reglas. Muchas propiedades CSS no funcionan igual en todos los clientes de correo, algunos estilos deben ir inline, las tablas siguen siendo habituales y Outlook continúa siendo uno de los grandes retos para cualquier persona que maqueta newsletters o emails transaccionales.

Por eso, cuando hablamos de html email responsive, suele aparecer una comparación muy habitual: MJML vs HTML tradicional. ¿Conviene escribir todo el email a mano usando HTML y CSS? ¿O es mejor apoyarse en MJML para generar un código más compatible y fácil de mantener?

La respuesta no es absoluta. MJML puede ser una herramienta muy útil para crear emails responsive de forma más rápida, limpia y ordenada. Pero el HTML tradicional sigue teniendo sentido cuando necesitas un control muy preciso sobre el resultado final.

En este artículo vamos a ver qué aporta MJML, qué limitaciones tiene, cuándo conviene usar HTML tradicional y cómo decidir qué opción encaja mejor según el tipo de proyecto.

Qué significa crear un email responsive

Un email responsive es un correo que se adapta correctamente a diferentes tamaños de pantalla y entornos de lectura. Esto incluye escritorio, móvil, tablet, clientes web, aplicaciones nativas y gestores de correo con distintos motores de renderizado.

En desarrollo web, solemos pensar en responsive design de una forma bastante natural. Ajustamos contenedores, usamos unidades relativas, media queries y componentes flexibles. Si vienes del mundo frontend, probablemente ya estés acostumbrada a trabajar con diseños adaptables. De hecho, conceptos como los que se aplican al dibujar con CSS responsive también parten de una idea similar: crear interfaces o composiciones que respondan bien a distintos contextos.

Sin embargo, el email no se comporta como una web normal. Un correo se abre dentro de aplicaciones que pueden modificar, ignorar o interpretar parcialmente el código. Por eso, maquetar emails requiere una mentalidad más conservadora.

Por qué el HTML email responsive es más complejo que una web

El principal problema del email responsive es la fragmentación. Cada cliente de correo tiene sus propias limitaciones. Algunas propiedades CSS funcionan bien en Apple Mail, pero pueden fallar en Outlook. Gmail puede interpretar ciertos estilos de una manera y otro cliente hacerlo de forma distinta.

Esto obliga a trabajar con una base técnica muy específica. En email, todavía es habitual usar estructuras basadas en tablas, estilos inline, anchuras fijas combinadas con comportamiento fluido, condicionales para Outlook, imágenes optimizadas y botones construidos con código compatible.

Aquí no basta con que el email se vea bien en el navegador mientras lo desarrollas. Lo importante es que se vea de forma consistente cuando llega a la bandeja de entrada real.

El error de diseñar emails como si fueran páginas web

Uno de los errores más comunes es intentar trasladar directamente las prácticas del desarrollo web moderno al email. Por ejemplo, usar estructuras con div, CSS externo, Grid, animaciones complejas o técnicas avanzadas puede parecer lógico si vienes del frontend, pero no siempre es recomendable.

Esto no significa que los emails tengan que ser visualmente pobres. Significa que hay que diseñarlos entendiendo sus límites. Igual que en accesibilidad web conviene pensar en la experiencia real de lectura, como comentaba en el artículo sobre la importancia de la accesibilidad web, en email también debemos priorizar claridad, legibilidad y compatibilidad.

Un email efectivo no es el más espectacular técnicamente. Es el que se lee bien, carga rápido, se entiende y permite al usuario actuar sin fricción.

Qué es MJML y por qué facilita la maquetación de emails

MJML, siglas de Mailjet Markup Language, es un lenguaje de marcado pensado específicamente para crear emails responsive. Su objetivo es simplificar la escritura de plantillas de correo sin tener que pelear directamente con todo el HTML basado en tablas.

En lugar de escribir manualmente una estructura compleja de tablas, celdas, atributos y estilos inline, MJML permite trabajar con etiquetas más claras, como mj-section, mj-column, mj-text, mj-image o mj-button.

Si quieres profundizar en la base de esta herramienta, puedes leer también el artículo sobre qué es MJML y por qué facilita la maquetación de emails responsive, donde se explica con más detalle cómo funciona y por qué puede ser tan útil en proyectos de email marketing.

La lógica de MJML

MJML funciona como una capa intermedia. Tú escribes código MJML y la herramienta lo compila a HTML compatible con email.

Un ejemplo muy sencillo sería este:

<mjml>
  <mj-body>
    <mj-section>
      <mj-column>
        <mj-text>
          Hola, este es un email responsive creado con MJML.
        </mj-text>
        <mj-button href="https://example.com">
          Leer más
        </mj-button>
      </mj-column>
    </mj-section>
  </mj-body>
</mjml>

Ese código no es el que recibe directamente el usuario final. MJML lo transforma en HTML preparado para funcionar mejor en distintos clientes de correo.

MJML vs HTML: no son enemigos

La comparación MJML vs HTML tradicional no debería plantearse como si una opción fuera correcta y la otra incorrecta. En realidad, hablamos de dos formas diferentes de afrontar el mismo problema.

El HTML tradicional te da control directo sobre todo el código final. MJML, en cambio, te permite trabajar de forma más declarativa y delegar parte de la complejidad técnica en el compilador.

Dicho de otra manera: MJML reduce el esfuerzo manual, pero también añade una capa de abstracción. Esa capa puede ser una gran ventaja en la mayoría de proyectos, aunque no siempre será la mejor solución si necesitas un control extremo.

Ventajas de MJML frente al HTML tradicional

MJML destaca especialmente cuando necesitas crear emails responsive de forma rápida, ordenada y mantenible. No elimina por completo los problemas del email development, pero sí reduce muchos de los obstáculos habituales.

Código más limpio y fácil de leer

Una plantilla de email escrita en HTML tradicional puede volverse muy larga rápidamente. Las tablas anidadas, los estilos inline y los condicionales para Outlook hacen que el código sea difícil de leer, incluso para personas con experiencia.

Con MJML, el código fuente resulta más claro. Las secciones, columnas, imágenes, textos y botones tienen etiquetas específicas. Esto facilita la lectura y también el mantenimiento.

Por ejemplo, este bloque:

<mj-section>
  <mj-column>
    <mj-text font-size="20px">
      Nueva colección disponible
    </mj-text>
  </mj-column>
</mj-section>

Es mucho más fácil de interpretar que una estructura equivalente en HTML email tradicional.

Desarrollo más rápido

Una de las mayores ventajas de MJML es la velocidad. Permite crear layouts habituales sin escribir desde cero todo el código necesario para que el email se comporte de forma responsive.

Esto resulta especialmente práctico si trabajas con newsletters recurrentes, emails transaccionales o campañas de contenido. Por ejemplo, si estás empezando a diseñar una newsletter, te puede interesar complementar esta comparativa con la guía sobre cómo crear tu primera newsletter responsive con MJML.

En proyectos donde hay que producir emails con frecuencia, ahorrar tiempo en la estructura técnica permite dedicar más atención al contenido, al diseño y a la estrategia.

Mejor punto de partida para emails responsive

MJML está pensado desde el principio para emails responsive. Sus componentes ya están diseñados para adaptarse a diferentes tamaños de pantalla. Esto no significa que todo vaya a funcionar perfecto sin pruebas, pero sí que partes de una base más sólida que escribiendo HTML desde cero sin experiencia en email.

Por ejemplo, las columnas en MJML se apilan automáticamente en móvil en muchos casos. Esto reduce bastante el trabajo manual y evita errores frecuentes en estructuras responsive.

Menos errores repetitivos

Cuando escribes HTML tradicional para emails, es fácil cometer pequeños errores que pueden romper el diseño: una tabla mal cerrada, una anchura inconsistente, un estilo que no se ha puesto inline o una propiedad CSS poco compatible.

MJML ayuda a reducir este tipo de errores porque genera una estructura HTML más preparada para el entorno email. Esto no sustituye las pruebas, pero sí disminuye la probabilidad de fallos básicos.

Mejor mantenimiento de plantillas

En proyectos con varias plantillas, MJML puede mejorar mucho el mantenimiento. Si tienes una newsletter mensual, emails de bienvenida, emails promocionales y mensajes transaccionales, mantener todo en HTML tradicional puede acabar siendo pesado.

Con MJML, el código fuente suele ser más corto y más comprensible. Esto facilita hacer cambios, reutilizar bloques y mantener una línea visual coherente.

MJML y reducción de carga cognitiva

MJML también reduce la carga cognitiva del desarrollo. No tienes que pensar constantemente en cada tabla, cada celda o cada hack de compatibilidad. Puedes centrarte más en la estructura del mensaje y menos en los detalles repetitivos del HTML email.

Esto es importante porque el desarrollo de emails puede volverse muy mecánico y propenso a errores. Una herramienta que simplifique ese proceso puede mejorar tanto la productividad como la calidad final.

Limitaciones de MJML que conviene tener claras

MJML es muy útil, pero no es una solución mágica. Para usarlo bien, también hay que conocer sus limitaciones.

MJML no elimina la necesidad de probar

El hecho de que MJML genere HTML responsive no significa que puedas olvidarte de las pruebas. Los emails deben revisarse en diferentes clientes de correo, dispositivos y tamaños de pantalla.

Esta es una de las ideas más importantes: MJML facilita el trabajo, pero no garantiza compatibilidad absoluta.

Antes de enviar una campaña, conviene comprobar cómo se ve el email en los clientes más relevantes para tu audiencia. En email marketing, una plantilla que funciona bien en tu entorno de desarrollo puede comportarse de forma diferente en la bandeja de entrada real.

Menos control sobre el HTML final

Con MJML no escribes directamente el HTML definitivo. Escribes una sintaxis que después se transforma. Esto hace que el trabajo sea más cómodo, pero puede ser una limitación si necesitas controlar cada detalle del código generado.

Por ejemplo, puede que quieras aplicar un ajuste muy específico para Outlook, modificar una estructura concreta o adaptar el HTML a las exigencias de una plataforma de envío. En esos casos, quizá tengas que revisar el HTML generado o combinar MJML con soluciones personalizadas.

Tiene su propia curva de aprendizaje

Aunque MJML simplifica mucho la maquetación de emails, también requiere aprender su sintaxis. Necesitas familiarizarte con sus componentes, sus atributos y su forma de estructurar los documentos.

Algunas etiquetas habituales son mjml, mj-head, mj-body, mj-section, mj-column, mj-text, mj-image, mj-button, mj-attributes, mj-style y mj-raw.

No es una curva de aprendizaje especialmente difícil, pero existe. Y si ya sabes HTML email tradicional, puede que al principio sientas que estás añadiendo una capa más al flujo de trabajo.

Dependencia del compilador

MJML necesita compilarse a HTML antes de enviar el email. Esto implica añadir un paso al proceso de desarrollo.

Si trabajas con un flujo moderno basado en Node, scripts, control de versiones o herramientas de automatización, esta dependencia no suele ser un problema. Pero si trabajas directamente dentro de un editor visual de email marketing, puede resultar menos cómodo.

Personalizaciones avanzadas más delicadas

MJML funciona muy bien para estructuras frecuentes: cabeceras, bloques de texto, imágenes, botones, columnas y footers. Sin embargo, cuando el diseño se vuelve muy específico, puede que necesites forzar más la herramienta.

Esto puede ocurrir en emails con diseños editoriales complejos, layouts poco convencionales o requisitos muy concretos de marca.

En esos casos, el HTML tradicional puede darte más libertad.

Ventajas del HTML tradicional para emails

Aunque MJML simplifica mucho el trabajo, el HTML tradicional sigue teniendo un papel importante en el desarrollo de emails.

Control total del código

La mayor ventaja del HTML tradicional es el control. Tú decides cada tabla, cada celda, cada atributo, cada estilo inline y cada comentario condicional.

Esto puede ser fundamental en proyectos donde el email debe cumplir requisitos muy estrictos o donde hay que optimizar el resultado para clientes concretos.

No dependes de una herramienta externa

Con HTML tradicional, el código que escribes es el código que se envía, siempre que la plataforma de email no lo modifique. No necesitas compilar ni añadir pasos intermedios.

Esto puede simplificar el flujo si trabajas en entornos muy manuales o si el equipo no quiere incorporar herramientas adicionales.

Mayor flexibilidad para casos especiales

Si tienes experiencia en HTML email, escribir a mano te permite resolver casos muy concretos. Puedes aplicar hacks específicos, ajustar comportamientos para Outlook o adaptar la estructura al sistema de envío que estés usando.

Esta flexibilidad puede ser muy valiosa en proyectos corporativos, plantillas heredadas o emails muy revisados por equipos de diseño, marketing o legal.

Te ayuda a entender mejor el medio

Aprender HTML tradicional para emails te obliga a comprender las reglas reales del entorno. Entiendes por qué se usan tablas, por qué algunos estilos deben ir inline y por qué ciertas propiedades CSS modernas no son seguras.

Incluso si después decides trabajar con MJML, conocer la base del HTML email te ayudará a depurar mejor cualquier problema.

HTML tradicional como conocimiento de fondo

Lo ideal no es usar MJML sin entender nada del HTML que genera. La mejor combinación suele ser esta: usar MJML para ganar velocidad, pero tener conocimientos suficientes de HTML email para revisar, ajustar y corregir cuando sea necesario.

Limitaciones del HTML tradicional frente a MJML

El HTML tradicional ofrece control, pero también tiene costes importantes.

Código más largo y difícil de mantener

Una plantilla responsive escrita a mano puede crecer mucho. Incluso un bloque aparentemente sencillo puede requerir varias tablas, atributos, estilos inline y ajustes específicos.

Esto dificulta el mantenimiento, sobre todo cuando hay varias plantillas o muchas campañas.

Más tiempo de desarrollo

Crear emails responsive con HTML tradicional lleva más tiempo. No solo por escribir el código, sino también por probarlo, corregirlo y adaptarlo.

En equipos donde se producen emails con frecuencia, ese tiempo puede convertirse en un coste importante.

Mayor riesgo de errores

Cuanto más manual es el proceso, más fácil es cometer errores. Una etiqueta mal cerrada o un estilo colocado en el lugar equivocado puede afectar al diseño final.

En este sentido, MJML ayuda a evitar parte del trabajo repetitivo y reduce algunos errores estructurales.

Menor escalabilidad

Si una marca necesita muchas plantillas, variaciones y bloques reutilizables, mantener todo en HTML tradicional puede volverse poco escalable. Se puede hacer, por supuesto, pero exige mucha disciplina y una arquitectura de componentes bien pensada.

MJML vs HTML tradicional: comparación práctica

Para elegir entre MJML y HTML tradicional, conviene comparar ambos enfoques según criterios concretos.

Facilidad de uso

MJML suele ser más fácil de usar. Su sintaxis es más clara y permite crear estructuras responsive sin escribir todo el HTML manualmente.

HTML tradicional requiere más conocimiento técnico y más atención a los detalles.

Control del resultado

El HTML tradicional gana en control. Si necesitas decidir exactamente cómo será el código final, escribir a mano sigue siendo la opción más directa.

MJML permite personalización, pero trabaja dentro de las reglas de su sistema.

Velocidad de desarrollo

MJML suele ser más rápido, sobre todo para emails estándar: newsletters, promociones, emails de bienvenida o comunicaciones transaccionales.

HTML tradicional puede ser más lento porque exige escribir y revisar más código.

Compatibilidad

La compatibilidad no depende solo de la herramienta. Depende del código final, de las pruebas y de los clientes de correo objetivo.

MJML genera una base bastante preparada, pero no sustituye el proceso de testeo. HTML tradicional puede ser igual de compatible o más, siempre que lo escriba alguien con experiencia en email development.

Mantenimiento

MJML suele ser más mantenible porque el código fuente es más breve y legible.

HTML tradicional puede mantenerse bien si existe una estructura clara, pero tiende a volverse más complejo a medida que crece el número de plantillas.

Cuándo conviene usar MJML

MJML es una buena elección cuando necesitas crear emails responsive de forma rápida, consistente y mantenible.

Puede ser especialmente útil si vas a crear newsletters recurrentes, necesitas varias plantillas similares, quieres reducir errores técnicos, el equipo no tiene mucha experiencia en HTML email, buscas un flujo de trabajo más claro o necesitas reutilizar bloques.

Casos ideales para MJML

MJML encaja muy bien en newsletters corporativas, emails de bienvenida, emails de confirmación, recuperación de contraseña, campañas promocionales, resúmenes mensuales, emails educativos y secuencias automatizadas.

En todos estos casos, la estructura suele ser relativamente estándar: cabecera, bloque principal, contenido, llamada a la acción y footer.

Cuándo conviene usar HTML tradicional

El HTML tradicional puede ser mejor cuando necesitas control total o trabajas con restricciones muy concretas.

Puede interesarte usar HTML tradicional si necesitas personalizar mucho el HTML final, trabajas con plantillas heredadas, tu plataforma de envío modifica el código, tienes requisitos estrictos de compatibilidad, necesitas aplicar hacks específicos o el diseño es muy particular.

Casos ideales para HTML tradicional

El HTML tradicional encaja mejor en emails corporativos muy controlados, plantillas antiguas ya validadas, campañas con requisitos técnicos específicos, sistemas donde no se quiere añadir una fase de compilación y proyectos donde cada detalle visual debe ajustarse manualmente.

En estos casos, la precisión puede pesar más que la velocidad.

Buenas prácticas para decidir entre MJML y HTML

La mejor elección depende del proyecto. No se trata de usar MJML porque sea más cómodo ni HTML tradicional porque parezca más profesional. Se trata de elegir la herramienta que mejor responda a las necesidades reales.

Evalúa la frecuencia de creación

Si vas a crear un email puntual, HTML tradicional puede ser suficiente. Pero si vas a producir emails de forma recurrente, MJML puede ahorrarte mucho tiempo.

Evalúa el nivel técnico del equipo

Si el equipo no tiene experiencia en email development, MJML reduce la barrera de entrada. Si el equipo ya domina HTML email, el HTML tradicional puede seguir siendo una opción sólida.

Evalúa el diseño

Si el diseño es estándar, MJML encaja muy bien. Si el diseño es muy personalizado, quizá necesites HTML tradicional o una combinación de ambos.

Evalúa el flujo de trabajo

Si trabajas con herramientas modernas, control de versiones y procesos de build, integrar MJML es bastante natural. Si todo ocurre dentro de una plataforma visual, quizá el HTML tradicional o el editor propio de la herramienta resulten más prácticos.

Una solución híbrida puede ser la más inteligente

En muchos casos, la mejor opción no es elegir entre MJML o HTML tradicional, sino combinarlos.

Puedes crear la estructura principal en MJML, compilar el HTML y después revisar o ajustar el resultado si es necesario. Este enfoque permite ganar velocidad sin renunciar del todo al control.

También puedes usar MJML para plantillas recurrentes y HTML tradicional para casos especiales.

Errores comunes al comparar MJML vs HTML

Al comparar MJML vs HTML, es fácil caer en algunas ideas demasiado simplificadas.

Pensar que MJML lo soluciona todo

MJML ayuda mucho, pero no elimina todos los problemas del email. Las pruebas siguen siendo necesarias.

Pensar que HTML tradicional siempre es mejor

El control total puede ser útil, pero también implica más trabajo. Si el código se vuelve difícil de mantener, ese control puede convertirse en deuda técnica.

Diseñar emails como si fueran landing pages

Un email no tiene el mismo contexto que una página web. El usuario lo abre en una bandeja de entrada, muchas veces desde el móvil y con poco tiempo de atención.

Por eso, conviene cuidar mucho la claridad del mensaje, la jerarquía visual y las llamadas a la acción. Si usas botones o enlaces, también es importante que sean comprensibles. En este punto, puede ayudarte el artículo sobre por qué los enlaces tipo “haz clic aquí” son un problema de accesibilidad.

No probar antes de enviar

Este error afecta tanto a MJML como a HTML tradicional. Da igual cómo hayas creado el email: si no lo pruebas, estás asumiendo riesgos.

Un email puede verse perfecto en el editor y fallar después en un cliente concreto. Por eso, las pruebas deberían formar parte del proceso, no ser un paso opcional.

Preguntas frecuentes sobre MJML vs HTML tradicional

¿MJML reemplaza completamente al HTML tradicional?

No. MJML no reemplaza el HTML tradicional, sino que lo abstrae. Tú escribes MJML y la herramienta genera HTML. Para trabajar bien con MJML, sigue siendo recomendable entender cómo funciona el HTML email, especialmente si necesitas depurar problemas de compatibilidad.

¿MJML es mejor para crear un html email responsive?

En muchos casos, sí. MJML facilita la creación de un html email responsive porque ofrece componentes pensados para adaptarse a diferentes tamaños de pantalla. Sin embargo, no elimina la necesidad de probar el email en clientes reales ni garantiza que todos los diseños funcionen igual en todas partes.

¿Cuándo debería usar HTML tradicional en lugar de MJML?

Deberías usar HTML tradicional cuando necesites control total sobre el código final, cuando trabajes con restricciones muy específicas o cuando el diseño requiera soluciones que MJML no resuelve fácilmente. También puede ser útil si ya tienes plantillas heredadas bien probadas.

MJML o HTML tradicional: elegir con criterio técnico

La comparación MJML vs HTML tradicional para emails no debería verse como una batalla entre lo moderno y lo clásico. En realidad, se trata de elegir el nivel de abstracción adecuado para cada proyecto.

MJML es una herramienta muy valiosa cuando necesitas crear emails responsive de forma rápida, clara y mantenible. Reduce la complejidad del HTML email, evita parte del trabajo repetitivo y permite centrarte más en la estructura, el contenido y la experiencia de lectura.

El HTML tradicional, por su parte, sigue siendo importante. Te da control, precisión y una comprensión más profunda del medio. En proyectos complejos o con requisitos muy concretos, puede ser la opción más segura.

La mejor decisión suele estar en el equilibrio. Puedes usar MJML para ganar velocidad y mantener una base técnica más limpia, pero cuanto mejor entiendas el HTML que se genera por debajo, más preparada estarás para resolver problemas reales.

Al final, un buen email responsive no es solo el que se ve bonito en una vista previa. Es el que llega bien, se lee bien, funciona en distintos clientes de correo y guía al usuario hacia la acción sin fricción innecesaria.

Animaciones CSS: guía básica para empezar desde cero

Las animaciones CSS son una de esas herramientas que pueden transformar una interfaz sencilla en una experiencia más clara, fluida y agradable. Pero también pueden convertirse en ruido visual si se usan sin intención. Por eso, antes de empezar a añadir movimiento a botones, tarjetas, menús o ilustraciones, conviene entender algo importante: animar con CSS no consiste en decorar por decorar, sino en acompañar al usuario.

Una buena animación puede ayudar a explicar qué está pasando en una interfaz. Puede indicar que un botón es interactivo, que un menú se ha abierto, que una tarjeta ha cambiado de estado o que una acción se ha completado correctamente. En cambio, una animación excesiva, lenta o mal planteada puede aumentar la carga cognitiva, distraer y empeorar la experiencia.

En esta guía básica sobre animaciones CSS vamos a ver desde cero qué son, cuándo usarlas, qué diferencia hay entre transition y animation, cómo funcionan los @keyframes, qué propiedades conviene animar y qué buenas prácticas deberías tener presentes si quieres crear animaciones web útiles, accesibles y mantenibles.

La idea de este artículo es que funcione como un post pilar: una página central desde la que puedas entender los conceptos principales y, después, profundizar en temas concretos como microinteracciones, efectos hover, menús animados, loaders, animaciones accesibles o ilustraciones CSS más complejas. Si también te interesa la parte más visual del CSS, puedes complementar esta guía con el artículo sobre cómo dibujar formas básicas con CSS.

Qué son las animaciones CSS

Las animaciones CSS permiten modificar visualmente uno o varios estilos de un elemento a lo largo del tiempo. En lugar de que un cambio ocurra de forma brusca, puedes hacer que ese cambio sea progresivo.

Por ejemplo, imagina un botón que cambia de color cuando pasas el ratón por encima. Sin animación, el color cambia de golpe. Con una transición, ese cambio puede hacerse de forma suave:

.button {
  background-color: #cc2b5e;
  transition: background-color 0.3s ease;
}

.button:hover {
  background-color: #753a88;
}

Este pequeño detalle ya mejora la percepción de la interfaz. El usuario siente que el elemento responde de forma más natural.

CSS permite crear movimiento principalmente de dos formas: mediante transiciones y mediante animaciones con @keyframes. Las transiciones sirven para animar el cambio entre dos estados de un elemento, por ejemplo un estado normal y un estado :hover. Las animaciones con @keyframes, en cambio, permiten definir varios pasos intermedios dentro de una secuencia más controlada.

Por qué usar animaciones CSS en una web

Las animaciones no deberían estar ahí solo porque “quedan bonitas”. En diseño de interfaces, el movimiento tiene sentido cuando ayuda a comunicar mejor.

Una animación puede cumplir varias funciones dentro de una web:

  • Dar feedback visual.
  • Guiar la atención del usuario.
  • Explicar una relación entre elementos.
  • Suavizar cambios de estado.
  • Hacer que una interfaz se sienta más cuidada.
  • Reforzar la personalidad visual de una marca.

Por ejemplo, una tarjeta que se eleva ligeramente al pasar el cursor comunica que es clicable. Un panel que aparece desde un lateral ayuda a entender de dónde viene ese contenido. Un icono que gira al abrir un acordeón indica que algo ha cambiado de estado.

Ahora bien, también hay que tener cuidado. Si todo se mueve, nada destaca. Una web llena de efectos puede generar cansancio visual y hacer que el usuario tarde más en decidir qué hacer. Aquí conviene pensar en algo muy relacionado con la experiencia de usuario: la diferencia entre captar la atención y aumentar la carga cognitiva. Una animación útil reduce fricción. Una animación innecesaria puede añadir ruido.

Si quieres profundizar más en cómo las decisiones visuales afectan a la comprensión de una interfaz, te puede interesar el artículo sobre HTML semántico y accesibilidad web, porque muchas veces la claridad de una interfaz empieza mucho antes de añadir movimiento.

Transiciones CSS: el primer paso para animar con CSS

Las transiciones CSS son la forma más sencilla de empezar a animar con CSS. Sirven para suavizar el cambio entre dos valores de una propiedad.

Cómo funciona una transición

Una transición necesita, como mínimo, dos cosas: una propiedad que vaya a cambiar y una duración para ese cambio.

.card {
  transform: translateY(0);
  transition: transform 0.25s ease;
}

.card:hover {
  transform: translateY(-8px);
}

Aquí estamos diciendo que la tarjeta parte de su posición original y, cuando el usuario pasa el cursor por encima, se desplaza ligeramente hacia arriba. Ese cambio no sucede de golpe, sino durante 0.25s.

La propiedad transition es una forma abreviada de declarar varias cosas a la vez: qué propiedad se anima, cuánto dura, qué curva de aceleración utiliza y si tiene retraso.

Propiedades principales de transition

Cuando trabajes con transiciones, estas son las propiedades que más vas a utilizar:

.element {
  transition-property: transform;
  transition-duration: 0.3s;
  transition-timing-function: ease;
  transition-delay: 0s;
}

También puedes escribirlo de forma abreviada:

.element {
  transition: transform 0.3s ease 0s;
}

La propiedad transition-property indica qué propiedad se va a animar. transition-duration define la duración. transition-timing-function controla el ritmo de la animación. Y transition-delay permite retrasar el inicio.

Cuándo usar transition

Usa transition cuando quieras animar un cambio sencillo entre dos estados. Es ideal para efectos :hover, estados :focus, botones, tarjetas, enlaces, cambios de color, cambios de opacidad o pequeños desplazamientos.

.link {
  color: #020101;
  text-decoration-thickness: 1px;
  transition: color 0.2s ease, text-decoration-thickness 0.2s ease;
}

.link:hover {
  color: #cc2b5e;
  text-decoration-thickness: 3px;
}

Este tipo de microinteracción puede mejorar mucho la experiencia sin añadir complejidad. Además, es una buena puerta de entrada si estás empezando a animar con CSS.

Animaciones CSS con @keyframes

Cuando necesitas más control que una simple transición, entran en juego las animaciones con @keyframes.

Una animación CSS se compone de dos partes principales: una regla @keyframes, donde defines los pasos de la animación, y una propiedad animation, donde aplicas esa animación a un elemento.

Qué es @keyframes

La regla @keyframes define cómo cambia un elemento durante una animación. Puedes usar from y to, o porcentajes como 0%, 50% y 100%.

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(16px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.hero-title {
  animation: fadeIn 0.6s ease-out both;
}

En este caso, el título aparece progresivamente y sube ligeramente desde abajo. Es una animación típica para introducir contenido en pantalla.

Diferencia entre from/to y porcentajes

Puedes escribir una animación sencilla así:

@keyframes scaleIn {
  from {
    transform: scale(0.9);
    opacity: 0;
  }

  to {
    transform: scale(1);
    opacity: 1;
  }
}

Pero si necesitas más control, puedes usar porcentajes:

@keyframes bounceSoft {
  0% {
    transform: translateY(0);
  }

  50% {
    transform: translateY(-10px);
  }

  100% {
    transform: translateY(0);
  }
}

Los porcentajes permiten definir puntos intermedios. Esto es útil para animaciones más elaboradas, como rebotes, loaders, entradas escalonadas o pequeños efectos decorativos.

Propiedades principales de animation

La propiedad animation también puede escribirse de forma abreviada. Agrupa propiedades como animation-name, animation-duration, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, animation-fill-mode y animation-play-state.

.badge {
  animation: pulse 1.5s ease-in-out infinite;
}

Aquí estamos diciendo que el elemento usará la animación pulse, durará 1.5s, tendrá una curva ease-in-out y se repetirá infinitamente.

La versión extendida sería:

.badge {
  animation-name: pulse;
  animation-duration: 1.5s;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
}

Transition vs animation: cuándo usar cada una

Una de las dudas más habituales al empezar con CSS animation es cuándo usar transition y cuándo usar animation.

Usa transition cuando hay un cambio de estado

Las transiciones son perfectas cuando el elemento cambia como respuesta a una interacción o a una clase añadida con JavaScript.

.menu {
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity 0.25s ease, transform 0.25s ease;
}

.menu.is-open {
  opacity: 1;
  transform: translateY(0);
}

Aquí el menú cambia entre cerrado y abierto. La transición suaviza ese cambio.

Usa animation cuando necesitas una secuencia propia

Las animaciones con @keyframes son más adecuadas cuando el movimiento tiene una secuencia definida que no depende únicamente de un cambio entre dos estados.

Por ejemplo, usarías animation para crear un loader, un icono que pulsa, una ilustración animada, una entrada de contenido o una animación que se repite.

@keyframes rotate {
  to {
    transform: rotate(360deg);
  }
}

.loader {
  animation: rotate 1s linear infinite;
}

En resumen: si solo necesitas suavizar un cambio, usa transition; si necesitas definir una secuencia, usa animation y @keyframes.

Propiedades recomendadas para animar

No todas las propiedades CSS se comportan igual cuando las animas. Algunas son más eficientes y otras pueden afectar al rendimiento de la página.

Prioriza transform y opacity

Cuando sea posible, conviene animar transform y opacity. Son dos propiedades especialmente útiles porque permiten crear muchos efectos visuales sin obligar al navegador a recalcular constantemente la estructura de la página.

.element {
  transition: transform 0.3s ease, opacity 0.3s ease;
}

Con transform puedes crear desplazamientos, escalados, rotaciones e inclinaciones:

.box:hover {
  transform: translateY(-6px) scale(1.02);
}

Con opacity puedes crear apariciones y desapariciones suaves:

.tooltip {
  opacity: 0;
  transition: opacity 0.2s ease;
}

.tooltip.is-visible {
  opacity: 1;
}

Evita animar propiedades costosas

Siempre que puedas, evita animar propiedades como width, height, top, left, margin o padding. No significa que estén prohibidas, pero sí que deberías usarlas con cuidado.

Por ejemplo, en lugar de animar top, suele ser mejor animar transform: translateY().

Menos recomendable:

.modal {
  top: -40px;
  transition: top 0.3s ease;
}

.modal.is-open {
  top: 0;
}

Mejor:

.modal {
  transform: translateY(-40px);
  transition: transform 0.3s ease;
}

.modal.is-open {
  transform: translateY(0);
}

Visualmente el resultado puede ser parecido, pero la segunda opción suele ser más eficiente y más fácil de mantener.

Curvas de animación: el papel del easing

La duración de una animación importa, pero el ritmo también. Ahí entra en juego el concepto de easing, que define cómo progresa la animación a lo largo del tiempo.

No es lo mismo una animación completamente lineal que una animación que empieza despacio, acelera y termina suavemente.

Valores habituales de timing-function

Algunos valores comunes son:

.element {
  transition-timing-function: ease;
}
.element {
  transition-timing-function: linear;
}
.element {
  transition-timing-function: ease-in;
}
.element {
  transition-timing-function: ease-out;
}
.element {
  transition-timing-function: ease-in-out;
}

Cuándo usar cada curva

Para interfaces, ease y ease-out suelen funcionar bien en muchas situaciones porque hacen que el movimiento se sienta más natural.

  • linear: útil para loaders o rotaciones constantes.
  • ease: buena opción general.
  • ease-in: empieza lento y termina más rápido.
  • ease-out: empieza rápido y termina suave.
  • ease-in-out: suaviza tanto la entrada como la salida.
.toast {
  animation: slideIn 0.35s ease-out both;
}

En una notificación, ease-out suele tener sentido porque queremos que aparezca con cierta agilidad y se asiente de forma suave.

Ejemplos básicos de animaciones CSS

Veamos algunos ejemplos prácticos que puedes usar como punto de partida. La idea no es copiar y pegar sin pensar, sino entender el patrón para adaptarlo después a tus propios componentes.

Botón con hover suave

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.85rem 1.25rem;
  border-radius: 999px;
  background: #cc2b5e;
  color: #ffffff;
  font-weight: 700;
  text-decoration: none;
  transition: transform 0.2s ease, background-color 0.2s ease;
}

.button:hover {
  transform: translateY(-2px);
  background: #753a88;
}

Este patrón es sencillo, pero muy útil. El botón responde visualmente sin resultar exagerado.

Tarjeta que aparece al cargar

@keyframes cardEnter {
  from {
    opacity: 0;
    transform: translateY(24px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.card {
  animation: cardEnter 0.5s ease-out both;
}

Aquí usamos both para que el elemento conserve los estilos del primer y último fotograma cuando corresponda.

Loader circular

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.loader {
  width: 2rem;
  height: 2rem;
  border: 3px solid #f8e0ea;
  border-top-color: #cc2b5e;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

En este caso, linear tiene sentido porque queremos una rotación constante.

Aparición escalonada de elementos

@keyframes fadeUp {
  from {
    opacity: 0;
    transform: translateY(16px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.list-item {
  animation: fadeUp 0.45s ease-out both;
}

.list-item:nth-child(2) {
  animation-delay: 0.1s;
}

.list-item:nth-child(3) {
  animation-delay: 0.2s;
}

.list-item:nth-child(4) {
  animation-delay: 0.3s;
}

Este recurso es útil para listas, grids de tarjetas o bloques de contenido. Eso sí: úsalo con moderación. Si una página tiene muchos elementos y todos aparecen con retraso, la experiencia puede volverse lenta.

Si estás trabajando con ilustraciones CSS, este tipo de animaciones también puede combinarse con técnicas como pseudo-elementos o recortes visuales. En ese caso, puedes ampliar el tema con el artículo sobre pseudo-elementos en CSS o con la guía sobre clip-path en CSS.

Accesibilidad en animaciones CSS

La accesibilidad es un punto fundamental cuando hablamos de animaciones web. No todas las personas perciben el movimiento de la misma manera. Para algunos usuarios, ciertas animaciones pueden provocar mareo, incomodidad o dificultad para concentrarse.

Por eso, CSS ofrece la media feature prefers-reduced-motion, que permite detectar si una persona ha activado en su sistema una preferencia para reducir el movimiento no esencial.

Cómo usar prefers-reduced-motion

Una forma habitual de aplicarlo es reducir o eliminar animaciones cuando el usuario ha indicado esa preferencia:

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
    transition-duration: 0.01ms !important;
  }
}

Este enfoque es bastante global. En proyectos reales, también puedes crear alternativas más cuidadas en lugar de eliminar todo de golpe.

@media (prefers-reduced-motion: reduce) {
  .hero-title {
    animation: none;
  }

  .card:hover {
    transform: none;
  }
}

Animar no debería bloquear la comprensión

Una animación accesible debería cumplir estas ideas:

  • No debe ser imprescindible para entender el contenido.
  • No debe impedir usar la interfaz.
  • No debe ejecutarse de forma infinita sin motivo.
  • No debe parpadear agresivamente.
  • No debe generar desplazamientos inesperados.
  • Debe poder reducirse si el usuario lo necesita.

Una buena regla práctica es esta: si quitas la animación, la interfaz debería seguir funcionando y entendiéndose perfectamente.

También es importante no olvidar los estados de teclado. Si una animación acompaña el estado :hover, muchas veces debería contemplar también :focus-visible. Puedes profundizar en esta parte en el artículo sobre focus visible y navegación con teclado.

Buenas prácticas para crear animaciones CSS

Crear buenas animaciones no depende solo de saber escribir @keyframes. También implica criterio visual, intención de diseño y cuidado técnico.

1. Empieza con movimientos pequeños

Cuando estás empezando, es fácil pasarse. Una tarjeta no necesita volar por la pantalla para comunicar que es interactiva. A menudo basta con un pequeño cambio de opacidad, color o posición.

.card:hover {
  transform: translateY(-4px);
}

Un movimiento pequeño suele sentirse más elegante y menos invasivo.

2. Usa duraciones cortas

En interfaces, muchas animaciones funcionan bien entre 150ms y 400ms. No es una regla absoluta, pero sí un buen punto de partida.

  • Microinteracciones: 150ms250ms.
  • Entradas de elementos: 300ms500ms.
  • Animaciones decorativas: depende del caso, pero conviene usarlas con cuidado.

Una animación demasiado rápida puede pasar desapercibida. Una demasiado lenta puede hacer que la web parezca pesada.

3. Mantén consistencia

Si cada botón, tarjeta y modal usa una duración diferente, la interfaz puede sentirse caótica. Es mejor definir un pequeño sistema de tiempos:

:root {
  --duration-fast: 150ms;
  --duration-base: 250ms;
  --duration-slow: 400ms;
  --ease-base: ease;
}

Y después reutilizarlo:

.button {
  transition: transform var(--duration-base) var(--ease-base);
}

Esto ayuda a que el proyecto sea más mantenible.

4. No animes todo

Una web con demasiadas animaciones puede parecer menos profesional. El movimiento debe tener jerarquía. Antes de añadir una animación, pregúntate si ayuda a entender algo, si aporta feedback, si guía la atención o si simplemente está ahí porque se puede hacer.

Si no cumple ninguna función clara, probablemente sobra.

Errores comunes al empezar con CSS animation

Cuando empiezas a trabajar con CSS animation, es normal cometer algunos errores. Lo importante es detectarlos pronto para que las animaciones no perjudiquen la experiencia.

Animar propiedades equivocadas

Uno de los errores más frecuentes es animar propiedades que afectan al layout cuando podrías usar transform.

Menos recomendable:

.box:hover {
  width: 120%;
}

Mejor:

.box:hover {
  transform: scale(1.05);
}

Usar infinite sin necesidad

Las animaciones infinitas deben reservarse para casos concretos, como loaders o pequeños indicadores de actividad. Si un elemento decorativo se mueve todo el tiempo, puede distraer mucho.

.icon {
  animation: pulse 1s infinite;
}

Antes de usar algo así, pregúntate si realmente necesita repetirse siempre.

Crear animaciones demasiado largas

Una animación larga puede parecer elegante en una demo, pero molesta en una interfaz real. El usuario no quiere esperar a que la web termine de “presentarse” para poder interactuar.

Olvidar el estado focus

Muchas veces se anima :hover, pero se olvida :focus-visible. Esto deja fuera a quienes navegan con teclado.

.button:hover,
.button:focus-visible {
  transform: translateY(-2px);
}

Las animaciones también deben acompañar la accesibilidad de la interacción, no solo el uso con ratón.

Cómo organizar animaciones CSS en un proyecto real

Cuando un proyecto crece, conviene evitar animaciones sueltas y repetidas por todo el CSS. Puedes crear una pequeña arquitectura de movimiento para que todo sea más coherente.

Variables para tiempos y curvas

:root {
  --motion-duration-fast: 150ms;
  --motion-duration-base: 250ms;
  --motion-duration-slow: 400ms;

  --motion-ease-standard: ease;
  --motion-ease-enter: ease-out;
  --motion-ease-exit: ease-in;
}

Clases reutilizables

.animate-fade-up {
  animation: fadeUp var(--motion-duration-slow) var(--motion-ease-enter) both;
}

.transition-base {
  transition-duration: var(--motion-duration-base);
  transition-timing-function: var(--motion-ease-standard);
}

Keyframes centralizados

@keyframes fadeUp {
  from {
    opacity: 0;
    transform: translateY(16px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

Este enfoque hace que las animaciones sean más coherentes y fáciles de ajustar. Si más adelante decides que las entradas son demasiado lentas, puedes cambiar una variable en lugar de revisar decenas de componentes.

Una nota sobre diseño responsive

También conviene probar las animaciones en distintos tamaños de pantalla. Un desplazamiento que se ve sutil en escritorio puede sentirse excesivo en móvil. Si trabajas mucho con composición visual en CSS, te recomiendo revisar también el artículo sobre cómo adaptar ilustraciones CSS a distintos tamaños de pantalla.

Animaciones CSS como parte de una estrategia de contenidos

Este artículo está pensado como una guía base sobre animaciones CSS, pero el tema da para mucho más. Por eso tiene sentido usarlo como página central de un cluster de contenidos.

Desde aquí puedes enlazar, por ejemplo, a artículos más específicos sobre:

  • Cómo usar transition en CSS.
  • Cómo crear animaciones con @keyframes.
  • Efectos hover modernos con CSS.
  • Animaciones CSS para botones.
  • Cómo animar menús responsive.
  • Loaders CSS sin JavaScript.
  • Animaciones accesibles con prefers-reduced-motion.
  • Errores de rendimiento al animar con CSS.
  • Microinteracciones CSS para mejorar la UX.
  • Diferencias entre animaciones CSS y animaciones JavaScript.

Esta estructura ayuda tanto al usuario como al SEO. El usuario encuentra una ruta de aprendizaje clara. Y Google puede entender mejor la relación semántica entre los artículos del sitio.

Un post pilar no debería intentar resolver todos los temas con profundidad extrema. Su función es ordenar el mapa, explicar los conceptos base y derivar hacia contenidos complementarios más concretos.

Preguntas frecuentes sobre animaciones CSS

¿Qué diferencia hay entre transition y animation en CSS?

transition sirve para suavizar el cambio entre dos estados de un elemento, por ejemplo cuando un botón pasa de su estado normal a :hover. animation, en cambio, permite crear una secuencia más completa mediante @keyframes, con pasos intermedios, repeticiones, retrasos y mayor control.

¿Qué propiedades CSS conviene animar?

Siempre que sea posible, conviene animar transform y opacity, porque suelen ser más eficientes para el navegador. Con transform puedes crear desplazamientos, escalados y rotaciones. Con opacity puedes controlar apariciones y desapariciones suaves.

¿Las animaciones CSS son mejores que las animaciones con JavaScript?

No siempre. Las animaciones CSS son ideales para microinteracciones, transiciones sencillas, loaders básicos y efectos visuales ligados a estilos. JavaScript puede ser más adecuado cuando necesitas controlar una animación de forma dinámica, responder a eventos complejos, sincronizar estados o crear interacciones avanzadas. La mejor opción depende del problema que quieras resolver.

Movimiento con intención

Las animaciones CSS son una herramienta poderosa, pero su valor no está en el movimiento por sí mismo. Su valor está en cómo ese movimiento ayuda a que una interfaz se entienda mejor.

Una buena animación no interrumpe. No compite con el contenido. No obliga al usuario a esperar. Simplemente acompaña: guía la mirada, suaviza los cambios, refuerza la interacción y hace que la experiencia se sienta más cuidada.

Si estás empezando desde cero, no necesitas memorizar todas las propiedades de golpe. Empieza con transition, practica con transform y opacity, crea tus primeros @keyframes y observa cómo cambia la percepción de una interfaz cuando el movimiento tiene intención.

Animar con CSS no es añadir efectos porque sí. Es tomar decisiones pequeñas, pero importantes, sobre cómo se comporta una web. Y cuando esas decisiones están bien pensadas, las animaciones dejan de ser un adorno para convertirse en parte de la experiencia de usuario.