Flexbox bilan amaliy layoutlar — nav, card, markazlash
Muammodan boshlaylik
13–16-darslarda Flexbox ning har bir xususiyatini alohida ko'rdik. Haqiqiy ishda esa ular birga ishlatiladi va bir xil naqshlar (pattern) qayta-qayta takrorlanadi: header, kartochka, forma qatori, sticky footer, markazlash.
Bu dars — eng ko'p uchraydigan 6 ta layout. Har birini avval o'zingiz yozib ko'ring, keyin yechimni oching. Har bir yechimni HTML faylga qo'yib, brauzerda tekshiring va DevTools da (Flexbox panelida — konteyner yonidagi flex belgisini bosing) chizilgan o'qlarni ko'ring.
1-mashq: Header
┌────────────────────────────────────────────────────────────┐
│ ◆ DevDocs Kurslar Blog Haqida [Kirish] │
└────────────────────────────────────────────────────────────┘
Talablar:
- Logo chapda, menyu havolalari logodan keyin, "Kirish" tugmasi o'ng chetda
- Hammasi vertikal o'rtada
- Balandlik 64px
<header class="header">
<a class="logo" href="/">◆ DevDocs</a>
<nav class="nav">
<a href="/kurslar">Kurslar</a>
<a href="/blog">Blog</a>
<a href="/haqida">Haqida</a>
</nav>
<a class="btn" href="/kirish">Kirish</a>
</header>
Yechim
.header {
display: flex;
align-items: center;
gap: 32px;
height: 64px;
padding: 0 24px;
}
.nav {
display: flex;
gap: 20px;
}
.header .btn {
margin-left: auto; /* barcha bo'sh joyni yutib, o'ng chetga */
}
justify-content: space-between bu yerda ishlamaydi: u menyuni o'rtaga qo'yib qo'yardi (uchta element orasida teng bo'shliq). Bitta elementni chetga surish uchun — margin-left: auto (15-dars).
2-mashq: Mukammal markazlash
Login formasi ekranning aniq o'rtasida, ekran qanday bo'lmasin.
Yechim
.page {
display: flex;
justify-content: center;
align-items: center;
min-height: 100dvh; /* 11-dars: mobil uchun dvh */
padding: 16px;
}
.login-card {
width: 100%;
max-width: 400px;
}
min-height (height emas) — forma ekrandan baland bo'lsa ham kesilmaydi va sahifa scroll bo'ladi. padding — telefonda forma ekran chetiga yopishmasligi uchun.
Muqobil — bitta element uchun yanada qisqa:
.page {
display: flex;
min-height: 100dvh;
}
.login-card {
margin: auto; /* flex ichida — to'rt tomondan markazlash */
}
3-mashq: Mahsulot kartochkalari
┌──────────┐ ┌──────────┐ ┌──────────┐
│ [rasm] │ │ [rasm] │ │ [rasm] │
│ Noutbuk │ │ Telefon │ │ Quloqchin│
│ Qisqa │ │ Juda uzun│ │ Tavsif │
│ tavsif │ │ tavsif │ │ │
│ │ │ ikki-uch │ │ │
│ │ │ qatorli │ │ │
│ 12 mln │ │ 8 mln │ │ 900 ming │
│ [Savat] │ │ [Savat] │ │ [Savat] │
└──────────┘ └──────────┘ └──────────┘
Talablar:
- Kartochkalar teng kenglikda, kamida 240px; sig'masa keyingi qatorga
- Hammasi bir xil balandlikda
- Narx va tugma har doim pastda, tavsif uzunligidan qat'i nazar
Yechim
.cards {
display: flex;
flex-wrap: wrap;
gap: 24px;
}
.card {
flex: 1 1 240px; /* o'sadi, qisqaradi, boshlang'ich 240px */
display: flex;
flex-direction: column;
gap: 8px;
padding: 16px;
border: 1px solid #e2e8f0;
border-radius: 12px;
}
.card img {
width: 100%;
aspect-ratio: 4 / 3;
object-fit: cover;
border-radius: 8px;
}
.card .price {
margin-top: auto; /* bo'sh joyni yutadi → narx va tugma pastga */
font-weight: 700;
}
- Tashqi flex (
.cards) — kartochkalarni qatorga tizadi va bir xil balandlik beradi (stretch) - Ichki flex (
.card,column) —margin-top: autobilan pastki qismni pastga suradi flex: 1 1 240px— 1000px konteynerda 3 ta, 600px da 2 ta, telefonda 1 ta
Kamchilik: oxirgi qatorda 1 ta kartochka qolsa, u butun kenglikka cho'ziladi. Har bir qatorda bir xil ustunlar kerak bo'lsa — Grid yaxshiroq (22-dars).
4-mashq: Sticky footer
Kontent kam bo'lsa ham footer ekranning pastida tursin; kontent ko'p bo'lsa — oddiy holda sahifa oxirida.
<body>
<header>...</header>
<main>...</main>
<footer>...</footer>
</body>
Yechim
body {
display: flex;
flex-direction: column;
min-height: 100dvh;
margin: 0;
}
main {
flex: 1; /* header va footer dan qolgan barcha joy */
}
Uch qator. Flexbox gacha bu masala uchun manfiy marginlar va aniq footer balandligi talab qilinardi.
5-mashq: Forma qatori
┌──────────────────────────────────────────────────────┐
│ [ email@example.com ........................ ][Obuna]│
└──────────────────────────────────────────────────────┘
Talablar:
- Input qolgan barcha joyni egallaydi, tugma o'z o'lchamida
- Telefonda (400px dan tor) — tugma input ostida, to'liq kenglikda
Yechim
.subscribe {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.subscribe input {
flex: 1 1 220px; /* kamida 220px; sig'masa — tugma pastga tushadi */
min-width: 0;
}
.subscribe button {
flex: 0 0 auto;
}
@media (max-width: 400px) {
.subscribe button {
flex-basis: 100%;
}
}
flex-wrap + flex-basis — media query siz ham deyarli to'g'ri moslashadi: input 220px dan torayishi kerak bo'lganda tugma keyingi qatorga o'tadi.
6-mashq: Media obyekt (izoh)
┌──────────────────────────────────────────────┐
│ (A) Abdurahmonbekov Muhammadali · 2 soat │
│ Juda foydali dars, rahmat! Flexbox... │
│ ♡ 12 Javob berish │
└──────────────────────────────────────────────┘
Talablar:
- Avatar 48×48, hech qachon siqilmaydi
- Matn qolgan joyda, uzun ism
…bilan qisqaradi - Vaqt — o'ng chetda
Yechim
.comment {
display: flex;
gap: 12px;
align-items: flex-start;
}
.comment .avatar {
flex: none;
width: 48px;
height: 48px;
border-radius: 50%;
}
.comment .body {
flex: 1;
min-width: 0; /* busiz uzun ism kartochkani kengaytirib yuboradi */
}
.comment .meta {
display: flex;
gap: 8px;
align-items: baseline;
}
.comment .name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.comment time {
flex: none;
margin-left: auto;
color: #64748b;
}
.comment .actions {
display: flex;
gap: 16px;
}
16-darsdagi chat xabari bilan deyarli bir xil — bu naqsh izohlar, bildirishnomalar, xabarlar, foydalanuvchi ro'yxatlarida qayta-qayta uchraydi.
Flexbox naqshlari — tezkor jadval
| Vazifa | Yechim |
|---|---|
| Markazlash | justify-content: center + align-items: center |
| Bitta elementni chetga | margin-left: auto |
| Qolgan joyni egallash | flex: 1 |
| Teng ustunlar | har biriga flex: 1 |
| Siqilmasin | flex: none yoki flex-shrink: 0 |
| Uzun matn qisqarsin | min-width: 0 + text-overflow: ellipsis |
| Pastga yopishtirish | ota column + margin-top: auto |
| Sticky footer | body column + main { flex: 1 } |
| Sig'masa — keyingi qatorga | flex-wrap: wrap + flex: 1 1 240px |
| Orasidagi bo'shliq | gap |
Nima uchun shunday?
Nima uchun bir xil naqshlarni yod olish foydali — har safar noldan o'ylab topish yaxshiroq emasmi?
Chunki layout masalalarining aksariyati yangi emas: header, kartochka, forma, izoh — har bir saytda bor va har safar bir xil muammolar chiqadi (uzun ism, turli uzunlikdagi tavsif, tor ekran). Naqshni bilsangiz, siz ham tezroq ishlaysiz, ham chekka holatlarni oldindan hisobga olasiz: min-width: 0 va flex: none — bular faqat bir marta "nega buzildi?" deb soatlab izlagandan keyin yodda qoladigan detallar. Bundan tashqari, umumiy naqshlar jamoada umumiy tilga aylanadi: "bu yerda media obyekt" desangiz, hamma darhol tushunadi.
Xulosa
Siz mashq qildingiz:
- Header —
margin-left: autobilan bitta elementni chetga - Markazlash —
center+centeryokimargin: auto - Kartochkalar — tashqi
wrap+ ichkicolumn+margin-top: auto - Sticky footer —
bodycolumn,main { flex: 1 } - Forma qatori —
flex: 1 1 220px+wrap - Media obyekt —
flex: none,flex: 1,min-width: 0
Keyingi bo'lim
4-bo'lim: Layout — Grid — ikki o'lchamli joylashuv: qatorlar va ustunlar birgalikda.