IlmHamroh
JavaScript Full-stack/6-qism. CSS: harakat, zamonaviy CSS va dizayn3/57-dars25 daqiqa
Mundarija (42)

CSS transition: holatlar orasida silliq o'tish va timing funksiyalari

Qisqacha: transition xususiyat qiymati o'zgarganda uni bir zumda emas, berilgan vaqt ichida silliq o'zgartiradi: transition: translate 0.2s ease-out. U o'zgaradigan holatga emas, elementning asosiy qoidasiga yoziladi — shunda ikkala yo'nalish ham silliq bo'ladi. Timing funksiyasi (ease-out, cubic-bezier(), steps(), linear()) harakatning "xarakterini" beradi. Interfeysda odatda 150–300 ms va ease-out ishlatiladi.

Bu darsda

  • transition ning to'rt qismini — xususiyat, davomiylik, timing funksiyasi, kechikish — yozasiz va qisqa yozuvini o'qiysiz.
  • Qaysi xususiyatlar silliq o'zgaradi va qaysilari sakraydi — farqlaysiz.
  • ease, ease-out, cubic-bezier(), steps() va linear() ni tanlaysiz va ular harakatni qanday o'zgartirishini tushuntirasiz.
  • Interfeys uchun to'g'ri davomiylikni tanlaysiz va harakatni kamaytirish sozlamasini hurmat qilasiz.
  • transitionend hodisasi va transitionning kaskaddagi o'rnini bilasiz.

Oldin bilishingiz kerak: 2D transformlar, 3D transformlar, Holat pseudo-klasslari, Foydalanuvchi afzalliklari.

1. Nega bu kerak?

2D transformlar darsida «Bahor» kartasi sichqoncha kelganda 6 piksel ko'tarilardi. Lekin bir zumda: bir kadrda pastda, keyingisida tepada. Ko'z buni "sakrash" deb ko'radi.

Hayotda narsalar bunday harakatlanmaydi. Choyxona eshigi bir zumda ochilib qolmaydi — u tezlik olib, sekinlashib, to'xtaydi. Liftning eshigi ham, telefon ekranidagi oyna ham shunday. Silliq o'zgarish ko'zga "nima bo'ldi va qayerdan qayerga" ekanini tushuntiradi. Sakrash esa buni yashiradi.

Holat pseudo-klasslari darsida ham va'da bergan edik: tugma bosilganda "botib ketish"ni silliq qilamiz. Buning uchun bitta xususiyat kerak — transition.

2. Birinchi transition

2.1 Bir qator farq

Ikki kartani solishtiramiz. Ikkalasi ham hover'da ko'tariladi, faqat ikkinchisida bitta qo'shimcha qator bor:

html
<style>
  :root {
    --rang-asosiy: #2f6b3a;
    --rang-fon: #fffaf0;
  }
  body { font-family: system-ui, sans-serif; }
  ul {
    display: flex;
    gap: 1rem;
    padding: 1rem 0 0;
    list-style: none;
  }
  li { display: grid; }
  .taom-karta {
    width: 10rem;
    padding: 0.75rem 1rem;
    border: 2px solid var(--rang-asosiy);
    border-radius: 0.5rem;
    background-color: var(--rang-fon);
  }
  .taom-karta p { margin: 0; }
  li:hover > .taom-karta {
    translate: 0 -8px;
  }
  .silliq {
    transition: translate 0.2s ease-out;
  }
</style>
<ul>
  <li>
    <article class="taom-karta">
      <h3>Osh</h3>
      <p>transition'siz</p>
    </article>
  </li>
  <li>
    <article class="taom-karta silliq">
      <h3>Osh</h3>
      <p>transition bilan</p>
    </article>
  </li>
</ul>

Nimaga qarang: sichqonchani chap kartaga olib boring — u bir zumda sakraydi. O'ng karta esa 0.2 soniyada suzib ko'tariladi va sichqonchani olib ketsangiz, xuddi shunday silliq tushadi. Farq — bitta qator: transition: translate 0.2s ease-out.

