Animation — @keyframes, animation xususiyatlari

~20 daq · CSS · Animatsiya va Ilg'or mavzular

Muammodan boshlaylik

transition (28-dars) faqat ikki holat orasida ishlaydi va sabab kerak: hover, fokus, class o'zgarishi. Lekin ba'zi animatsiyalar o'zi ishlashi kerak:

  • Yuklanish spinneri — to'xtovsiz aylanadi
  • Sahifa ochilganda elementlar ketma-ket paydo bo'ladi
  • "Skeleton" — kontent yuklanguncha miltillaydigan kulrang bloklar
  • Bildirishnoma qo'ng'irog'i — tebranadi

Buning uchun — @keyframes (kalit kadrlar) va animation xususiyati.


@keyframes — animatsiya ssenariysi

@keyframes paydo-bolish {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
  • @keyframes dan keyin — nom (o'zingiz tanlaysiz)
  • from (0%) — boshlang'ich holat, to (100%) — oxirgi holat
  • Brauzer oraliq holatlarni o'zi hisoblaydi

Ko'proq bosqich — foizlar bilan:

@keyframes tebranish {
  0%, 100% { transform: rotate(0); }
  20%      { transform: rotate(-12deg); }
  40%      { transform: rotate(10deg); }
  60%      { transform: rotate(-6deg); }
  80%      { transform: rotate(4deg); }
}

Bir xil holatli kadrlarni vergul bilan birlashtirish mumkin: 0%, 100%.


animation — elementga qo'llash

.card {
  animation: paydo-bolish 400ms ease-out;
}

Sahifa ochilishi bilan kartochka pastdan yumshoq paydo bo'ladi. Hech qanday hover yoki JavaScript kerak emas.

Barcha xususiyatlar

Xususiyat Nima Misol
animation-name @keyframes nomi paydo-bolish
animation-duration Bitta sikl davomiyligi 400ms
animation-timing-function Tezlik egri chizig'i (28-dars) ease-out, linear
animation-delay Boshlanishdan oldin kutish 200ms
animation-iteration-count Necha marta 1, 3, infinite
animation-direction Yo'nalish normal, reverse, alternate
animation-fill-mode Oldin/keyin qaysi holatda turish none, forwards, backwards, both
animation-play-state To'xtatish running, paused

Qisqa yozuv:

animation: aylanish 1s linear infinite;
animation: paydo-bolish 400ms ease-out 200ms both;
/*         nom          davom. egri    kechik. fill-mode */

Davomiylik birinchi, kechikish ikkinchi vaqt qiymati — tartib muhim.


fill-mode — eng ko'p chalkashlik

Standartda animatsiya tugagach element asl CSS holatiga qaytadi, va kechikish paytida ham asl holatda turadi:

.card {
  animation: paydo-bolish 400ms ease-out 500ms;
}
0–500ms (kechikish):  kartochka TO'LIQ KO'RINIB turadi (asl holat)
500ms:                birdaniga opacity: 0 ga sakraydi — animatsiya boshlandi
500–900ms:            paydo bo'ladi

Kartochka avval ko'rinadi, keyin yo'qolib, qaytadan paydo bo'ladi — xunuk "miltillash".

fill-mode Kechikish paytida Tugagandan keyin
none (standart) Asl holat Asl holat
backwards Birinchi kadr (from) Asl holat
forwards Asl holat Oxirgi kadr (to) qoladi
both Birinchi kadr Oxirgi kadr

Paydo bo'lish animatsiyalari uchun deyarli har doim both.


direction va iteration

.pulse {
  animation: nafas 2s ease-in-out infinite alternate;
}

@keyframes nafas {
  from { transform: scale(1); }
  to   { transform: scale(1.08); }
}

alternate — har bir toq sikl oldinga, juft sikl orqaga: kattalashadi → kichrayadi → kattalashadi. to dan from ga qaytishni alohida yozish shart emas.


Amaliy misollar

Yuklanish spinneri

.spinner {
  width: 24px;
  height: 24px;
  border: 3px solid #e2e8f0;
  border-top-color: #2563eb;
  border-radius: 50%;
  animation: aylanish 800ms linear infinite;
}

@keyframes aylanish {
  to { transform: rotate(1turn); }
}

from yo'q — brauzer elementning joriy holatini boshlang'ich deb oladi. Aylanish uchun — linear (tezlik bir tekis).

Ketma-ket paydo bo'lish (stagger)

.list > * {
  animation: paydo-bolish 400ms ease-out both;
}

.list > :nth-child(1) { animation-delay: 0ms; }
.list > :nth-child(2) { animation-delay: 60ms; }
.list > :nth-child(3) { animation-delay: 120ms; }
.list > :nth-child(4) { animation-delay: 180ms; }

CSS o'zgaruvchisi bilan qisqaroq (6-dars):

<li style="--i: 0">...</li>
<li style="--i: 1">...</li>
<li style="--i: 2">...</li>
.list > * {
  animation: paydo-bolish 400ms ease-out both;
  animation-delay: calc(var(--i) * 60ms);
}

Skeleton yuklanish

.skeleton {
  background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%);
  background-size: 200% 100%;
  animation: shimmer 1.4s ease-in-out infinite;
  border-radius: 6px;
}

@keyframes shimmer {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}

Kulrang blok bo'ylab yorug' to'lqin o'tadi — "kontent yuklanyapti" degan signal, bo'sh oq ekrandan ancha yaxshiroq his.

Pauza

.marquee:hover {
  animation-play-state: paused;    /* sichqoncha ustida — to'xtaydi */
}

transition yoki animation?

transition animation + @keyframes
Boshlanishi Holat o'zgarganda (hover, class) O'zi — sahifa yuklanganda yoki class qo'shilganda
Holatlar Faqat ikkita (A → B) Istalgancha (0%, 30%, 70%, 100%)
Takrorlash Yo'q infinite
Qachon Hover, fokus, ochish-yopish Spinner, paydo bo'lish, diqqat jalb qilish, skeleton

Qoida: foydalanuvchi harakatiga javob — transition; o'zi ishlaydigan yoki murakkab ketma-ketlik — animation.


Tezlik va hurmat

28-dars qoidalari bu yerda ham amal qiladi:

  • @keyframes ichida faqat transform va opacity — silliq 60 fps. width, top, margin — telefonda qotadi
  • prefers-reduced-motion (26-dars) — cheksiz va katta harakatli animatsiyalarni o'chiring:
@media (prefers-reduced-motion: reduce) {
  .pulse,
  .marquee {
    animation: none;
  }
}
  • Cheksiz animatsiyalar diqqatni chalg'itadi — faqat haqiqatan kerak bo'lganda (spinner, yuklanish holati). Sekundiga 3 martadan ko'p miltillash — epilepsiya xavfi.

Nima uchun shunday?

Nima uchun animatsiyalarni JavaScript bilan emas, CSS bilan yozish tavsiya etiladi?

Chunki CSS animatsiyani brauzer oldindan biladi: qaysi xususiyat, qancha vaqt, qanday egri chiziq. Bu ma'lumot bilan u animatsiyani asosiy JavaScript oqimidan ajratib, alohida (compositor) oqimda, GPU da bajarishi mumkin — sahifadagi JavaScript og'ir hisob-kitob bilan band bo'lsa ham, spinner silliq aylanishda davom etadi. JavaScript animatsiyasi esa har bir kadrda kod bajarishni talab qiladi va asosiy oqim band bo'lsa "qotadi". JavaScript faqat haqiqatan dinamik narsalar uchun kerak: foydalanuvchi barmog'iga ergashish, fizik simulyatsiya, murakkab ketma-ketliklar (Web Animations API yoki GSAP kabi kutubxonalar).


Xulosa

Eslab qoling:

  • @keyframes nom { from {} to {} } yoki foizlar bilan — animatsiya ssenariysi
  • animation: nom davomiylik egri-chiziq kechikish takror yo'nalish fill-mode
  • infinite — cheksiz; alternate — oldinga-orqaga
  • fill-mode: both — kechikishda birinchi kadr, oxirida oxirgi kadr (miltillash yo'q)
  • Spinner — linear infinite; ketma-ket paydo bo'lish — animation-delay + calc(var(--i) * 60ms)
  • animation-play-state: paused — to'xtatish
  • transition — javob; animation — o'zi ishlaydi
  • Faqat transform/opacity; prefers-reduced-motion ni hurmat qiling

Keyingi dars

31-dars: Pseudo-class — :is(), :where(), :has(), :not()