Animar desde scale(0) no es una decisión de diseño. Es teleportación.
Un modal aparece desde el centro de la pantalla. Escala de cero a uno. Se ve como PowerPoint.
Cambias el valor inicial a 0.97. El modal ahora emerge. La diferencia son tres puntos porcentuales. La percepción es completamente distinta.
No es magia. Es física.
Por qué scale(0) viola una expectativa
Nada en el mundo real aparece de la nada. Los objetos entran al campo visual — desde un borde, desde detrás de otro elemento, emergiendo desde una superficie. Tienen origen. Tienen trayectoria.
Un elemento que escala desde cero no entra. Aparece. El cerebro procesa eso como un glitch, no como movimiento con información.
El problema no es la animación. Es el valor inicial.
La diferencia no está en la duración ni en el easing — esos están documentados en Cuándo no animar. Está en el punto de partida.
El origen espacial importa tanto como el valor inicial
Hay un segundo error que ocurre junto al primero: el elemento animado escala desde su propio centro geométrico, no desde su trigger.
Un dropdown que escala desde el centro del viewport no tiene relación espacial con el botón que lo abrió. La animación ocurre en el lugar equivocado.
La regla es simple: el elemento debe emerger desde donde fue invocado.
Un dropdown abierto desde un botón en la esquina superior derecha debería escalar desde esa esquina. Un tooltip debería aparecer desde el elemento al que pertenece. Un popover desde su trigger exacto.
Esto no es solo estética. Es causalidad visual. El usuario necesita ver que el elemento que aparece tiene relación con la acción que ejecutó. Cuando el origen es incorrecto, la interfaz parece que hace cosas por su cuenta.
En CSS el origen se controla con transform-origin. En la mayoría de los componentes de librería este valor nunca se toca — va a center center por defecto. Ese default es incorrecto para casi todos los casos de uso reales.
/* Dropdown abierto desde un trigger arriba a la derecha */
.dropdown {
transform-origin: top right;
animation: enter 160ms ease-out;
}
@keyframes enter {
from { transform: scale(0.95); opacity: 0; }
to { transform: scale(1); opacity: 1; }
}
El valor inicial no es universal
El mismo valor inicial no funciona para todos los elementos. La amplitud correcta depende del tamaño del elemento y de su propósito.
Un modal grande que escala desde 0.85 se siente como si alguien lo lanzara hacia ti. Un tooltip que escala desde 0.99 prácticamente no animó — la animación no comunicó nada.
La tabla que falta en la mayoría de los design systems:
| Elemento | Scale inicial | Por qué |
|---|---|---|
| Modal, drawer | 0.97 |
Grande — poca amplitud, mucho peso |
| Dropdown, popover | 0.95 |
Medio — amplitud moderada desde el trigger |
| Tooltip | 0.85 |
Pequeño — más amplitud, movimiento relativo menor |
| Toast, notificación | Sin scale | Entra desde el borde, solo translate + opacity |
| Badge, chip | 0.8 |
Pequeño y puntual — la amplitud confirma la aparición |
Los toasts y notificaciones de sistema son el caso especial. No escalan — entran desde fuera del viewport con translate. Una notificación que escala desde el centro compite visualmente con el contenido principal y no tiene origen espacial coherente.
El gap entre Figma y producción
Este es el problema real para un equipo.
En Figma diseñas el estado final. Smart Animate interpola entre frames. Se ve bien en el prototipo porque Figma nunca hace scale desde cero — el valor inicial está implícito en cómo construiste el componente.
El developer recibe la spec. Ve «animación de entrada, modal, ease-out». Implementa:
@keyframes enter {
from { transform: scale(0); opacity: 0; }
to { transform: scale(1); opacity: 1; }
}
transform-origin.No es un error de código. Es un error de documentación de sistema.
Un design system que no especifica el valor inicial de cada tipo de animación de entrada no está completo. El componente Modal en Figma debería tener anotado en su spec:
Entrada:
scale inicial: 0.97
opacity inicial: 0
transform-origin: center (ajustar según posición del trigger)
Referencia: token --animation-modal-enter
Si el developer tiene que adivinar el valor inicial, el sistema falló antes de que escribiera una línea de código.
La regla
El valor inicial nunca es cero.
El transform-origin siempre apunta al trigger.
Y en el design system: cada componente flotante tiene su valor inicial y su origen documentados. No en un Notion que nadie lee — en la propia especificación del componente en Figma.