Transition (o'tish) — xususiyat qiymati o'zgarganda brauzerga "eski qiymatdan yangisiga bir zumda emas, shuncha vaqtda o't" deydigan xususiyat. Brauzer oraliq qiymatlarni o'zi hisoblaydi: 0 dan −8 pikselgacha har kadrda biroz suradi. Eslatma: kadr (frame) — ekran bir lahzada ko'rsatadigan bitta surat, odatda soniyasiga 60 ta (Critical Rendering Path darsida ko'rgan edingiz).

2.2 Qayerga yoziladi

Diqqat qiling: transition :hover qoidasiga emas, kartaning asosiy qoidasiga (.silliq) yozilgan. Nega?

Transition "o'zgarish sodir bo'lganda qanday o'tish" haqidagi qoida. Brauzer uni yangi holatdan oladi:

  • Sichqoncha keldi: yangi holat — hover. Asosiy qoidadagi transition hover'da ham amal qiladi → ko'tarilish silliq.
  • Sichqoncha ketdi: yangi holat — oddiy. U yerda ham transition bor → tushish ham silliq.

Agar transition ni faqat :hover ga yozsangiz, ko'tarilish silliq bo'ladi, tushish esa sakraydi — oddiy holatda transition yo'q. Bu ko'p uchraydigan xato. Lekin ba'zan aynan shu kerak: ikki yo'nalishga har xil tezlik. Buni pastda, "Davomiylik" bo'limida ko'ramiz.

Tekshirib ko'ring: Tugma qoidasi: button { background-color: green; }, button:hover { background-color: darkgreen; transition: background-color 0.3s; }. Sichqoncha kelganda va ketganda nima bo'ladi?

Javob

Kelganda rang 0.3 soniyada silliq to'qlashadi — yangi holat (:hover) da transition bor. Ketganda rang bir zumda yashilga qaytadi — yangi holat oddiy button, unda transition yo'q. Ikkala yo'nalish silliq bo'lishi uchun transition ni button qoidasiga ko'chiring.

3. To'rt qism va qisqa yozuv

3.1 To'liq yozuv

transition — qisqa yozuv. U to'rtta xususiyatni birlashtiradi:

Xususiyat Nima Misol
transition-property Qaysi xususiyat silliq o'zgarsin translate, opacity, all
transition-duration Qancha davom etsin 0.2s, 200ms
transition-timing-function Qanday tezlik bilan ease-out
transition-delay Qancha kutib boshlansin 0s, 100ms

Vaqt birliklari — s (soniya) va ms (millisoniya): 0.2s = 200ms. Birlik majburiy, hatto nolda ham: transition: translate 200 — xato, brauzer butun deklaratsiyani tashlaydi (CSS nima darsidagi "birlik majburiy" qoidasi).

3.2 Qisqa yozuv tartibi

css
.taom-karta {
  transition: translate 0.2s ease-out 0.1s;
  /*          xususiyat davomiylik timing kechikish */
}

Tartib erkin, faqat bitta qoida bor: birinchi vaqt — davomiylik, ikkinchi vaqt — kechikish. Timing funksiyasi va xususiyat nomini brauzer ko'rinishidan taniydi.

3.3 Bir nechta xususiyat

Ro'yxat vergul bilan yoziladi — har xususiyatga o'z vaqti:

css
.taom-karta {
  transition:
    translate 0.2s ease-out,
    box-shadow 0.3s ease-out,
    border-color 0.15s linear;
}

Diqqat: transition ham bitta xususiyat. 2D transformlar darsidagi tuzoqni eslang: keyingi qoidadagi transition butun ro'yxatni almashtiradi. Karta hover'ida transition: translate 0.3s yozsangiz, box-shadow va border-color ning o'tishi yo'qoladi. Ro'yxatni to'liq takrorlang.

3.4 all — qulay, lekin xavfli

transition: all 0.3s — "hamma o'zgarayotgan xususiyat silliq bo'lsin". Qulay ko'rinadi, lekin uchta muammo bor:

  1. Kutilmagan animatsiya. Keyinchalik kimdir kartaga padding yoki width o'zgarishini qo'shadi — u ham sekin "suzib" o'zgaradi. Qorong'i rejimga o'tganda butun sahifaning ranglari 0.3 soniya "oqib" o'zgaradi.
  2. Tezlik. Brauzer har o'zgarishni kuzatishi kerak. width kabi layout xususiyatlari silliq o'zgarsa, har kadrda layout qayta hisoblanadi (Rendering va samaradorlik).
  3. O'qish qiyin. Kodni o'qigan odam nima silliq bo'lishini bilmaydi.

Qoida: nimani silliq qilmoqchi ekaningizni nomi bilan yozing. all — faqat tez sinab ko'rish uchun.

Tekshirib ko'ring: transition: 0.3s opacity 0.1s ease-in; — qaysi qiymat nima?

Javob

Xususiyat — opacity, davomiylik — 0.3s (birinchi vaqt), kechikish — 0.1s (ikkinchi vaqt), timing funksiyasi — ease-in. Tartib g'alati, lekin to'g'ri: brauzer faqat ikki vaqtning tartibiga qaraydi.

4. Nima silliq o'zgaradi, nima sakraydi

4.1 Oraliq qiymati bor xususiyatlar

Transition ishlashi uchun brauzer ikki qiymat orasidagi qiymatni hisoblay olishi kerak. 0 va 8 piksel orasida — 4 piksel. Yashil va qizil orasida — aralash rang. Bunday xususiyatlar animatsiyalanadigan (animatable) deyiladi:

  • uzunlik va sonlar: translate, width, padding, opacity, font-weight;
  • ranglar: color, background-color, border-color;
  • transformlar, soyalar (box-shadow), filter.

"Osh" va "lag'mon" orasida esa oraliq yo'q. display: block va none orasida ham. Bunday xususiyatlar diskret (discrete) — ular sakrab o'zgaradi.

Chrome'da tekshirdik — quyidagilarga transition yozdik, lekin ular bir zumda o'zgardi, animatsiya umuman yaratilmadi:

Xususiyat Nega sakraydi
display: block → none Diskret — oraliq yo'q
background-image (bir gradientdan boshqasiga) Rasmlar orasida oraliq hisoblanmaydi
height: 0 → auto auto — son emas, brauzer uni oldindan bilmaydi
text-decoration-thickness: 1px → 3px Chrome'da silliq o'zgarmadi

Birinchi va uchinchisini JS'siz silliq qilishning yangi yo'llari bor — ularni Kirish va chiqish animatsiyalari darsida ko'ramiz. Oxirgisi — kutilmagan holat: spetsifikatsiyada qalinlik uzunlik, lekin Chrome uni sakratdi. Shuning uchun har transition'ni brauzerda sinab ko'ring.

Qaysi xususiyat animatsiyalanadi — MDN'da har xususiyat sahifasining pastidagi "Formal definition" jadvalida "Animation type" qatori aytadi.

4.2 visibility — alohida holat

visibility ham diskret, lekin uning o'z "aqlli" qoidasi bor. Chrome'da 1 soniyali transition bilan o'lchadik:

  • visible → hidden: 0.5 soniyada ham, 0.999 soniyada ham visible edi — faqat oxirida hidden bo'ldi.
  • hidden → visible: birinchi millisoniyadayoq visible bo'ldi.

Ya'ni visibility o'tish davomida doim "ko'rinadi" tomonda turadi. Bu bizga kerak narsa. display darsidagi tuzoqni eslang: opacity: 0 — yashirish emas, element bosiladi va Tab unga boradi. Yechim — opacity bilan birga visibility:

css
.yashirin {
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s, visibility 0.2s;
}

.ochiq {
  opacity: 1;
  visibility: visible;
}

Yo'qolishda element 0.2 soniya xiralashadi va faqat oxirida hidden bo'ladi — bosilmaydi, Tab o'tkazib yuboradi, ekran o'quvchi o'qimaydi. Paydo bo'lishda darhol visible va xiralashib ko'rinadi. Bu naqsh menyular va bildirishnomalarda ko'p uchraydi.

4.3 «Bahor»: hover'da paydo bo'ladigan havola

Menyu kartasida "Batafsil" havolasi faqat sichqoncha kelganda chiqsin — karta tozaroq ko'rinsin. Lekin telefonda hover yo'q, klaviatura foydalanuvchisi esa havolani ko'rishi kerak:

html
<style>
  :root {
    --rang-asosiy: #2f6b3a;
    --rang-urgu: #b4461a;
    --rang-fon: #fffaf0;
  }
  body { font-family: system-ui, sans-serif; }
  .taom-karta {
    max-width: 14rem;
    padding: 0.75rem 1rem;
    border: 2px solid var(--rang-asosiy);
    border-radius: 0.5rem;
    background-color: var(--rang-fon);
  }
  .taom-nomi { margin: 0; }
  .narx { color: var(--rang-urgu); font-weight: bold; }
  .taom-karta a { color: var(--rang-asosiy); }

  @media (hover: hover) {
    .taom-karta a {
      opacity: 0;
      transition: opacity 0.2s ease-out;
    }
    .taom-karta:hover a,
    .taom-karta:focus-within a {
      opacity: 1;
    }
  }
  @media (hover: hover) and (prefers-reduced-motion: no-preference) {
    .taom-karta a {
      display: inline-block;
      translate: 0 0.5rem;
      transition:
        opacity 0.2s ease-out,
        translate 0.2s ease-out;
    }
    .taom-karta:hover a,
    .taom-karta:focus-within a {
      translate: 0;
    }
  }
</style>
<article class="taom-karta">
  <h3 class="taom-nomi">Lag'mon</h3>
  <p class="narx">28 000 so'm</p>
  <p><a href="#">Batafsil</a></p>
</article>

Nimaga qarang: kompyuterda "Batafsil" boshida ko'rinmaydi. Sichqonchani kartaga olib boring — havola xiralikdan chiqib, biroz pastdan suzib keladi. Tab bilan havolaga kelsangiz ham chiqadi: :focus-within (Holat pseudo-klasslari). Telefonda esa havola doim ko'rinadi.

Uch qaror:

  • visibility yo'q — ataylab. Havola fokusni olishi kerak: Bobur Tab bosganda unga yetib borsin va :focus-within uni ko'rsatsin. visibility: hidden bo'lsa, Tab uni o'tkazib yuborardi.
  • Yashirish — faqat (hover: hover) da. Telefonda ko'rinmas havola bosiladigan "tuzoq" bo'lardi.
  • Xiralashish — hamma uchun, siljish — faqat ruxsat bo'lsa. Harakatni kamaytirgan foydalanuvchida havola joyida xiralikdan chiqadi, suzmaydi. Xiralashish harakat emas — u bosh aylantirmaydi. Bu farqni Harakat etikasi darsida chuqurroq ko'ramiz.

5. Timing funksiyalari: harakat xarakteri

5.1 Tezlik egri chizig'i

Transition 0.2 soniyada 0 dan 8 pikselgacha boradi. Lekin qanday boradi? Bir tekis tezlikdami yoki avval tez, keyin sekinmi? Buni timing funksiyasi (easing) belgilaydi.

Taksini tasavvur qiling. Yaxshi haydovchi joyidan sekin qo'zg'aladi, yo'lda tezlashadi, bekatga yaqinlashganda sekinlashadi. Yomon haydovchi esa birdan gazni bosib, birdan tormozlaydi — yo'lovchilar oldinga uchadi. Harakat bir xil masofada, lekin his butunlay boshqa.

Beshta tayyor kalit so'z bor. Ularni Chrome'da o'lchadik: 1 soniyali transition 0 dan 100 pikselgacha, yarim soniyada element qayerda edi:

Kalit so'z Xarakteri 0.5 soniyada
linear Bir tekis 50 px
ease (odatiy) Tez boshlanadi, uzoq sekinlashadi 80 px
ease-in Sekin boshlanadi, tezlashadi 31.5 px
ease-out Tez boshlanadi, sekinlashadi 68.5 px
ease-in-out Sekin → tez → sekin 50 px

Timing funksiyasi yozilmasa — ease. Vaqtning yarmida yo'lning 80 foizi bosib o'tiladi.

5.2 Egri chiziqlarni ko'ramiz

Har timing funksiyasi — egri chiziq: gorizontal o'q — vaqt, vertikal — bosib o'tilgan yo'l. Tik joyi — tez, yotiq joyi — sekin. Chiziqlar ostidagi koptoklar shu funksiya bilan yuradi:

html
<style>
  :root {
    --rang-asosiy: #2f6b3a;
    --rang-urgu: #b4461a;
    --rang-ikkinchi: #5b6660;
    --rang-fon-och: #e8f1ec;
  }
  body { font-family: system-ui, sans-serif; }
  .egrilar {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
    gap: 1.5rem;
    padding: 1rem;
  }
  figure { margin: 0; }
  svg {
    display: block;
    width: 100%;
    height: auto;
    overflow: visible;
  }
  .ramka {
    fill: none;
    stroke: var(--rang-ikkinchi);
    stroke-dasharray: 3 3;
  }
  .egri {
    fill: none;
    stroke: var(--rang-asosiy);
    stroke-width: 3;
  }
  figcaption {
    margin-block: 0.25rem 0.5rem;
    font-family: monospace;
    font-size: 0.85rem;
  }
  .yolak {
    container-type: inline-size;
    border-radius: 0.5rem;
    background-color: var(--rang-fon-och);
  }
  .koptok {
    width: 1rem;
    height: 1rem;
    border-radius: 50%;
    background-color: var(--rang-urgu);
  }
  .egrilar:hover .koptok {
    translate: calc(100cqi - 1rem);
  }
  .l { --e: linear; }
  .ea { --e: ease; }
  .ei { --e: ease-in; }
  .eo { --e: ease-out; }
  @media (prefers-reduced-motion: no-preference) {
    .koptok { transition: translate 1.5s var(--e); }
  }
</style>
<div class="egrilar">
  <figure class="l">
    <svg viewBox="0 0 100 100" role="img" aria-label="linear">
      <rect class="ramka" width="100" height="100"/>
      <path class="egri" d="M0 100 L100 0"/>
    </svg>
    <figcaption>linear</figcaption>
    <div class="yolak"><div class="koptok"></div></div>
  </figure>
  <figure class="ea">
    <svg viewBox="0 0 100 100" role="img" aria-label="ease">
      <rect class="ramka" width="100" height="100"/>
      <path class="egri" d="M0 100 C25 90 25 0 100 0"/>
    </svg>
    <figcaption>ease</figcaption>
    <div class="yolak"><div class="koptok"></div></div>
  </figure>
  <figure class="ei">
    <svg viewBox="0 0 100 100" role="img" aria-label="ease-in">
      <rect class="ramka" width="100" height="100"/>
      <path class="egri" d="M0 100 C42 100 100 0 100 0"/>
    </svg>
    <figcaption>ease-in</figcaption>
    <div class="yolak"><div class="koptok"></div></div>
  </figure>
  <figure class="eo">
    <svg viewBox="0 0 100 100" role="img" aria-label="ease-out">
      <rect class="ramka" width="100" height="100"/>
      <path class="egri" d="M0 100 C0 100 58 0 100 0"/>
    </svg>
    <figcaption>ease-out</figcaption>
    <div class="yolak"><div class="koptok"></div></div>
  </figure>
</div>

Nimaga qarang: ease-out chizig'i boshida tik — koptok joyidan "otilib" chiqadi va oxirida sekin to'xtaydi. ease-in aksincha: boshida yotiq, koptok sekin qo'zg'aladi va oxirida "urilib" to'xtaydi. Sichqonchani blok ustiga olib boring va to'rttasining poygasini kuzating: hammasi bir vaqtda — 1.5 soniyada — marraga yetadi, lekin yo'lda har xil. Harakatni kamaytirish yoqilgan bo'lsa, koptoklar sakrab o'tadi — egri chiziqlar esa baribir farqni ko'rsatadi.

5.3 Interfeys uchun qaysi biri

Oddiy qoidalar (Google'ning Material Design ko'rsatmalarida ham shunday tavsiya qilinadi):

  • Paydo bo'lish, hover, javob — ease-out. Harakat darhol boshlanadi: foydalanuvchi "meni eshitdi" deb his qiladi, keyin yumshoq to'xtaydi.
  • Yo'qolish, ekrandan chiqish — ease-in. Sekin qo'zg'alib, tezlashib ketadi — ko'z uni kuzatib ulgurmaydi, bu yaxshi.
  • Joyida o'zgarish (bir joydan boshqasiga ko'chish) — ease-in-out.
  • linear — rang, xiralik va aylanish (spinner) uchun. Joy o'zgartiradigan harakatda u "mexanik" ko'rinadi.

ease-in ni hover'ga qo'ymang: boshida sekin — foydalanuvchi "sekin ishlayapti" deb o'ylaydi.

6. cubic-bezier(): o'z egri chizig'ingiz

Beshta kalit so'z — aslida tayyor egri chiziqlar. Har birining ichida cubic-bezier() turadi: ease = cubic-bezier(0.25, 0.1, 0.25, 1), ease-out = cubic-bezier(0, 0, 0.58, 1).

To'rtta son — ikkita "tortish nuqtasi"ning koordinatasi: (x1, y1) va (x2, y2). Egri chiziq (0, 0) dan (1, 1) ga boradi, nuqtalar esa uni o'ziga tortadi — xuddi arqonni ikki joyidan barmoq bilan tortgandek. Vaqt koordinatalari (x1, x2) 0 va 1 orasida bo'lishi shart. Yo'l koordinatalari (y1, y2) esa 1 dan oshishi mumkin.

y 1 dan oshsa, element marradan o'tib ketib, qaytadi — "orqaga qaytish" effekti:

css
.taom-karta {
  transition: translate 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}

Chrome'da o'lchadik: 100 pikselli yo'lda yarim vaqtda element 108.7 pikselda edi — marradan 8.7 piksel o'tib ketgan, keyin 100 ga qaytdi. Tugma yoki bildirishnoma "prujina bilan" chiqishi uchun qulay. Lekin ehtiyot bo'ling: ko'p ishlatilsa, interfeys "o'ynoqi" va jiddiy bo'lmagandek tuyuladi.

Egri chiziqni qo'lda terish shart emas. Chrome DevTools'da Styles panelidagi har timing funksiyasi yonida kichik egri chiziq belgisi bor. Uni bossangiz, tahrirlagich ochiladi: nuqtalarni sichqoncha bilan surasiz, tayyor variantlarni tanlaysiz va natija darhol sahifada ko'rinadi.

7. steps(): zinapoya

Ba'zan silliqlik kerak emas. Soat mili "tik-tik" bilan sakraydi, eski o'yinlardagi qahramon kadrma-kadr qadam tashlaydi. steps(n) harakatni n ta teng sakrashga bo'ladi.

Chrome'da steps(4) bilan 0 dan 100 pikselgacha o'lchadik:

Vaqt steps(4) steps(4, jump-start)
0.1 s 0 25
0.25 s 25 50
0.5 s 50 75
0.75 s 75 100
0.9 s 75 100

Farqi — sakrash qachon bo'ladi. Odatiy jump-end — har bo'lak oxirida: element boshida 0 da turadi, 100 ga faqat vaqt tugaganda yetadi. jump-start — har bo'lak boshida: birinchi sakrash darhol. step-start va step-end kalit so'zlari — steps(1, ...) ning qisqa shakli.

steps() transition'dan ko'ra animatsiyada ko'proq kerak: "yozuv mashinkasi" effekti, sprite animatsiyasi, yuklanish nuqtalari — keyingi darsda.

8. linear(): prujina va sakrash

cubic-bezier() bir marta o'tib ketib qaytishi mumkin. Lekin haqiqiy prujina bir necha marta tebranadi, koptok bir necha marta sakraydi. Buni linear() funksiyasi chizadi: u egri chiziqni nuqtalar ro'yxati bilan beradi, brauzer nuqtalarni to'g'ri chiziqlar bilan tutashtiradi.

css
.bron-havola {
  transition: scale 0.5s linear(0, 1.2 60%, 0.95 80%, 1);
}

O'qilishi: "boshida 0; vaqtning 60 foizida 1.2 — marradan o'tib ketgan; 80 foizida 0.95 — biroz qaytgan; oxirida 1". Chrome'da o'lchadik: 0 dan 100 gacha yo'lda vaqtning yarmida element 100 da, 75 foizida 101.25 da, 90 foizida 97.5 da edi — tebranib to'xtadi.

Nuqtalar qancha ko'p bo'lsa, egri chiziq shuncha silliq. Real prujina uchun 20–40 ta nuqta kerak — ularni qo'lda yozmaydi. Jake Archibald'ning "Linear easing generator" kabi vositalarda prujinani sozlab, tayyor linear(...) qatorini nusxalaydi.

Baseline ma'lumotiga ko'ra linear() 2023-yil dekabrdan hamma asosiy brauzerda, 2026-yil iyundan keng tarqalgan Baseline. Eski brauzer linear(...) li deklaratsiyani tashlaydi. Zaxira uchun oldiga oddiy qatorni yozing:

css
.bron-havola {
  transition: scale 0.5s ease-out;
  transition: scale 0.5s linear(0, 1.2 60%, 0.95 80%, 1);
}

Tushunmagan brauzer ikkinchi qatorni tashlaydi va birinchisi bilan qoladi (CSS nima darsidagi kechirimli o'qish).

Tekshirib ko'ring: Qaysi timing funksiyasini tanlaysiz? a) Menyu ochilib, pastga tushadi. b) Yuklanish belgisi to'xtovsiz aylanadi. c) Raqamli soatda soniyalar almashadi.

Javob

a) ease-out — paydo bo'lish: tez boshlanib, yumshoq to'xtaydi. b) linear — aylanish bir tekis bo'lishi kerak, aks holda belgi har aylanishda "sekinlashib-tezlashib" turadi. c) steps() — soniya silliq "oqmaydi", sakraydi.

