Mundarija (32)
- Bu darsda
- 1. Nega bu kerak?
- 2. Silliq skroll: scroll-behavior
- 2.1 Bitta qator
- 2.2 Harakatni kamaytirishni hurmat qiling
- 2.3 Silliq skrollning ikki tuzog'i
- 3. Scroll snap: "magnitli" skroll
- 3.1 Birinchi lenta
- 3.2 scroll-snap-type: o'q va qattiqlik
- 3.3 scroll-snap-align: elementning qaysi cheti
- 4. Snap nuqtasini surish: scroll-padding va scroll-margin
- 4.1 Konteyner ichki chekinishi
- 4.2 Element tashqi chekinishi
- 5. Vertikal snap va mandatory tuzog'i
- 5.1 "Hikoyalar" — butun ekranli bo'limlar
- 5.2 Tuzoq: element ekrandan baland bo'lsa
- 5.3 scroll-snap-stop: bittadan o'tkazmaslik
- 6. Lenta chetida: overscroll-behavior
- 7. JavaScript tomoni: scrollend va snap hodisalari
- 8. Ko'p uchraydigan xatolar
- 8.1 Snap konteynerida overflow yo'q
- 8.2 Kartalar siqilib, hammasi sig'ib qoldi
- 8.3 Oxirgi karta chetga yetmaydi
- 8.4 Skrollbarni yashirish
- 9. Mashqlar
- 1-mashq (oson): silliq menyu
- 2-mashq (o'rta): taomlar lentasi
- 3-mashq (qiyin): ikki o'qli xarita
- 4-mashq: Portfolio qadami — silliq o'tish havolalari
- 10. Real ishda
- Xulosa
- Manbalar
CSS scroll-snap va skroll xulqi: silliq skroll va "magnitli" galereya
Qisqacha:
scroll-behavior: smoothsahifa ichidagi havolaga keskin sakrash o'rniga silliq suradi — uniprefers-reduced-motionbilan cheklang. Xususiyatscroll-snap-type: x mandatoryesa skroll konteynerni "magnitli" qiladi: foydalanuvchi qo'yib yuborganda skroll eng yaqin elementga tortiladi, elementning qaysi cheti tortilishini esascroll-snap-alignaytadi. Bu JavaScript'siz karusel va galereyalar asosi.
Bu darsda
- Sahifa ichidagi havolalarni silliq qilasiz va harakatni kamaytirishni hurmat qilasiz.
scroll-snap-type,scroll-snap-alignvascroll-snap-stopbilan gorizontal lenta va vertikal "hikoyalar" yasaysiz.scroll-paddingvascroll-marginsnap nuqtasini qanday surishini tushuntira olasiz.mandatoryvaproximityfarqini vamandatorytuzoqlarini bilasiz.overscroll-behaviorvascrollendhodisasi qayerda kerakligini bilasiz.
Oldin bilishingiz kerak: Overflow va skroll konteynerlar, position: fixed va sticky, prefers-reduced-motion, Sahifa ichidagi havolalar.
1. Nega bu kerak?
O'tgan darsda @property bilan o'zgaruvchilarni animatsiya qildik. Endi harakatning yana bir turi — skroll.
«Bahor» menyu sahifasida ikki muammo bor.
Birinchisi — sakrash. Tepada "Issiq taomlar · Salatlar · Ichimliklar" havolalari bor (Sahifa ichidagi havolalar darsidan). Mehmon "Ichimliklar" ni bosadi — sahifa bir zumda boshqa joyga "teleport" bo'ladi. U qayerga kelganini, qancha pastga tushganini sezmaydi. Xuddi kitobni varaqlamasdan, birdan 200-betni ochib qo'yish kabi.
Ikkinchisi — yarim karta. Telefonda "Bugungi taomlar" kartalari gorizontal lentada turibdi (Overflow darsidagi overflow-x: auto). Mehmon barmog'i bilan suradi va qo'yib yuboradi. Lenta qayerda to'xtasa, o'sha yerda qoladi: bir kartaning yarmi, ikkinchisining choragi. Endi u qo'lda to'g'rilashi kerak.
Bugun ikkalasini CSS'ning o'zi bilan hal qilamiz. Birinchisini — silliq skroll, ikkinchisini — scroll snap ("magnitli" skroll).
2. Silliq skroll: scroll-behavior
2.1 Bitta qator
html {
scroll-behavior: smooth;
}scroll-behavior — skroll konteyner ichidagi "dasturiy" surilish qanday bo'lishini aytadi: auto — bir zumda (sukut bo'yicha), smooth — silliq. "Dasturiy" deganimiz: havola bosilganda, Tab bilan fokus o'tganda yoki JavaScript skrollni o'zgartirganda. Foydalanuvchining o'z g'ildiragi va barmog'iga u tegmaydi.
Sahifaning o'zi uchun xususiyat html ga yoziladi — sahifa skrolli aynan html elementida (Overflow). Ichki skroll konteyner uchun esa o'sha konteynerning o'ziga:
<style>
.menyu-oyna {
height: 220px;
overflow-y: auto;
scroll-behavior: smooth;
border: 2px solid #2f6b3a;
background-color: #fffaf0;
font-family: system-ui, sans-serif;
}
.menyu-oyna nav {
position: sticky;
top: 0;
display: flex;
gap: 12px;
padding: 8px 12px;
background-color: #2f6b3a;
}
.menyu-oyna nav a {
color: #fffaf0;
}
.menyu-oyna section {
min-height: 260px;
padding-inline: 12px;
scroll-margin-top: 44px;
}
.menyu-oyna section:target h2 {
color: #b4461a;
}
</style>
<div class="menyu-oyna">
<nav aria-label="Menyu bo'limlari">
<a href="#issiq">Issiq taomlar</a>
<a href="#salat">Salatlar</a>
<a href="#ichimlik">Ichimliklar</a>
</nav>
<section id="issiq"><h2>Issiq taomlar</h2>
<p>Osh — 35 000 so'm. Lag'mon — 28 000 so'm.</p></section>
<section id="salat"><h2>Salatlar</h2>
<p>Achchiq-chuchuk, Toshkent salati.</p></section>
<section id="ichimlik"><h2>Ichimliklar</h2>
<p>Ko'k choy — 5 000 so'm.</p></section>
</div>Nimaga qarang: "Ichimliklar" ni bosing — ramka ichidagi matn yuqoriga silliq suriladi, sakramaydi. Kelgan bo'lim sarlavhasi qizg'ish bo'ladi (Holat pseudo-klasslari darsidagi :target). Sarlavha yashil menyu tasmasi ostida qolib ketmadi — uni scroll-margin-top: 44px pastroqqa to'xtatdi (position: fixed va sticky darsidagi usul).
Chrome'da o'lchadik: havola bosilgach, ramka ichidagi skroll 0 dan boshlab bir necha kadrda oxirgi joyiga yetdi. Silliqlik davomiyligini CSS'da sozlab bo'lmaydi — tezlikni brauzer o'zi tanlaydi.
2.2 Harakatni kamaytirishni hurmat qiling
Silliq skroll — harakat. Muvozanat a'zosi (vestibulyar tizim) sezgir odamda uzun sahifa bo'ylab "uchish" bosh aylanishiga sabab bo'lishi mumkin (prefers-reduced-motion darsi). Shuning uchun uni faqat foydalanuvchi qarshi bo'lmasa yoqamiz:
@media (prefers-reduced-motion: no-preference) {
html {
scroll-behavior: smooth;
}
}Harakat o'chirilgan qurilmada havola avvalgidek sakraydi — ishlaydi, faqat silliqliksiz.
2.3 Silliq skrollning ikki tuzog'i
- Uzun sahifada sekinlik. "Yuqoriga" havolasi 20 ekranlik blog maqolasida bir soniyadan ko'proq "uchishi" mumkin. Foydalanuvchi uchun bu kutish. Juda uzun sahifalarda silliqlikni faqat ichki navigatsiyaga bering, butun
htmlga emas. - Sahifadan qidirish.
Ctrl + Ftopgan so'zga o'tish ham "dasturiy" skroll.smoothbo'lsa, har topilgan so'zga silliq suriladi — ba'zilarga qulay, ba'zilarga sekin.
Baseline ma'lumotiga ko'ra scroll-behavior — widely available (keng tarqalgan), 2022-yil martidan hamma asosiy brauzerda.
Tekshirib ko'ring:
scroll-behavior: smoothnibodyga yozdingiz, lekin menyu havolalari hali ham sakrayapti. Nega?
Javob
Sahifaning skroll konteyneri — html, body emas. scroll-behavior skrollni boshqarayotgan konteynerga yoziladi. html { scroll-behavior: smooth; } deb yozing (va uni prefers-reduced-motion bilan o'rang).
3. Scroll snap: "magnitli" skroll
3.1 Birinchi lenta
Scroll snap — skroll konteynerga "to'xtash nuqtalari" beradigan CSS moduli. Foydalanuvchi surishni tugatganda brauzer skrollni eng yaqin nuqtaga tortib qo'yadi. Xuddi magnitli taxta kabi: shashka donasini katak chegarasiga yaqin qo'ysangiz, u o'zi katak o'rtasiga "chiqib" o'tiradi.
Ikki qism kerak:
- Konteynerga —
scroll-snap-type: qaysi o'q bo'yicha va qanchalik qattiq tortilsin. - Elementlarga —
scroll-snap-align: elementning qaysi joyi to'xtash nuqtasi bo'lsin.
<style>
.lenta {
display: flex;
gap: 12px;
overflow-x: auto;
padding-block-end: 8px;
font-family: system-ui, sans-serif;
}
.magnit {
scroll-snap-type: x mandatory;
}
.taom-karta {
flex: 0 0 75%;
padding: 16px;
border: 2px solid #2f6b3a;
border-radius: 12px;
background-color: #fffaf0;
}
.magnit .taom-karta {
scroll-snap-align: start;
}
h3 { margin-block: 16px 8px; }
</style>
<h3>❌ Magnitsiz</h3>
<div class="lenta" tabindex="0" aria-label="Taomlar, magnitsiz">
<article class="taom-karta">Osh — 35 000 so'm</article>
<article class="taom-karta">Lag'mon — 28 000 so'm</article>
<article class="taom-karta">Manti — 30 000 so'm</article>
</div>
<h3>✅ Magnitli</h3>
<div class="lenta magnit" tabindex="0" aria-label="Taomlar, magnitli">
<article class="taom-karta">Osh — 35 000 so'm</article>
<article class="taom-karta">Lag'mon — 28 000 so'm</article>
<article class="taom-karta">Manti — 30 000 so'm</article>
</div>Nimaga qarang: ikkala lentani ham barmoq, touchpad yoki Shift + g'ildirak bilan yon tomonga suring. Birinchisi qayerda qo'yib yuborsangiz, o'sha yerda to'xtaydi. Ikkinchisi doim kartaning chap chetiga "yopishadi" — lag'mon kartasi lenta boshida to'liq ko'rinadi. Karta eni 75%: keyingi kartaning bir bo'lagi o'ngdan chiqib turadi — bu foydalanuvchiga "yana bor, suring" deb ishora qiladi.
tabindex="0" va aria-label — Overflow darsidagi jadval-orami qoidasi: klaviatura foydalanuvchisi lentaga Tab bilan kirib, strelkalar bilan suradi. Strelka bilan surganda ham snap ishlaydi.
3.2 scroll-snap-type: o'q va qattiqlik
Qiymat ikki qismdan iborat:
| Qism | Qiymatlar | Ma'nosi |
|---|---|---|
| O'q | x, y, both, inline, block |
Qaysi yo'nalishda tortilsin |
| Qattiqlik | mandatory, proximity |
Har doimmi yoki yaqin bo'lsagina |
mandatory(majburiy) — skroll har doim biror nuqtada to'xtaydi. Oraliq holat yo'q.proximity(yaqinlik) — nuqtaga yaqin to'xtasa tortiladi, uzoqda to'xtasa — qo'yib yuborilgan joyda qoladi. Qiymat yozilmasa —proximity.
Barmoq qo'yib yuborilgan paytda brauzer shunday qaror qiladi:
flowchart TD
A["Barmoq qo'yib yuborildi"] --> B{"Qattiqlik?"}
B -->|mandatory| C["Eng yaqin nuqtaga tortiladi"]
B -->|proximity| D{"Nuqta yaqinmi?"}
D -->|Ha| C
D -->|Yo'q| E["Shu joyda qoladi"]Nimaga qarang: mandatory da "shu joyda qoladi" degan yo'l umuman yo'q. Shuning uchun u kuchli, lekin ehtiyot bo'lish kerak — pastda, «Vertikal snap va mandatory tuzog'i» bo'limida ko'ramiz.
Chrome'da o'lchadik: 240 pikselli kartalar, oralig'i 12 piksel. Skrollni JavaScript bilan 130 pikselga qo'ydik:
| Konteyner | Natija |
|---|---|
x mandatory |
252 — ikkinchi kartaning boshiga tortildi |
x proximity |
130 — nuqtadan uzoq, o'z joyida qoldi |
x proximity, 60 ga qo'yilganda |
0 — birinchi nuqtaga yaqin, tortildi |
"Yaqin" qancha ekanini brauzer o'zi hal qiladi — CSS'da sozlanmaydi.
3.3 scroll-snap-align: elementning qaysi cheti
start — elementning boshi konteyner boshiga, center — o'rtasi o'rtasiga, end — oxiri oxiriga. Ikki qiymat yozilsa: birinchisi vertikal (block), ikkinchisi gorizontal (inline) o'q uchun.
Galereya uchun center qulay — tanlangan rasm doim ekran o'rtasida:
<style>
.galereya {
display: flex;
gap: 12px;
overflow-x: auto;
scroll-snap-type: x mandatory;
padding-block: 8px;
}
.galereya div {
flex: 0 0 60%;
height: 120px;
border-radius: 12px;
scroll-snap-align: center;
display: grid;
place-items: center;
color: #fffaf0;
font: bold 20px system-ui, sans-serif;
}
.galereya div:nth-child(odd) { background-color: #2f6b3a; }
.galereya div:nth-child(even) { background-color: #b4461a; }
</style>
<div class="galereya" tabindex="0" aria-label="Choyxona rasmlari">
<div>Hovli</div>
<div>Tandir</div>
<div>Supa</div>
<div>Choynaklar</div>
</div>Nimaga qarang: boshida "Hovli" chap chetda turibdi — undan chaproqqa surib bo'lmaydi, shuning uchun birinchi element hech qachon o'rtaga chiqmaydi. "Tandir" ga suring — u aniq o'rtada to'xtaydi, ikki yonida qo'shnilarining bo'lagi ko'rinadi. Chrome'da o'lchadik (320 pikselli konteyner, 240 pikselli elementlar, oralig'i 12): center bilan skroll 212 pikselda to'xtadi — ikkinchi elementning o'rtasi (252 + 120 = 372) konteyner o'rtasiga (212 + 160 = 372) aynan tushdi.
Tekshirib ko'ring: Kartalar lentasida
scroll-snap-type: x mandatoryyozildi, lekin lenta magnitlanmayapti. Kartalardascroll-snap-alignyo'q. Nima bo'ladi?
Javob
Hech narsa tortilmaydi. scroll-snap-type faqat "bu konteyner magnitli" deydi. To'xtash nuqtalari esa elementlarda — scroll-snap-align bo'lmasa, nuqta yo'q, tortadigan joy ham yo'q. Ikki qism doim birga yoziladi.
4. Snap nuqtasini surish: scroll-padding va scroll-margin
4.1 Konteyner ichki chekinishi
Lentaga ichki padding berdingiz — kartalar chetga yopishmasin. Lekin snap nuqtasi hali ham konteynerning eng chetida. Birinchi kartadan keyingilari chetga yopishib to'xtaydi.
scroll-padding konteynerga aytadi: "to'xtash chizig'ing chetdan shuncha ichkarida". position: fixed va sticky darsida uni scroll-padding-top sifatida ko'rgan edik — yopishqoq sarlavha ostida qolmaslik uchun. Snap uchun ham xuddi shu xususiyat:
.lenta {
padding-inline: 16px;
scroll-padding-inline: 16px;
}Chrome'da o'lchadik: padding-inline: 16px va scroll-padding-inline: 16px bilan ikkinchi karta 16 pikselli chekinish bilan to'xtadi — birinchi karta turgan chiziqda. Demak, padding va scroll-padding qiymati bir xil bo'lsa, hamma karta bir chiziqda turadi.
4.2 Element tashqi chekinishi
scroll-margin — elementning o'ziga: "meni to'xtatganda atrofimda shuncha joy qoldir". Menyu misolidagi scroll-margin-top: 44px aynan shu edi. Farqi position: fixed va sticky darsidagidek: scroll-padding — butun konteyner uchun bitta qoida, scroll-margin — alohida element uchun.
Baseline ma'lumotiga ko'ra scroll snap moduli — widely available, ya'ni bemalol ishlatish mumkin. Xususiyatlar brauzerlarga har xil vaqtda to'liq yetib kelgan. scroll-snap-align — 2020-yil yanvarida, scroll-padding va scroll-margin-top — 2021-yil aprelida. Mantiqiy scroll-padding-inline — 2021-yil sentabrida, scroll-snap-type esa 2022-yil aprelida (Firefox 99 dagi tuzatish bilan).
5. Vertikal snap va mandatory tuzog'i
5.1 "Hikoyalar" — butun ekranli bo'limlar
Telegram va Instagram hikoyalari kabi: har bo'lim — bitta ekran, surganda keyingisiga tortiladi.
<style>
.hikoyalar {
height: 100vh;
overflow-y: auto;
scroll-snap-type: y mandatory;
margin: -8px;
}
.hikoyalar section {
height: 100vh;
scroll-snap-align: start;
display: grid;
place-items: center;
color: #fffaf0;
font: bold 28px system-ui, sans-serif;
}
.hikoyalar section:nth-child(1) { background-color: #2f6b3a; }
.hikoyalar section:nth-child(2) { background-color: #b4461a; }
.hikoyalar section:nth-child(3) { background-color: #1a5d1a; }
</style>
<div class="hikoyalar" tabindex="0" aria-label="Kun hikoyalari">
<section>Ertalab — ko'k choy</section>
<section>Tushlik — osh</section>
<section>Kechqurun — manti</section>
</div>Nimaga qarang: ramka ichida g'ildirakni bir marta aylantiring — yashil ekran o'rniga qizg'ishi to'liq keladi, oraliqda to'xtamaydi. Bu yerda 100vh sabab natija oynasi 400 pikselga qotadi, har bo'lim ham 400 piksel. margin: -8px — body ning brauzer bergan chekinishini yopadi (Box model).
5.2 Tuzoq: element ekrandan baland bo'lsa
Aytaylik, "Tushlik" bo'limiga uzun menyu qo'shildi va u ekrandan ikki barobar baland bo'ldi. mandatory da foydalanuvchi uning o'rtasini o'qiy oladimi?
CSS standarti bu holatni hisobga olgan: element konteynerdan katta bo'lsa, brauzer uning ichida erkin skrollga ruxsat berishi kerak. Zamonaviy brauzerlar shunday qiladi. Lekin tajribada boshqa muammolar qoladi:
- Telefonda brauzer paneli yashirinib-chiqqanda
100vho'zgaradi va snap "tebranadi" (Viewport birliklari). - Klaviatura bilan
Tabbosilganda fokus olgan element ko'rinmay qolishi mumkin — snap uni qaytadan tortib ketadi. - Sahifa balandligi o'zgarsa (rasm yuklandi), skroll birdan boshqa bo'limga sakraydi.
Qoida: butun sahifa uchun proximity, mandatory esa faqat bir xil o'lchamli elementlar (kartalar, rasmlar) turgan ichki lentalarda.
5.3 scroll-snap-stop: bittadan o'tkazmaslik
Telefonda qattiq "silkitib" surilsa, lenta bir nechta kartani uchib o'tib ketadi. Ba'zan bu kerak emas — masalan, onboarding'da (ilova bilan tanishtiruvchi ekranlar) har ekranni ko'rsatish shart.
.taom-karta {
scroll-snap-align: start;
scroll-snap-stop: always;
}always — "qanchalik tez surilsa ham, har bir elementda to'xta". Sukut bo'yicha normal — o'tib ketishi mumkin. Baseline ma'lumotiga ko'ra u 2022-yil iyulidan hamma asosiy brauzerda (widely available). Ehtiyot bo'ling: 30 ta rasmli galereyada always foydalanuvchini har rasmda to'xtatib, zeriktiradi.
Tekshirib ko'ring: Blog sahifasiga
html { scroll-snap-type: y mandatory; }va harh2gascroll-snap-align: startqo'shildi. Nega bu yomon fikr?
Javob
Bo'limlar har xil uzunlikda, ko'pi ekrandan baland. mandatory da skroll doim sarlavhaga tortiladi: o'quvchi paragrafning o'rtasida to'xtab o'qiy olmasligi, bo'lim oxiri ko'rinmay qolishi mumkin. Rasm yuklanganda sahifa sakraydi. Matnli sahifa uchun snap umuman kerak emas, zarur bo'lsa — proximity.
6. Lenta chetida: overscroll-behavior
Overflow darsida skroll zanjiri (scroll chaining) ni ko'rgan edik: ichki konteyner oxiriga yetganda skroll tashqi sahifaga "o'tib ketadi". Gorizontal lentada boshqa xavf bor: chetga yetgach yana surilsa, brauzer buni "oldingi sahifaga qaytish" imo-ishorasi (swipe navigation) deb tushunishi mumkin. MDN'ga ko'ra contain ana shu imo-ishorani ham, tepadan tortib yangilashni (pull-to-refresh) ham o'chiradi.
.lenta {
overscroll-behavior-x: contain;
}contain — skroll lenta ichida qoladi, tashqariga uzatilmaydi. Baseline holatini Overflow darsida ko'rgan edik: rasman Baseline emas — Safari'da qisman. MDN'ning brauzerlar jadvalida izoh bor: Safari 16 dan beri qo'llaydi, lekin sig'magan kontenti yo'q konteynerda xususiyat ishlamaydi. Lentada kontent doim sig'maydi — asosiy holat hamma joyda ishlaydi.
7. JavaScript tomoni: scrollend va snap hodisalari
Ba'zan "skroll tugadi" degan xabar kerak: lenta ostidagi nuqtachalardan qaysi biri faol ekanini ko'rsatish uchun. JavaScript'ni 08-qismdan o'rganasiz, hodisalarni esa Fokus, scroll va resize hodisalari darsida — hozir faqat nomlarini bilib qo'ying:
const lenta = document.querySelector(".lenta");
lenta.addEventListener("scrollend", () => {
console.log("To'xtadi:", lenta.scrollLeft);
});scrollend— skroll to'liq to'xtaganda (snap tortishi ham tugagach) bir marta keladi. Baseline ma'lumotiga ko'ra u yangi Baseline: 2025-yil dekabridan hamma asosiy brauzerda — oxirgi bo'lib Safari 26.2 qo'shdi. Eski brauzerda bu hodisa kelmaydi.scrollsnapchangevascrollsnapchanging— "magnit boshqa elementga o'tdi" va "o'tmoqda". Juda qulay, lekin hozircha faqat Chrome va Edge'da (129-versiyadan) — Baseline emas.
CSS'da ham shunga o'xshash yangilik bor: Container queries darsida tilga olingan snapped holati. Konteynerga container-type: scroll-state beriladi va @container scroll-state(snapped: x) bilan hozir tortilgan element bezaladi. Baseline ma'lumotiga ko'ra u hozircha faqat Chrome va Edge'da (133-versiyadan), Baseline emas. Uni faqat bezak sifatida ishlating: boshqa brauzerlarda snap ishlaydi, faqat ajratib ko'rsatish bo'lmaydi.
8. Ko'p uchraydigan xatolar
8.1 Snap konteynerida overflow yo'q
scroll-snap-type ni display: flex li oddiy blokka yozdingiz, kartalar esa ekrandan chiqib ketdi. Konteynerda overflow-x: auto yo'q — u skroll konteyner emas, magnit ishlashi uchun joy yo'q. Tuzatish: overflow-x: auto qo'shing.
8.2 Kartalar siqilib, hammasi sig'ib qoldi
Flex lentada kartalarga eni berilmagan — flex-shrink ularni konteynerga siqdi (flex algoritmi). Skroll yo'q, snap ham yo'q. Tuzatish: flex: 0 0 75% (o'smasin, qisqarmasin, eni 75%).
8.3 Oxirgi karta chetga yetmaydi
scroll-snap-align: start li lentaning oxirgi kartasi hech qachon chap chetga kelmaydi — undan keyin skroll qilishga joy yo'q. Bu xato emas, geometriya: brauzer imkon qadar yaqin nuqtada to'xtatadi. Kerak bo'lsa, oxirgi kartadan keyin bo'sh joy qo'shing yoki center ishlating.
8.4 Skrollbarni yashirish
Lenta chiroyli bo'lsin deb skrollbar yashirildi, sichqonchali kompyuterda esa foydalanuvchi lentani surish mumkinligini bilmay qoldi. Tuzatish: skrollbarni qoldiring yoki "oldinga/orqaga" tugmalarini qo'shing — bu Karusel darsining mavzusi.
9. Mashqlar
Mashqlarni kurs/mashqlar/06/ papkasida bajaring.
1-mashq (oson): silliq menyu
«Bahor» menyu sahifasiga silliq skroll qo'shing: butun sahifa uchun, faqat harakat kamaytirilmagan bo'lsa. Sahifa tepasida 56 pikselli yopishqoq sarlavha bor — havolaga sakraganda bo'lim sarlavhasi uning ostida qolmasin.
Ishora: ikkala xususiyat ham html ga: biri silliqlik uchun, biri yopishqoq sarlavha uchun (scroll-padding-top).
Yechim
html {
scroll-padding-top: 4rem; /* 56px sarlavha + 8px havo */
}
@media (prefers-reduced-motion: no-preference) {
html {
scroll-behavior: smooth;
}
}scroll-padding-top media query'dan tashqarida: sarlavha ostida qolmaslik harakatga bog'liq emas, u doim kerak. Faqat silliqlik foydalanuvchi sozlamasiga bog'liq.
2-mashq (o'rta): taomlar lentasi
Menyu sahifasida telefon uchun "Bugungi taomlar" lentasi yasang:
- Kartalar gorizontal qatorda, eni 80%, oralig'i 12px.
- Lenta ichki chekinishi 16px, kartalar shu chiziqda to'xtasin.
- Magnit — majburiy, kartaning boshi bo'yicha.
- Lenta oxirida skroll sahifaga o'tib ketmasin.
- Klaviatura bilan ham surilsin.
Ishora: 2-band uchun padding-inline va scroll-padding-inline bir xil. 5-band — HTML atributlari.
Yechim
<style>
.lenta {
display: flex;
gap: 12px;
overflow-x: auto;
padding: 8px 16px;
scroll-padding-inline: 16px;
scroll-snap-type: x mandatory;
overscroll-behavior-x: contain;
font-family: system-ui, sans-serif;
}
.taom-karta {
flex: 0 0 80%;
padding: 16px;
border: 2px solid #2f6b3a;
border-radius: 12px;
background-color: #fffaf0;
scroll-snap-align: start;
}
.narx { color: #b4461a; font-weight: bold; }
</style>
<div class="lenta" tabindex="0" aria-label="Bugungi taomlar">
<article class="taom-karta"><h3>Osh</h3>
<p class="narx">35 000 so'm</p></article>
<article class="taom-karta"><h3>Lag'mon</h3>
<p class="narx">28 000 so'm</p></article>
<article class="taom-karta"><h3>Manti</h3>
<p class="narx">30 000 so'm</p></article>
</div>tabindex="0" lentani Tab bilan fokuslanadigan qiladi, aria-label ekran o'quvchiga uning nomini aytadi. Fokus olgan lentani → strelkasi suradi, snap esa keyingi kartaga tortadi.
3-mashq (qiyin): ikki o'qli xarita
Choyxona hovlisining sxemasi 3×3 katakdan iborat, har katak konteyner o'lchamida (240×160px). Foydalanuvchi har yo'nalishda sursin va har safar bitta katak to'liq ko'rinsin. Tez "silkitganda" ham katak o'tkazib yuborilmasin.
Ishora: o'q — both. Kataklar grid bilan: grid-template-columns: repeat(3, 100%). Ikki qiymatli scroll-snap-align yoki bitta start (ikkala o'qqa ham qo'llanadi).
Yechim
<style>
.hovli {
width: 240px;
height: 160px;
overflow: auto;
scroll-snap-type: both mandatory;
display: grid;
grid-template-columns: repeat(3, 100%);
grid-auto-rows: 100%;
border: 2px solid #2f6b3a;
}
.hovli div {
scroll-snap-align: start;
scroll-snap-stop: always;
display: grid;
place-items: center;
font: bold 18px system-ui, sans-serif;
}
.hovli div:nth-child(odd) { background-color: #e8f1ec; }
.hovli div:nth-child(even) { background-color: #fffaf0; }
</style>
<div class="hovli" tabindex="0" aria-label="Hovli sxemasi">
<div>Darvoza</div><div>Supa 1</div><div>Supa 2</div>
<div>Hovuz</div><div>Tandir</div><div>Supa 3</div>
<div>Oshxona</div><div>Choyxona</div><div>Bog'</div>
</div>grid-auto-rows: 100% — har qator konteyner balandligida, repeat(3, 100%) — har ustun konteyner enida. Shunda har katak aynan bitta "oyna". scroll-snap-align: start bitta qiymat bilan ikkala o'qqa ham ishlaydi. scroll-snap-stop: always tez surilganda ham har katakda to'xtatadi.
4-mashq: Portfolio qadami — silliq o'tish havolalari
Portfolio'da sahifa ichidagi havola bor: har sahifa boshidagi .otish (skip link) #asosiy ga olib boradi. Bosh sahifaga yana bitta qo'shing va skrollni silliq qiling.
- Bosh sahifa footer'iga "Yuqoriga" havolasi:
<a href="#asosiy">Yuqoriga</a>(footerdagipichida). asosiy.cssga: sahifa skrolli silliq, faqat harakat kamaytirilmagan bo'lsa.- Havola
mainga olib borgandah1ekran chetiga yopishmasin: 1rem havo qolsin. - Telefon va kompyuterda, keyin OS sozlamalarida "harakatni kamaytirish" ni yoqib tekshiring. So'ng
npm run check.
Ishora: 3-band — nishon elementning o'ziga (main) scroll-margin-top. Harakat sozlamasini DevTools'da ham o'zgartirish mumkin: Rendering paneli → prefers-reduced-motion (Foydalanuvchi afzalliklari).
Yechim
index.html footer'i — mavjud ikki paragraf orasiga yangisi:
<footer>
<p>
<a href="mailto:aziz@example.com">aziz@example.com</a> ·
<a href="https://t.me/sizning_kanal">Telegram</a>
</p>
<p><a href="#asosiy">Yuqoriga</a></p>
<p><small>© 2026 Aziz Karimov. Sayt faqat HTML'da.</small></p>
</footer>asosiy.css ning «Umumiy» qismidagi html qoidasidan keyin:
/* Sahifa ichidagi havolalar silliq surilsin (Skroll xulqi darsi) */
@media (prefers-reduced-motion: no-preference) {
html {
scroll-behavior: smooth;
}
}
/* Skip link va "Yuqoriga" dan kelganda sarlavha chetga yopishmasin */
main {
scroll-margin-top: 1rem;
}Footer'dagi oxirgi paragraf footer p:last-child qoidasi bilan kichik shriftda qolaveradi (Yakuniy loyiha) — yangi havola o'rtadagi paragrafda, oddiy o'lchamda. "Sayt faqat HTML'da" endi to'g'ri emas — xohlasangiz, "HTML va CSS" deb yangilang.
.otish ham endi silliq ishlaydi: Tab → Enter bosilganda sahifa main ga yumshoq o'tadi. Harakat kamaytirilgan qurilmada esa avvalgidek sakraydi. Tekshirganda buni DevTools'da ham ko'ring: Rendering paneli → "Emulate CSS media feature prefers-reduced-motion" → reduce.
10. Real ishda
- Onlayn do'konlar — mahsulot rasmlari galereyasi telefonda:
scroll-snap+center. - Hikoyalar va reels — to'liq ekranli vertikal snap.
- Hujjat saytlari — mundarija havolalari silliq,
scroll-padding-topyopishqoq sarlavha uchun. - Karusel kutubxonalari (Swiper, Embla) ichida ham ko'pincha aynan scroll snap. Kutubxona qachon kerakligini Karusel darsida ko'ramiz.
- Intervyuda: "JavaScript'siz karusel qanday qilinadi?" —
overflow-x: auto+scroll-snap-type+scroll-snap-align.
Xulosa
scroll-behavior: smooth— havola va fokus skrolli silliq;htmlga,prefers-reduced-motion: no-preferenceichida yoziladi.- Snap ikki qismdan: konteynerga
scroll-snap-type(o'q + qattiqlik), elementlargascroll-snap-align. mandatory— doim tortiladi, bir xil kartali lentalar uchun; butun sahifa uchun —proximity.scroll-paddingkonteynerdagi,scroll-marginelementdagi to'xtash chizig'ini suradi.scroll-snap-stop: always— elementni o'tkazib yubormaydi;overscroll-behavior-x: contain— skroll lentadan chiqmaydi.scrollend— yangi Baseline;scrollsnapchangevascroll-stateso'rovlari — hozircha faqat Chrome'da.
Keyingi dars: Scroll-driven animatsiyalar — animatsiyani vaqtga emas, skroll holatiga bog'lab, progress chizig'i va paydo bo'lish effektini JavaScript'siz yasaymiz.
Manbalar
- MDN: "scroll-behavior", "scroll-snap-type", "scroll-snap-align", "scroll-snap-stop", "scroll-padding", "scroll-margin", "overscroll-behavior", "scrollend event" — developer.mozilla.org
- W3C: "CSS Scroll Snap Module Level 1" — w3.org/TR/css-scroll-snap-1
- web-features (Baseline ma'lumotlari): "scroll-behavior", "scroll-snap", "overscroll-behavior", "scrollend", "scroll-snap-events", "container-scroll-state-queries" — github.com/web-platform-dx/web-features
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!