Tranziții și animații
transition vs @keyframes, easing, ce se poate anima ieftin, prefers-reduced-motion.
Actualizat
Ce sunt tranzițiile și animațiile
Mișcarea în interfață are un rol, nu e decor: arată ce s-a schimbat, de unde vine un element și că acțiunea ta a avut efect. CSS îți dă două unelte:
| Transition | Animation (@keyframes) |
|
|---|---|---|
| Pornește | când o proprietate se schimbă (hover, clasă nouă) | singură, la apariție, sau în buclă |
| Stări | de la A la B | oricâți pași (0%, 50%, 100%) |
| Când | hover, focus, deschidere / închidere, feedback | loader, intrare în pagină, atenționare |
Transition
.btn {
transition: background-color 150ms ease, transform 150ms ease;
}
.btn:hover {
background-color: var(--accent-hover);
transform: translateY(-1px);
}transition: <proprietate> <durată> <easing> <întârziere>. Evită transition: all — animă și proprietăți pe care nu le vrei (și costă).
@keyframes și animation
@keyframes fade-in {
from { opacity: 0; transform: translateY(8px); }
to { opacity: 1; transform: none; }
}
.toast {
animation: fade-in 200ms ease-out both;
}| Proprietate | Rol |
|---|---|
animation-duration |
cât durează |
animation-timing-function |
curba de viteză |
animation-iteration-count |
de câte ori (infinite pentru loader) |
animation-fill-mode: both |
păstrează stilul de început înainte și de final după |
Easing — curba de viteză
| Easing | Senzație | Când |
|---|---|---|
ease-out |
pornește repede, încetinește | elemente care apar — cea mai naturală |
ease-in |
pornește lent, accelerează | elemente care dispar |
ease-in-out |
lent – rapid – lent | mișcări dintr-un loc în altul |
linear |
constantă | rotații, progres, loadere |
Durate: 100–200 ms pentru feedback (hover), 200–300 ms pentru apariții, rar peste 400 ms. Animațiile lungi fac interfața să pară lentă.
Ce animezi — performanța
Animă doar transform și opacity: se calculează pe GPU, fără layout. width, height, top, margin declanșează layout la fiecare cadru → animație sacadată. Explicația în Cum desenează browserul.
| În loc de | Folosește |
|---|---|
left: 0 → 100px |
transform: translateX(100px) |
width: 0 → 100% (bară de progres) |
transform: scaleX(0 → 1) |
display: none ↔ block |
opacity + visibility, sau @starting-style |
Respectă preferința userului
Unii oameni au rău de mișcare sau sensibilitate vestibulară și activează „reduce motion” în sistem. Obligatoriu:
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}În Tailwind: motion-safe:animate-… / motion-reduce:transition-none.
Moderne: apariție din display: none
.dialog[open] {
opacity: 1;
transition: opacity 200ms, display 200ms allow-discrete;
@starting-style { opacity: 0; }
}@starting-style definește starea „de dinaintea apariției” — poți anima elemente care tocmai au trecut din display: none. Pentru tranziții între pagini există View Transitions API.
Mai departe
Pentru animații în React (Motion), timeline-uri și scroll (GSAP) și exemple complete, vezi tema Animații.
Pe scurt
- Transition = de la A la B la o schimbare; animation =
@keyframes, pornește singură. ease-outla apariție, 150–300 ms; doartransformșiopacity.prefers-reduced-motionobligatoriu.