9. Davomiylik: qancha tez?

9.1 Raqamlar

Tajribada shakllangan qoidalar:

Davomiylik His Qayerda
100 ms dan kam Bir zumda Bosilish javobi (:active)
150–300 ms Tez, lekin ko'rinadi Hover, kichik elementlar, tugmalar
300–500 ms Sezilarli Katta panel, modal oyna, sahifa qismi
500 ms dan ko'p Sekin, "kuttiradi" Faqat ataylab: karta ag'darish, dekorativ effekt

Qoida: masofa qancha katta, vaqt shuncha uzun — kichik tugma 150 ms da, butun ekranni kesib o'tadigan panel 400 ms da. Telefonda odatda qisqaroq: ekran kichik, masofalar ham kichik.

Eng ko'p uchraydigan xato — juda uzun transition. Birinchi marta chiroyli ko'rinadi, yuzinchi marta esa jahlni chiqaradi. Har kuni ishlatiladigan interfeysda tezlik chiroyliroq.

9.2 Kirish va chiqish har xil

Ba'zan ikki yo'nalishga har xil vaqt kerak. Masalan, "Batafsil" havolasi tez chiqsin, lekin sekin yo'qolsin — sichqoncha tasodifan chetga chiqsa, darhol g'oyib bo'lmasin. "Qayerga yoziladi" bo'limidagi qoidani eslang: brauzer transition'ni yangi holatdan oladi.

