Margin collapse muammosi va yechimi
Muammodan boshlaylik
Ikki holat, ikkalasi ham "CSS buzilgan" deb o'ylatadi:
1. Ikki paragraf:
p {
margin-top: 20px;
margin-bottom: 30px;
}
Paragraflar orasidagi bo'shliq 20 + 30 = 50px bo'lishi kerak. DevTools da o'lchaysiz — 30px.
2. Kartochka ichidagi sarlavhaga margin-top: 40px berdingiz. Sarlavha kartochka ichida pastga tushmadi — butun kartochka 40px pastga surildi, sarlavha esa uning yuqori chetiga yopishib qoldi.
Bu xato emas. Bu — margin collapse (marginlar "qo'shilib ketishi"): CSS ning ataylab qilingan, lekin eng ko'p chalkashlik keltiradigan qoidalaridan biri.
Qoida: vertikal marginlar qo'shilmaydi — kattasi qoladi
Ikki vertikal margin to'qnashganda ular qo'shilmaydi. Natijada kattasi qoladi:
┌──────────────┐
│ 1-paragraf │
└──────────────┘
margin-bottom: 30px ┐
├─ to'qnashadi → 30px (kattasi), 50px emas
margin-top: 20px ┘
┌──────────────┐
│ 2-paragraf │
└──────────────┘
| Margin lar | Natija |
|---|---|
| 30px va 20px | 30px |
| 20px va 20px | 20px |
| 30px va −10px | 20px (manfiy bo'lsa — qo'shiladi) |
| −10px va −20px | −20px (ikkalasi manfiy — eng kichigi) |
[!INFO] Margin collapse faqat vertikal (tepa va past) marginlarda bo'ladi. Gorizontal (chap va o'ng) marginlar hech qachon qo'shilib ketmaydi — ular har doim yig'iladi.
Uch holat
1. Qo'shni elementlar
Yuqoridagi paragraflar misoli. Bu holat foydali: matn sahifasida har bir element "men atrofimda kamida 30px bo'shliq bo'lsin" deydi, va qo'shnilar bo'shliqni ikki baravar oshirib yubormaydi.
2. Ota va birinchi/oxirgi bola
<div class="card">
<h2>Sarlavha</h2>
</div>
.card {
background: #f1f5f9;
}
.card h2 {
margin-top: 40px;
}
Ota (.card) va uning birinchi bolasi (h2) orasida hech narsa yo'q — padding ham, border ham, matn ham. Shuning uchun bolaning margin-top i otaning chetidan "sizib chiqadi" va otaning o'z margini bilan birlashadi. Natija: butun .card 40px pastga suriladi — darsning boshidagi 2-holat.
Kutilgan: Haqiqatda:
┌─ .card ─────────┐ ↕ 40px (kartochka tashqarisida!)
│ ↕ 40px │ ┌─ .card ─────────┐
│ Sarlavha │ │ Sarlavha │
└─────────────────┘ └─────────────────┘
Oxirgi bolaning margin-bottom i bilan ham xuddi shunday.
3. Bo'sh element
Balandligi, padding i, border i va kontenti yo'q element — uning o'z margin-top va margin-bottom i bir-biri bilan birlashadi. Kamdan-kam uchraydi.
Yechimlar
Collapse faqat marginlar bevosita to'qnashganda bo'ladi. Ular orasiga biror narsa qo'ysangiz — to'xtaydi.
Ota-bola holati uchun
/* 1. Margin o'rniga otaga padding */
.card {
padding-top: 40px;
}
/* 2. Otaga padding yoki border — hatto 1px ham yetarli */
.card {
padding: 24px;
}
/* 3. Yangi formatlash konteksti */
.card {
display: flow-root;
}
display: flow-root — aynan shu maqsad uchun yaratilgan: elementni "mustaqil" qiladi, bolalarining margini undan sizib chiqmaydi. Ko'rinishga boshqa hech narsa ta'sir qilmaydi.
Flexbox va Grid — collapse yo'q
.card {
display: flex;
flex-direction: column;
}
Flex va Grid konteynerlar ichida margin collapse umuman bo'lmaydi. Bu ularning ko'p sabablardan biri, nima uchun zamonaviy layout lar asosan shular bilan quriladi (3–4-bo'limlar).
Qo'shnilar uchun — bir tomonlama margin
Eng sodda va eng tushunarli usul: marginni faqat bir yo'nalishda bering:
/* ❌ ikki tomonlama — collapse va chalkashlik */
.card {
margin-top: 20px;
margin-bottom: 20px;
}
/* ✅ faqat pastdan */
.card {
margin-bottom: 20px;
}
Yoki zamonaviyroq — "lobotomized owl" selektori (4-dars kombinatorlari):
.stack > * + * {
margin-top: 16px;
}
".stack ning har bir bolasi, agar undan oldin boshqa bola bo'lsa — tepadan 16px". Birinchi elementdan oldin bo'shliq yo'q, qolganlari orasida — teng. Collapse ga joy qolmaydi.
Eng yaxshisi — gap
.stack {
display: flex;
flex-direction: column;
gap: 16px;
}
gap — faqat elementlar orasida, chetlarda emas, collapse yo'q, hisoblash yo'q. Komponentlar ichida bo'shliq uchun bugungi eng yaxshi tanlov (14-dars).
Collapse bo'lmaydigan holatlar
Margin collapse bo'lmaydi, agar:
- Marginlar gorizontal bo'lsa
- Element flex yoki grid item bo'lsa
- Element
position: absoluteyokifixedbo'lsa - Element
floatbo'lsa - Element
display: inline-blockbo'lsa - Ota
display: flow-root,overflow: hidden/autoyoki padding/border ga ega bo'lsa (ota-bola holati uchun)
Nima uchun shunday?
Nima uchun CSS marginlarni "yutib yuboradigan" qilib loyihalangan — bu xato emasmi?
Yo'q — bu matnli hujjatlar uchun loyihalangan va u yerda juda mantiqiy. Tasavvur qiling: sarlavha "mendan keyin 24px bo'shliq bo'lsin" deydi, paragraf esa "mendan oldin 16px". Ular yonma-yon kelganda 40px bo'shliq hujjatni tarqoq qiladi — tipografik qoidalar bo'yicha bo'shliq kattasi bo'lishi kerak: 24px. Margin collapse aynan shuni qiladi, va maqola, blog, hujjat sahifalarida avtomatik chiroyli ritm beradi. Muammo faqat CSS "hujjat" emas, "ilova interfeysi" quradigan bo'lganda paydo bo'ldi — kartochkalar, panellar. Shuning uchun komponentlar uchun Flexbox, Grid va gap ga o'tish tavsiya etiladi: u yerda bunday qoida yo'q.
Xulosa
Eslab qoling:
- Ikki vertikal margin to'qnashsa — qo'shilmaydi, kattasi qoladi
- Gorizontal marginlar hech qachon collapse bo'lmaydi
- Uch holat: qo'shni elementlar; ota va birinchi/oxirgi bola; bo'sh element
- Ota-bola: otaga
padding/borderyokidisplay: flow-root - Flex va Grid ichida collapse yo'q
- Bir tomonlama margin (
margin-bottom) yoki.stack > * + * - Eng yaxshisi —
display: flex/grid+gap
Keyingi dars
10-dars: Overflow — visible, hidden, scroll, auto