css
/* Chiqish (oddiy holatga qaytish): 0.3s kutib */
.taom-karta a {
  transition: opacity 0.2s ease-in 0.3s;
}

/* Kirish (hover): darhol va tez */
.taom-karta:hover a {
  transition: opacity 0.15s ease-out;
}

Ochiladigan menyularda chiqishdagi kechikish ayniqsa foydali: sichqoncha menyudan bir lahzaga chiqib qaytsa, menyu yopilib ulgurmaydi.

9.3 O'rtada to'xtatilgan transition

Sichqoncha kartaga keldi va karta ko'tarila boshladi. Yarim yo'lda sichqoncha ketdi. Endi karta yuqoridan emas, o'sha yarim yo'ldan tushadi — va to'liq davomiylikni emas, qisqartirilganini oladi.

Chrome'da o'lchadik: 1 soniyali transition 0.3 soniyada (30 pikselda) teskari burildi. Qaytish transition'i 1 soniya emas, 0.3 soniya bo'ldi. Brauzer o'zi hisoblaydi — "qancha yurgan bo'lsa, shuncha vaqtda qaytadi". Shuning uchun sichqonchani kartalar ustida tez yurgizsangiz ham, ular "kechikib" ergashmaydi.

10. Transition va kaskad

Kaskad darsida "harakat effektlari ham kaskadda o'z joyiga ega" degan edik. Transition — kaskaddagi eng kuchli manba. U hatto !important dan ham ustun.

Chrome'da tekshirdik. Paragrafda color: rgb(255, 0, 0) !important va 1 soniyali transition: color bor. Class qo'shdik — yangi rang rgb(0, 0, 255) !important. Yarim soniyada hisoblangan rang rgb(128, 0, 128) — binafsha edi. Ya'ni o'tish paytida transition bergan oraliq qiymat ikkala !important qiymatni ham "yengdi".

Mantiq oddiy: transition — "eski va yangi qiymat orasidagi yo'l". Agar !important uni to'xtata olsa, !important li xususiyatlar hech qachon silliq o'zgarmas edi. Transition tugashi bilan esa qiymat oddiy kaskad natijasiga — yangi !important rangga — qaytadi.

Animatsiyalarning kaskaddagi joyi boshqacha — uni keyingi darsda ko'ramiz.

11. transitionend: tugaganini bilish

Ba'zan transition tugaganda nimadir qilish kerak: panel yopilib bo'lgach uni sahifadan butunlay olib tashlash, keyingi animatsiyani boshlash. Brauzer buni JavaScript'ga hodisa (event) bilan xabar qiladi:

js
const karta = document.querySelector(".taom-karta");

karta.addEventListener("transitionend", (hodisa) => {
  console.log(hodisa.propertyName, "tugadi");
});

Bu JavaScript'ni hozir tushunish shart emas — hodisalarni 09-qismda o'rganasiz. Faqat uch faktni eslab qoling:

  • Hodisa har xususiyat uchun alohida keladi: translate va box-shadow silliq o'zgarsa — ikki marta. propertyName qaysi biri ekanini aytadi.
  • Transition o'rtada to'xtatilsa, transitionend kelmaydi — o'rniga transitioncancel keladi. "Tugagach yopaman" deb yozilgan kod shu holatda "osilib" qolishi mumkin.
  • transitionrun va transitionstart hodisalari ham bor — kechikish boshlanganda va harakat boshlanganda.

12. «Bahor» menyusi: silliq versiya

2D transformlar darsidagi menyuga transition qo'shamiz. Rang o'zgarishi hamma uchun silliq, harakat esa faqat ruxsat bo'lsa:

html
<style>
  :root {
    --rang-asosiy: #2f6b3a;
    --rang-urgu: #b4461a;
    --rang-fon: #fffaf0;
    --rang-matn: #1f2a24;
  }
  body {
    font-family: system-ui, sans-serif;
    color: var(--rang-matn);
  }
  ul {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
    gap: 1rem;
    padding: 0.5rem 0 0;
    list-style: none;
  }
  li { display: grid; }
  .taom-karta {
    padding: 0.75rem 1rem;
    border: 2px solid var(--rang-asosiy);
    border-radius: 0.5rem;
    background-color: var(--rang-fon);
    transition: border-color 0.2s ease-out;
  }
  .taom-nomi { margin: 0; }
  .narx { color: var(--rang-urgu); font-weight: bold; }
  .bron-havola {
    display: inline-block;
    padding: 0.75rem 1.25rem;
    border-radius: 0.5rem;
    background-color: var(--rang-asosiy);
    color: var(--rang-fon);
    text-decoration: none;
  }
  @media (hover: hover) {
    li:hover > .taom-karta {
      border-color: var(--rang-urgu);
    }
  }
  @media (prefers-reduced-motion: no-preference) {
    .taom-karta {
      transition:
        border-color 0.2s ease-out,
        translate 0.2s ease-out,
        box-shadow 0.2s ease-out;
    }
    .bron-havola {
      transition: scale 0.1s ease-out;
    }
    .bron-havola:active {
      scale: 0.96;
    }
  }
  @media (hover: hover) and (prefers-reduced-motion: no-preference) {
    li:hover > .taom-karta {
      translate: 0 -6px;
      box-shadow: 0 6px 12px rgb(0 0 0 / 0.15);
    }
  }
</style>
<ul>
  <li>
    <article class="taom-karta">
      <h3 class="taom-nomi">Osh</h3>
      <p class="narx">35 000 so'm</p>
    </article>
  </li>
  <li>
    <article class="taom-karta">
      <h3 class="taom-nomi">Lag'mon</h3>
      <p class="narx">28 000 so'm</p>
    </article>
  </li>
  <li>
    <article class="taom-karta">
      <h3 class="taom-nomi">Manti</h3>
      <p class="narx">30 000 so'm</p>
    </article>
  </li>
</ul>
<a class="bron-havola" href="#">Stolni band qilish</a>

Nimaga qarang: kartaga sichqoncha olib boring — chegara 0.2 soniyada qizg'ishga o'tadi, karta suzib ko'tariladi va soya oladi. Chiqib ketsangiz, hammasi xuddi shunday silliq qaytadi. Tugmani bosing — u 0.1 soniyada "botadi". Tizimda harakatni kamaytirish yoqilgan bo'lsa, faqat chegara rangi silliq o'zgaradi.

Diqqat qiling: ikkinchi @media blokida transition ro'yxatida border-color takrorlangan. Usiz rang o'tishi yo'qolardi — keyingi transition butun ro'yxatni almashtiradi.

13. Ko'p uchraydigan xatolar

13.1 Transition faqat :hover da

Kirish silliq, chiqish sakraydi. Tuzatish: transition ni asosiy qoidaga ko'chiring.

13.2 height: auto yoki display silliq emas

"Transition yozdim, ishlamayapti." DevTools'da tekshirsangiz, xato yo'q — xususiyat shunchaki animatsiyalanmaydi. Tuzatish: translate yoki opacity bilan boshqa yo'l toping, yoki Kirish va chiqish animatsiyalari darsidagi yangi usullar.

13.3 transition: all

Keyinchalik qo'shilgan har o'zgarish ham "suzadi", qorong'i rejimga o'tish sekin "oqadi". Tuzatish: xususiyatlarni nomi bilan yozing.

13.4 Ikkinchi transition birinchisini o'chiradi

@media yoki hover ichidagi transition asosiy ro'yxatni almashtirdi. Tuzatish: ro'yxatni to'liq takrorlang.

13.5 Harakat hamma uchun

translate ning transition'i prefers-reduced-motion shartisiz yozildi. Tuzatish: harakatni @media (prefers-reduced-motion: no-preference) ichiga oling. Rang va xiralik o'tishi tashqarida qolishi mumkin.

14. Mashqlar

1-mashq (oson): Qisqa yozuvni o'qing

Har bir qatorda xususiyat, davomiylik, timing funksiyasi va kechikishni ayting. Bittasi xato — qaysi va nega?

  1. transition: opacity 300ms;
  2. transition: background-color 0.2s linear 50ms;
  3. transition: 0.5s 1s translate ease-in-out;
  4. transition: scale 150 ease-out;
Yechim
  1. opacity, 300 ms, ease (odatiy), kechikish 0.
  2. background-color, 0.2 s, linear, kechikish 50 ms.
  3. translate, 0.5 s (birinchi vaqt), ease-in-out, kechikish 1 s (ikkinchi vaqt). Tartib g'alati, lekin to'g'ri.
  4. Xato: 150 da birlik yo'q. Vaqt birliksiz bo'lmaydi — brauzer butun deklaratsiyani tashlaydi. To'g'risi: 150ms.

2-mashq (o'rta): Havola chizig'i o'sib chiqsin

«Bahor» sahifasidagi oddiy havolalarda tag chiziq yo'q (text-decoration: none). Sichqoncha kelganda havola tagida chiziq chapdan o'ngga o'sib chiqsin.

Ishora: text-decoration-thickness Chrome'da silliq o'zgarmaydi — "Nima silliq o'zgaradi" bo'limidagi jadval. Chiziqni ::after bilan chizing (Pseudo-elementlar), uni scale: 0 1 bilan "yig'ib" qo'ying va o'sish nuqtasini chapga qo'ying (2D transformlar darsidagi transform-origin). Havolaga position: relative, chiziqqa position: absolute.

Yechim
html
<style>
  body { font-family: system-ui, sans-serif; padding: 1rem; }
  a {
    position: relative;
    color: #2f6b3a;
    text-decoration: none;
  }
  a::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: -2px;
    width: 100%;
    height: 2px;
    background-color: currentColor;
    scale: 0 1;
    transform-origin: left;
  }
  a:hover::after,
  a:focus-visible::after {
    scale: 1 1;
  }
  @media (prefers-reduced-motion: no-preference) {
    a::after {
      transition: scale 0.25s ease-out;
    }
  }
</style>
<p>
  <a href="#">Menyu</a> · <a href="#">Bron</a> · <a href="#">Aloqa</a>
</p>
  • scale: 0 1 — eni 0, bo'yi o'zgarmagan: chiziq bor, lekin ko'rinmaydi. Hover'da 1 1 — to'liq en.
  • transform-origin: left — chap chetdan o'sadi. center bo'lsa, o'rtadan ikki tomonga o'sardi — bu ham chiroyli variant.
  • :focus-visible — klaviatura foydalanuvchisi ham chiziqni ko'radi.
  • Harakatni kamaytirgan foydalanuvchida chiziq darhol paydo bo'ladi — havola hover'ni baribir ko'rsatadi.
  • a odatda inline, lekin transform ::after da, u esa position: absolute — absolute element blokka aylanadi, shuning uchun scale ishlaydi.

3-mashq (qiyin): "Ish vaqti" ochiladigan paneli

«Bahor» sahifasining tepasida "Ish vaqti" tugmasi bor. Sichqoncha kelganda yoki fokusda uning ostida kichik panel chiqadi: "Har kuni 7:00 — 23:00". Talablar:

  1. Yopiq panel ko'rinmaydi, bosilmaydi va Tab unga bormaydi.
  2. Ochilishda: darhol boshlanadi, 0.15 s, xiralikdan chiqadi va 0.5rem pastdan suzib keladi.
  3. Yopilishda: 0.3 s kutib, keyin 0.2 s da yo'qoladi.
  4. Harakatni kamaytirgan foydalanuvchida — faqat xiralashish, siljishsiz.
html
<div class="ish-vaqti">
  <button type="button">Ish vaqti</button>
  <p>Har kuni 7:00 — 23:00</p>
</div>

ish-vaqti — faqat shu mashq uchun namoyish nomi.

Ishora: 1-band — "visibility — alohida holat" bo'limi. 2–3-bandlar — "Kirish va chiqish har xil" bo'limi: chiqish vaqti asosiy qoidada, kirish vaqti — ochiq holat qoidasida. visibility ning kechikishi ham opacity bilan bir xil bo'lsin.

Yechim
html
<style>
  body { font-family: system-ui, sans-serif; padding: 1rem; }
  .ish-vaqti {
    position: relative;
    display: inline-block;
  }
  .ish-vaqti p {
    position: absolute;
    top: 100%;
    left: 0;
    width: max-content;
    margin: 0.25rem 0 0;
    padding: 0.5rem 0.75rem;
    border-radius: 0.5rem;
    background-color: #2f6b3a;
    color: #fffaf0;
    opacity: 0;
    visibility: hidden;
    /* Yopilish: 0.3s kutib, 0.2s da */
    transition:
      opacity 0.2s ease-in 0.3s,
      visibility 0.2s 0.3s;
  }
  .ish-vaqti:hover p,
  .ish-vaqti:focus-within p {
    opacity: 1;
    visibility: visible;
    /* Ochilish: darhol, 0.15s da */
    transition:
      opacity 0.15s ease-out,
      visibility 0.15s;
  }
  @media (prefers-reduced-motion: no-preference) {
    .ish-vaqti p {
      translate: 0 0.5rem;
      transition:
        opacity 0.2s ease-in 0.3s,
        visibility 0.2s 0.3s,
        translate 0.2s ease-in 0.3s;
    }
    .ish-vaqti:hover p,
    .ish-vaqti:focus-within p {
      translate: 0;
      transition:
        opacity 0.15s ease-out,
        visibility 0.15s,
        translate 0.15s ease-out;
    }
  }
</style>
<div class="ish-vaqti">
  <button type="button">Ish vaqti</button>
  <p>Har kuni 7:00 — 23:00</p>
</div>
  • visibility yopilishda oxirida hidden bo'ladi — shuning uchun panel 0.5 soniya (0.3 kutish + 0.2 yo'qolish) ko'rinib turadi, keyin bosilmaydigan bo'ladi. Ochilishda birinchi lahzadayoq visible.
  • Ikki joyda transition: asosiy qoidada — chiqish uchun (kechikish bilan), ochiq holatda — kirish uchun (kechikishsiz).
  • Harakat bloki ro'yxatni to'liq takrorlaydi — opacity va visibility qatorlari yo'qolmasin.
  • Fokus: button ga Tab bilan kelsangiz, :focus-within panelni ochadi. Panelda havola bo'lsa, u ham fokus olardi — chunki panel allaqachon ochiq.

4-mashq: Portfolio qadami — silliq hover

Portfolio'da hozir uchta hover effekti sakrab o'zgaradi: havola fonining rangi (Yakuniy loyiha), "boshqa sayt" strelkasi (2D transformlar) va bosh sahifa rasmining to'g'rilanishi (3D transformlar). Ularni silliq qiling:

  1. Havola foni 0.15 s da, ease-out bilan — hamma uchun (bu harakat emas).
  2. Strelka 0.2 s da va rasm 0.3 s da, ease-out bilan — faqat harakat ruxsat bo'lsa.
  3. transition: all ishlatmang.
  4. Chrome'da tekshiring: hover'da havola chizig'i qalinlashishi ham silliqmi?

Ishora: transition asosiy qoidaga yoziladi, hover'ga emas. Hover faqat sichqonchali qurilmada ishlaydi — transition'larni ham "6. Afzalliklar va qurilma" bo'limidagi @media bloklariga qo'ysangiz, telefonda keraksiz qoida qolmaydi.

Yechim

"6. Afzalliklar va qurilma" bo'limidagi ikkala blok:

css
/* Hover faqat sichqonchali qurilmada */
@media (hover: hover) {
  /* Rang o'tishi — hamma uchun (Transition darsi) */
  a {
    transition: background-color 0.15s ease-out;
  }

  a:not([aria-current="page"]):hover {
    background-color: var(--rang-fon-och);
    text-decoration-thickness: 2px;
  }

  /* header nav havolasining hover rangi — o'zgarishsiz */
}

/* Harakat faqat ruxsat bo'lsa */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  a[href^="https://"]::after {
    transition: translate 0.2s ease-out;
  }

  a[href^="https://"]:hover::after {
    translate: 0.125em -0.125em;
  }

  main > img {
    transition: transform 0.3s ease-out;
  }

  main > img:hover {
    transform: none;
  }
}
  • Menyu havolasining rangi ham shu a qoidasi bilan silliq bo'lishi kerakmi? Xohlasangiz, ro'yxatga color 0.15s ease-out qo'shing — lekin a qoidasidagi transition ga, alohida qoida yozmang (ikkinchisi birinchisini o'chiradi).
  • Rasm: perspective(50rem) rotateY(-10deg) dan none ga — brauzer none ni "hech narsa qilmaydigan" funksiyalar ro'yxatiga aylantirib, oraliqni hisoblaydi. Chrome'da o'lchadik: yarim yo'lda rasm matrix3d(...) bilan 5 gradus burilgan holatda edi.
  • Chiziq qalinligi Chrome'da sakraydi — text-decoration-thickness silliq o'zgarmaydi. Fon silliq o'zgargani uchun bu deyarli sezilmaydi. Xohlasangiz, 2-mashqdagi ::after chizig'i bilan almashtiring — lekin portfolio'da ::after allaqachon strelka uchun band.

15. Real ishda

  • Har bir tugma va havola. Zamonaviy dizayn tizimlarida hover va fokus holatlari deyarli doim 100–200 ms lik transition bilan. Davomiylik va easing ham token sifatida saqlanadi: masalan, "tez" — 150 ms, "o'rta" — 250 ms (Dizayn tokenlari).
  • Kutubxonalar. Tailwind'da transition duration-200 ease-out kabi tayyor klasslar bor (Tailwind CSS 1); React'da Framer Motion (Motion) prujina animatsiyalarini beradi. Ular ham ichida xuddi shu tushunchalar bilan ishlaydi — hozir bilish shart emas.
  • Dizayner bilan til. Figma prototiplarida "Ease out, 200ms" yoki "Spring" deb yoziladi (Figma dasturchi uchun 2). Endi ularni CSS'ga aniq o'gira olasiz.
  • Intervyuda so'raladi: "transition va animation farqi?", "Nega height: auto ga transition ishlamaydi?", "ease-in va ease-out qachon?", "transition: all nega yomon?"

Xulosa

  • transition qiymat o'zgarishini silliq qiladi; u asosiy qoidaga yoziladi — shunda ikkala yo'nalish ham silliq.
  • To'rt qism: xususiyat, davomiylik, timing, kechikish. Birinchi vaqt — davomiylik, ikkinchisi — kechikish.
  • Faqat oraliq qiymati bor xususiyatlar silliq o'zgaradi; display, gradient, height: auto sakraydi. opacity + visibility — to'g'ri yashirish.
  • Interfeysda: 150–300 ms, paydo bo'lishda ease-out, yo'qolishda ease-in.
  • cubic-bezier() — o'z egri chizig'ingiz, steps() — zinapoya, linear() — prujina va sakrash.
  • Harakat — prefers-reduced-motion: no-preference ichida; rang va xiralik o'tishi — hamma uchun.

Keyingi dars: @keyframes va animation xususiyatlari — hover kutmasdan o'zi ishlaydigan, ko'p bosqichli va takrorlanuvchi animatsiyalar yozamiz.

Manbalar

  • MDN: "transition", "Using CSS transitions", "easing-function", "cubic-bezier()", "steps()", "linear()", "transitionend event" — developer.mozilla.org
  • W3C: "CSS Transitions Level 1" va "CSS Easing Functions Level 2" — w3.org/TR/css-transitions-1, w3.org/TR/css-easing-2
  • web.dev: "Learn CSS — Transitions" — web.dev/learn/css
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
CSS transition: holatlar orasida silliq o'tish va timing funksiyalari — IlmHamroh