IlmHamroh
JavaScript Full-stack/5-qism. CSS asoslari va layout45/63-dars20 daqiqa
Mundarija (30)

CSS align-self, order va auto margin: flex tuzoqlari va min-width: 0

Qisqacha: align-self bitta flex elementni ko'ndalang o'q bo'ylab boshqalardan alohida tekislaydi. order elementni ekranda boshqa joyga qo'yadi, lekin klaviatura (Tab) va ekran o'quvchi baribir HTML tartibida yuradi — shuning uchun ma'noli tartibni HTML'da o'zgartiring. Asosiy o'qda bitta elementni surish — auto margin: margin-left: auto uni o'ng chetga itaradi, ustunda margin-top: auto — pastga. Flex element sukut bo'yicha o'z mazmunidan torroq qisqarmaydi (min-width: auto); matnni "…" bilan kesish yoki ichki skroll uchun unga min-width: 0 (ustunda min-height: 0) yoziladi.

Bu darsda

  • Bitta elementni align-self bilan alohida tekislaysiz.
  • order ko'rinishni qanday o'zgartirishini va nega Tab tartibini o'zgartirmasligini tushuntirasiz.
  • auto margin bilan elementni o'ng chetga yoki karta pastiga itarasiz.
  • Flex ichida "…" bilan qisqartirish va ichki skroll ishlamaganda min-width: 0 yoki min-height: 0 qo'yasiz.

Oldin bilishingiz kerak: flex-grow, flex-shrink va flex-basis, Margin sirlari, Overflow, Klaviatura va fokus.

1. Nega bu kerak?

Oldingi darslarda hamma xususiyat konteynerga yozilardi: "hammangiz o'rtaga", "hammangiz teng". Lekin real sahifada ko'pincha bitta element boshqacha bo'lishi kerak:

  • «Bahor» sarlavhasida logotip va menyu chapda, "Stolni band qilish" tugmasi esa o'ng chetda.
  • Menyu kartalari bir xil baland, lekin narx har kartaning pastida turishi kerak. Viewport birliklari darsida "kontentni blok pastiga joylashni Flexbox darslarida o'rganamiz" degan edik.
  • Kartalar orasida bitta "Aksiya" kartasi birinchi ko'rinsin.

Va bitta chala ish: o'tgan darsda uzun email flex element ichida qisqarmay, narxni kartadan itarib chiqardi. Bugun to'rttasini ham hal qilamiz.

2. align-self — bitta elementni alohida tekislash

align-self — align-items ning bitta element uchun varianti. U elementning o'ziga yoziladi va konteynerdagi align-items ni faqat shu element uchun bekor qiladi. Qiymatlari tanish: flex-start, center, flex-end, stretch, baseline. Sukut auto — "konteyner nima desa, shu".

«Bahor» menyusida taom kartasi: chapda rasm, o'rtada tavsif, o'ngda "Yangi" belgisi. Konteyner rasmni cho'zmaslik uchun flex-start (Flex'da tekislash darsidagi tuzoq), belgi esa o'rtada tursin:

html
<style>
  :root {
    --rang-asosiy: #2f6b3a;
    --rang-urgu: #b4461a;
  }
  .taom-karta {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    max-width: 26rem;
    padding: 8px;
    border: 2px solid var(--rang-asosiy);
  }
  .taom-karta svg {
    flex: none;
  }
  .taom-karta p {
    margin: 0;
  }
  .taom-karta strong {
    align-self: center;
    padding: 2px 8px;
    color: #fff;
    background-color: var(--rang-urgu);
    border-radius: 999px;
  }
</style>
<article class="taom-karta yangi">
  <svg width="64" height="64" viewBox="0 0 64 64" aria-hidden="true">
    <circle cx="32" cy="32" r="30" fill="#2f6b3a"/></svg>
  <p><b class="taom-nomi">Tandir go'sht</b> — sekin olovda,
  tandirda pishirilgan qo'y go'shti. Non va salat bilan
  tortiladi. Buyurtma kechqurun 18:00 dan.</p>
  <strong>Yangi</strong>
</article>

Nimaga qarang: rasm tepada, o'z bo'yida — konteynerning flex-start i ishladi. Rasmga flex: none ham yozildi: usiz uzun tavsif uni qisib qo'yardi (flex-shrink darsidagi "belgi siqilib qoldi" xatosi). "Yangi" belgisi esa kartaning o'rtasida — align-self: center faqat unga tegdi. Tavsif ham tepadan boshlangan.

Flex'da justify-self yo'q — Chrome'da tekshirdik, flex elementga yozilgan justify-self: end hech narsa qilmadi. Asosiy o'qda bitta elementni surishning boshqa yo'li bor — auto margin. Uni pastroqda, «auto margin — elementni itarish» bo'limida ko'ramiz.

3. order — ko'rinish tartibi

3.1 Qanday ishlaydi

order — flex elementning ekrandagi o'rnini belgilaydigan butun son. Sukut 0. Brauzer elementlarni order bo'yicha o'sish tartibida teradi. Bir xil order li elementlar HTML tartibida qoladi. Manfiy son ham mumkin: order: -1 — "hammadan oldin".

html
<style>
  :root {
    --rang-asosiy: #2f6b3a;
    --rang-urgu: #b4461a;
  }
  section {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
  }
  .taom-karta {
    flex: 1 1 8rem;
    padding: 0 12px;
    border: 2px solid var(--rang-asosiy);
  }
  .aksiya {
    order: -1;
    color: var(--rang-urgu);
    border-color: currentColor;
  }
</style>
<section>
  <article class="taom-karta"><h3>Osh</h3></article>
  <article class="taom-karta"><h3>Lag'mon</h3></article>
  <article class="taom-karta aksiya">
    <h3>Aksiya: manti −20%</h3>
  </article>
</section>

Nimaga qarang: HTML'da aksiya kartasi oxirgi, ekranda esa birinchi. Qolgan ikkitasining order i 0 — ular o'z tartibida qoldi.

3.2 Tuzoq: ko'z bir tartibda, Tab boshqasida

Endi eng muhim qism. order faqat ko'rinishni o'zgartiradi. HTML esa o'zgarmadi — va ko'pchilik uchun sahifa aynan HTML'dir:

  • Bobur faqat klaviatura bilan ishlaydi. Tab bosganda fokus HTML tartibida yuradi.
  • Malika ekran o'quvchi (NVDA) bilan eshitadi — u ham HTML tartibida o'qiydi.

Semantik skelet darsidagi qoida: kod tartibi — o'qish tartibi, "o'ngda" yoki "tepada" esa CSS ishi. Qulay forma darsida esa ogohlantirgan edik: "CSS bilan elementlarni joyidan siljitish mumkin. Unda ko'z bir tartibda o'qiydi, Tab boshqasida yuradi." Buni tekshiramiz. Uchta havola, order bilan teskari qo'yilgan:

html
<style>
  :root {
    --rang-asosiy: #2f6b3a;
  }
  nav {
    display: flex;
    gap: 16px;
  }
  a:focus-visible {
    outline: 3px solid var(--rang-asosiy);
    outline-offset: 2px;
  }
  a:nth-child(1) { order: 3; }
  a:nth-child(2) { order: 2; }
  a:nth-child(3) { order: 1; }
</style>
<nav aria-label="Asosiy menyu">
  <a href="menyu/">1. Menyu</a>
  <a href="bron/">2. Bron</a>
  <a href="aloqa/">3. Aloqa</a>
</nav>

Nimaga qarang: ekranda "3. Aloqa, 2. Bron, 1. Menyu" — o'ngdan chapga. Natijani bosing va Tab tugmasini uch marta bosing. Chrome'da tekshirdik: fokus "1. Menyu" → "2. Bron" → "3. Aloqa" tartibida yurdi — ya'ni ekranda o'ngdan chapga, teskari sakrab. Bobur uchun bu chalkash: fokus halqasi kutilmagan tomonga ketadi.

Bu WCAG'ning ikki mezonini buzishi mumkin (Accessibility nima):

  • 1.3.2 Ma'noli ketma-ketlik (A) — tartib ma'noga ta'sir qilsa, dastur o'qiydigan tartib ham to'g'ri bo'lsin.
  • 2.4.3 Fokus tartibi (A) — fokus mantiqiy tartibda yursin.

Qoida: ma'noli tartibni HTML'da o'zgartiring. CSS'dagi order ni esa faqat tartib ma'noga ta'sir qilmaydigan joyda ishlating: bezak elementlari yoki bosiladigan narsasi yo'q, tartibi farq qilmaydigan bloklar. Masalan, yuqoridagi aksiya kartasi chegarada turibdi: kartalar ichida havola bo'lsa, Tab avval Osh va Lag'monga, keyin ekrandagi birinchi kartaga boradi. To'g'ri yo'l — aksiya kartasini HTML'da birinchi yozish. Flexbox'ga kirish darsidagi row-reverse va column-reverse ga ham xuddi shu qoida.

3.3 Yangi yechim: reading-flow

CSS'ga yangi xususiyat qo'shilmoqda — reading-flow. reading-flow: flex-visual konteynerga yozilsa, Tab va ekran o'quvchi ekrandagi tartib bo'yicha yuradi. Chrome'da tekshirdik: yuqoridagi menyuga shu qatorni qo'shganda fokus "3. Aloqa" dan boshladi.

Lekin u Baseline emas. Baseline ma'lumotiga ko'ra hozircha faqat Chrome va Edge 137 dan beri bor, Firefox va Safari'da yo'q. U yerda xususiyat tashlab ketiladi va fokus yana HTML tartibida sakraydi. Shuning uchun zaxira yo'l o'zgarmaydi: HTML tartibini to'g'ri yozing. reading-flow ni faqat qo'shimcha himoya deb biling.

Tekshirib ko'ring: Dizayner telefonda "Stolni band qilish" tugmasi sahifa tepasida, kompyuterda esa pastda bo'lishini xohlaydi. HTML'da u pastda. order: -1 bilan telefonda tepaga chiqarsangiz, qanday muammo bo'ladi?

Javob

Telefonda tugma ekranda birinchi, lekin Tab bilan unga eng oxirida yetib boriladi — butun sahifadan keyin. Ekran o'quvchi ham uni oxirida o'qiydi. Bu yerda tartib ma'noga ta'sir qiladi (bu asosiy harakat), shuning uchun yechim — HTML'ni o'zgartirish. Masalan, tugmani HTML'da tepaga yozish yoki ikki joyda ikkita havola qo'yish.

4. auto margin — elementni itarish

4.1 margin-left: auto — o'ng chetga

Margin sirlari darsida auto margin "qolgan joyni o'zing ber" degani ekanini ko'rgan edik. U normal oqimda (flex'siz oddiy bloklarda) faqat gorizontal ishlaydi. Flex'da u ikkala o'qda ishlaydi va yanada kuchli: auto margin asosiy o'qdagi bo'sh joyni justify-content dan oldin o'ziga oladi.

«Bahor» sarlavhasi: logotip va menyu chapda, bron tugmasi o'ng chetda. Uchalasi bitta konteynerning bolalari:

html
<style>
  :root {
    --rang-asosiy: #2f6b3a;
  }
  header {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 8px;
    border-bottom: 2px solid var(--rang-asosiy);
  }
  header > p {
    margin: 0;
    font-weight: bold;
  }
  .bron-havola {
    margin-left: auto;
    padding: 4px 12px;
    color: #fff;
    background-color: var(--rang-asosiy);
    border-radius: 999px;
  }
</style>
<header>
  <p>Choyxona «Bahor»</p>
  <a href="menyu/">Menyu</a>
  <a href="aloqa/">Aloqa</a>
  <a class="bron-havola" href="bron/">Stolni band qilish</a>
</header>

Nimaga qarang: bron tugmasi o'ng chetga yopishdi, qolganlari chapda qoldi. Tugmaning chap margin'i qatordagi butun bo'sh joyni "yutdi". Qo'shimcha o'rovchi div kerak bo'lmadi. auto margin yozilgan elementdan keyingi hamma elementlar ham u bilan birga o'ngga ketadi — ikki havolani o'ngga surmoqchi bo'lsangiz, auto ni ularning birinchisiga yozing.

4.2 margin-top: auto — karta pastiga

Ustunda (column) asosiy o'q vertikal — margin-top: auto elementni pastga itaradi. Flexbox'ga kirish darsida kartalar stretch tufayli bir xil baland bo'lgan edi. Endi har kartaning ichini ham flex ustun qilamiz, narxni esa pastga itaramiz:

html
<style>
  :root {
    --rang-asosiy: #2f6b3a;
    --rang-urgu: #b4461a;
  }
  section {
    display: flex;
    gap: 12px;
  }
  .taom-karta {
    display: flex;
    flex-direction: column;
    flex: 1;
    padding: 0 12px;
    border: 2px solid var(--rang-asosiy);
    border-radius: 8px;
  }
  .narx {
    margin-top: auto;
    color: var(--rang-urgu);
    font-weight: bold;
  }
</style>
<section>
  <article class="taom-karta">
    <h3 class="taom-nomi">Osh</h3>
    <p class="narx">35 000 so'm</p>
  </article>
  <article class="taom-karta">
    <h3 class="taom-nomi">Lag'mon</h3>
    <p>Qo'lda cho'zilgan xamir, mol go'shti, bulg'or qalampiri
    va maxsus ziravorlar.</p>
    <p class="narx">28 000 so'm</p>
  </article>
  <article class="taom-karta">
    <h3 class="taom-nomi">Manti</h3>
    <p>Bug'da pishgan.</p>
    <p class="narx">30 000 so'm</p>
  </article>
</section>

Nimaga qarang: uchala kartada narxlar bitta chiziqda — kartalarning pastida. Osh kartasida tavsif yo'q, lekin narx baribir pastda. Bu auto margin ikki qavatli flex'da: tashqi qator kartalarni bir xil baland qildi, ichki ustun esa narxni o'sha bo'yning oxiriga itardi.

Mana Viewport birliklari darsidagi va'da: "kontentni blok pastiga joylash". Butun ekran bo'yli blokning pastiga tugma qo'yish ham xuddi shunday — blok column, tugma margin-top: auto.

4.3 auto margin justify-content dan kuchli

Bo'sh joy avval auto margin'larga beriladi. Ular hammasini olib qo'yadi — justify-content ga taqsimlash uchun hech narsa qolmaydi. Bitta elementda margin: auto bo'lsa, u ikkala o'qda ham o'rtaga tushadi — markazlashning yana bir yo'li. Uni keyingi darsda boshqa usullar bilan solishtiramiz.

Tekshirib ko'ring: Konteynerda justify-content: center, uchinchi elementda margin-left: auto. Birinchi ikki element qayerda turadi?

Javob

Chap chetda. Bo'sh joyning hammasini uchinchi elementning auto margin'i oldi. justify-content: center ga taqsimlash uchun joy qolmadi, shuning uchun u ishlamaydi. Birinchi ikkitasi boshda, uchinchisi o'ng chetda.

5. min-width: 0 — flex'ning mashhur tuzog'i

5.1 Nega flex element qisqarmaydi

O'tgan darsda ko'rdik: flex elementning min-width i sukut bo'yicha 0 emas, auto. Flex elementda auto — "mazmunim eng kamida qancha joy talab qilsa, shuncha" (min-content). Uzun so'z, URL yoki white-space: nowrap li matn bo'lsa, bu minimum katta bo'ladi va element qisqarmaydi.

Brauzer buni ataylab qiladi: aks holda matn ustma-ust tushib, o'qib bo'lmay qolardi. Lekin ba'zan bizga aynan qisqarish kerak — matnni "…" bilan kesish yoki ichida skroll qilish uchun.

5.2 Flex ichida "…"

Overflow darsidagi uch shartni eslang: bir qator (white-space: nowrap), kesish (overflow: hidden), cheklangan en — keyin text-overflow: ellipsis. Flex ichida "cheklangan en" shartini aynan kontent minimumi buzadi.

Bron ro'yxatidagi qator: chapda mehmon ismi (uzun bo'lishi mumkin), o'ngda vaqt. Ism ichki p da, "…" bilan kesilishi kerak:

html
<style>
  :root {
    --rang-asosiy: #2f6b3a;
  }
  li {
    display: flex;
    gap: 8px;
    width: 260px;
    margin-bottom: 8px;
    padding: 4px 8px;
    outline: 2px solid var(--rang-asosiy);
  }
  li > div {
    flex: 1;
  }
  li > div p {
    margin: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  li > b {
    flex: none;
  }
  li + li > div {
    min-width: 0;
  }
</style>
<ul>
  <li><div><p>❌ Rustam aka, oila bilan — 8 kishi</p></div>
    <b>19:00</b></li>
  <li><div><p>✅ Rustam aka, oila bilan — 8 kishi</p></div>
    <b>19:00</b></li>
</ul>

Nimaga qarang: birinchi qatorda "…" yo'q — vaqt ramkadan o'ngga chiqib ketdi, ism esa to'liq ko'rinib turibdi. Ikkinchi qatorda ism "…" bilan kesildi, vaqt joyida. Farq bitta qator: min-width: 0 — p ni o'raydigan flex elementga (div ga).

Nega p ning o'zi kesmadi? p da uchala shart bor, lekin uning eni otasidan — div dan keladi. div esa flex element. Uning kontent minimumi — ichidagi bir qatorlik matnning to'liq eni. div shuncha keng bo'lib qoldi, p ham u bilan birga — kesadigan joy yo'q. Chrome'da o'lchadik: birinchi qatorda div 236 piksel bo'ldi — ismning to'liq eni. Ramka ichida esa unga 214.67 piksel joy bor edi (260 − 8 gap − 37.33 vaqt).

5.3 overflow bilan bog'liqlik

Qiziq detal: agar "…" kesiladigan element flex elementning o'zi bo'lsa, min-width: 0 shart emas. Sababi: overflow qiymati visible bo'lmagan flex elementning kontent minimumi avtomatik 0 bo'ladi. overflow: hidden ning o'zi "men qisqarishga tayyorman, ortiqchasini kesaman" degani. Chrome'da tekshirdik: span ning o'zi flex element bo'lib, uchala shart unda bo'lganda "…" min-width siz chiqdi.

Qoida oddiy:

  • Kesiladigan matn flex elementning o'zida — overflow: hidden yetarli.
  • Matn flex element ichidagi bolada — flex elementga min-width: 0.

Ikkinchi holat amalda ko'proq uchraydi: karta ichidagi sarlavha, jadval qatoridagi ism, chat ro'yxatidagi oxirgi xabar. Shubha bo'lsa — min-width: 0 yozing, zarari yo'q.

5.4 min-height: 0 — ustunda ichki skroll

Ustunda (column) xuddi shu muammo bo'y bo'yicha: flex elementning min-height i auto. Oshpaz Rustam akaning ekranidagi buyurtmalar paneli: bo'yi qat'iy, tepada sarlavha, pastda buyurtmalar ro'yxati skroll qilinishi kerak:

html
<style>
  :root {
    --rang-asosiy: #2f6b3a;
  }
  article {
    display: flex;
    flex-direction: column;
    width: 220px;
    height: 180px;
    margin-bottom: 12px;
    border: 2px solid var(--rang-asosiy);
  }
  article section {
    flex: 1;
    display: flex;
    flex-direction: column;
  }
  article ul {
    flex: 1;
    overflow-y: auto;
    margin: 0;
  }
  article + article section {
    min-height: 0;
  }
  h3, h4 {
    margin: 0;
    padding: 4px 8px;
  }
</style>
<article>
  <h3>❌ Buyurtmalar</h3>
  <section>
    <h4>Stol 5</h4>
    <ul><li>Osh</li><li>Lag'mon</li><li>Manti</li><li>Somsa</li>
    <li>Ko'k choy</li><li>Non</li><li>Salat</li><li>Kabob</li></ul>
  </section>
</article>
<article>
  <h3>✅ Buyurtmalar</h3>
  <section>
    <h4>Stol 5</h4>
    <ul><li>Osh</li><li>Lag'mon</li><li>Manti</li><li>Somsa</li>
    <li>Ko'k choy</li><li>Non</li><li>Salat</li><li>Kabob</li></ul>
  </section>
</article>

Nimaga qarang: birinchi panelda ro'yxat ramkadan pastga chiqib ketdi va skroll yo'q. Ikkinchisida ro'yxat ramka ichida, uni aylantirish mumkin. Ro'yxatning o'zida overflow-y: auto bor edi. Muammo uning otasida: section flex element, uning kontent minimumi butun ro'yxat bo'yi. Unga min-height: 0 berilgach, u panelga sig'di va ul skroll konteynerga aylandi (Overflow).

Tekshirib ko'ring: Flex qatorda span bor, unga white-space: nowrap; overflow: hidden; text-overflow: ellipsis; yozilgan va span ning o'zi flex element. min-width: 0 kerakmi?

Javob

Kerak emas. span ning o'zi flex element va uning overflow i hidden — bunday elementning kontent minimumi avtomatik 0. min-width: 0 faqat "…" kesiladigan matn flex elementning ichidagi bolada bo'lsa kerak.

6. Ko'p uchraydigan xatolar

6.1 justify-self bilan bitta elementni surish

Flex'da justify-self ishlamaydi. Tuzatish: margin-left: auto (o'ngga) yoki margin-right: auto (qolganlarini o'ngga).

6.2 order bilan ma'noli tartibni o'zgartirish

Ko'z bilan fokus tartibi ajraladi. Tuzatish: HTML tartibini o'zgartiring. order — faqat tartibi ma'noga ta'sir qilmaydigan bezak uchun.

6.3 "…" chiqmayapti, element konteynerdan chiqib ketyapti

Matn ichki bolada, flex elementning kontent minimumi katta. Tuzatish: flex elementga min-width: 0.

6.4 Ichki skroll ishlamayapti, panel cho'zilib ketdi

Ustundagi flex elementning min-height: auto. Tuzatish: skroll qiladigan element bilan panel orasidagi har flex elementga min-height: 0.

6.5 auto margin + justify-content — "center ishlamayapti"

auto margin bo'sh joyning hammasini oldi. Tuzatish: ikkalasidan birini tanlang.

7. Mashqlar

1-mashq (oson): Belgi pastda

«Bahor» taom kartasi — display: flex; align-items: flex-start;. Ichida rasm, tavsif va "Achchiq" belgisi. Belgi kartaning pastki chetida tursin, qolganlari tepada.

Yechim
html
<style>
  :root {
    --rang-asosiy: #2f6b3a;
    --rang-urgu: #b4461a;
  }
  .taom-karta {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    max-width: 24rem;
    padding: 8px;
    border: 2px solid var(--rang-asosiy);
  }
  .taom-karta svg {
    flex: none;
  }
  .taom-karta p {
    margin: 0;
  }
  .taom-karta strong {
    align-self: flex-end;
    color: var(--rang-urgu);
  }
</style>
<article class="taom-karta achchiq">
  <svg width="48" height="48" viewBox="0 0 48 48" aria-hidden="true">
    <circle cx="24" cy="24" r="22" fill="#b4461a"/></svg>
  <p><b class="taom-nomi">Lag'mon</b> — qo'lda cho'zilgan
  xamir, mol go'shti va achchiq qalampir. Achchiqligini
  o'zingiz tanlaysiz.</p>
  <strong>Achchiq</strong>
</article>

align-self: flex-end — faqat belgi ko'ndalang o'q oxiriga (pastga) tushdi. Konteynerning flex-start i qolgan ikkitasi uchun ishlayveradi.

2-mashq (o'rta): Bron havolasi karta pastida

Uchta kartadan iborat qator: har birida sarlavha, tavsif (uzunligi har xil) va "Stolni band qilish" havolasi (bron-havola). Havolalar uchala kartada ham pastda, bir chiziqda tursin, kartaning butun eniga emas — o'z matni enida.

Ishora: kartaning ichi — ustun. Havolani pastga itarish — «margin-top: auto — karta pastiga» bo'limidagi usul. Ustunda havola butun enga cho'zilmasligi uchun — align-self ning qaysi qiymati (Flex'da tekislash darsidagi stretch ni eslang)?

Yechim
html
<style>
  :root {
    --rang-asosiy: #2f6b3a;
  }
  section {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
  }
  .taom-karta {
    display: flex;
    flex-direction: column;
    flex: 1 1 12rem;
    padding: 0 12px 12px;
    border: 2px solid var(--rang-asosiy);
    border-radius: 8px;
  }
  .bron-havola {
    margin-top: auto;
    align-self: flex-start;
    padding: 4px 12px;
    color: #fff;
    background-color: var(--rang-asosiy);
    border-radius: 999px;
  }
</style>
<section>
  <article class="taom-karta">
    <h3>Tushlik</h3>
    <p>12:00–15:00.</p>
    <a class="bron-havola" href="bron/">Stolni band qilish</a>
  </article>
  <article class="taom-karta">
    <h3>Kechki osh</h3>
    <p>18:00 dan. Katta qozon, oila va do'stlar uchun alohida
    joy bor.</p>
    <a class="bron-havola" href="bron/">Stolni band qilish</a>
  </article>
  <article class="taom-karta">
    <h3>To'y va ma'raka</h3>
    <p>Oldindan kelishiladi.</p>
    <a class="bron-havola" href="bron/">Stolni band qilish</a>
  </article>
</section>
  • margin-top: auto — havolani ustunning pastiga itardi.
  • align-self: flex-start — ustunda ko'ndalang o'q gorizontal. Sukut stretch havolani butun enga cho'zardi, flex-start uni o'z matni enida, chapda qoldirdi.
  • Telefonda kartalar ustma-ust tushadi — har biri o'z qatorida, havola baribir pastda.

Uchta bir xil matnli havola haqida: ekran o'quvchi havolalar ro'yxatida uchta "Stolni band qilish" ni eshitadi. Ular bir joyga olib borgani uchun bu ruxsat etiladi, lekin har xil joyga olib borsa, matni ham farq qilsin (Kontent accessibility'si).

3-mashq (qiyin): Uch tuzoq, bitta kod

Jasur aka uchun bron ro'yxati sahifasi. Stajyor har qatorga shunday CSS yozdi:

css
li {
  display: flex;
  justify-content: space-between;
}
li p {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
li > a:has(time) {
  justify-self: end;
}
li > a[href$="/tahrir"] {
  order: -1;
}

HTML (har qator):

html
<li>
  <div><p>Mehmon ismi va izohi</p></div>
  <a href="bron/12/"><time datetime="19:00">19:00</time></a>
  <a href="bron/12/tahrir">Tahrirlash</a>
</li>

Shikoyatlar: (a) uzun ism "…" bilan kesilmayapti; (b) stajyor justify-self bilan vaqtni o'ng chetga surmoqchi edi; (c) Bobur Tab bosganda fokus avval vaqtga, keyin chap chetdagi "Tahrirlash" ga sakraydi.

Har birining sababini ayting va tuzating. Selektorlar — Atribut selektorlari ($= — "shu bilan tugaydi") va Mantiqiy pseudo-klasslar (:has() — "ichida time bor havola").

Yechim
  • (a) "…" kesiladigan p flex elementning ichida — flex element esa div. Uning kontent minimumi ismning to'liq eni. Tuzatish: li > div { min-width: 0; } («Flex ichida "…"» bo'limidagi holat).
  • (b) Flex'da justify-self yo'q. Tuzatish: li > a:has(time) { margin-left: auto; } — vaqt va undan keyingi hamma narsa o'ngga.
  • (c) order: -1 "Tahrirlash" ni ekranda boshiga qo'ydi, HTML'da esa u oxirgi. Tuzatish: order ni olib tashlang va havolani HTML'da birinchi yozing.
css
li {
  display: flex;
  align-items: baseline;
  gap: 8px;
}
li > div {
  min-width: 0;
}
li p {
  margin: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
li > a:has(time) {
  margin-left: auto;
}

HTML — "Tahrirlash" birinchi:

html
<li>
  <a href="bron/12/tahrir">Tahrirlash</a>
  <div><p>Mehmon ismi va izohi</p></div>
  <a href="bron/12/"><time datetime="19:00">19:00</time></a>
</li>

Endi ko'z ham, Tab ham bir tartibda yuradi: Tahrirlash → vaqt (ism havola emas, unga fokus tushmaydi). justify-content: space-between olib tashlandi — auto margin va gap yetarli. Selektor HTML tartibiga emas, ma'noga (href va time) bog'langan — shuning uchun tartib o'zgarganda ham buzilmadi.

4-mashq: Portfolio qadami — non yo'li va tartib auditi

«Bahor» loyiha sahifangizdagi non yo'li (nav[aria-label="Non yo'li"]) Ro'yxatlar stili darsidan beri bir qatorda: bandlar display: inline, orasida o'qilmaydigan /. Lekin uzun nom tor ekranda keyingi qatorga o'raladi.

  1. Uni flex qatorga aylantiring: inline o'rniga flex, / ajratgich qolsin va ekran o'quvchiga o'qilmasin.
  2. Qator o'ralmasin. Oxirgi element (joriy sahifa) sig'masa — "…" bilan kesilsin, qolgan ikki havola esa qisqarmasin.
  3. Tekshirish uchun loyiha nomini vaqtincha uzaytiring ("Choyxona «Bahor» sayti: menyu, bron formasi va 404") va 360 piksel enda oching.
  4. Tartib auditi: portfolio'ning hamma sahifasini faqat Tab bilan o'ting. Fokus ekrandagi tartibda yuryaptimi? asosiy.css da order, row-reverse yoki column-reverse bormi?

Ishora: 1-band — ajratgich o'sha darsdagi li + li::before, "o'qilmaydigan" content — Pseudo-elementlar darsidagi alternativ matn (/ ""); oraliqni endi gap beradi. 2-band — joriy sahifa havolasini flex element qilish uchun oxirgi li ni ham flex qiling. Havola overflow: hidden li flex element bo'lsa, unga min-width: 0 kerakmi («overflow bilan bog'liqlik» bo'limi)? Oxirgi li ning o'ziga-chi?

Yechim
css
/* Non yo'li: bir qator, oxirgisi sig'masa "…" */
nav[aria-label="Non yo'li"] ol {
  display: flex;
  gap: 0.5rem;
}

nav[aria-label="Non yo'li"] li {
  display: flex;
  flex: none;
}

nav[aria-label="Non yo'li"] li + li::before {
  content: "/" / "";
  margin-inline-end: 0.5rem;
  color: var(--rang-ikkinchi);
}

nav[aria-label="Non yo'li"] li:last-child {
  flex-shrink: 1;
  min-width: 0;
}

nav[aria-label="Non yo'li"] [aria-current="page"] {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

Telefon enida, uzun nom bilan:

html
<style>
  :root {
    --rang-matn: #1f2a24;
    --rang-fon: #f7faf8;
    --rang-asosiy: #1f6f4a;
    --rang-ikkinchi: #5b6660;
  }
  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }
  body {
    font-family: system-ui, sans-serif;
    color: var(--rang-matn);
    background-color: var(--rang-fon);
    line-height: 1.5;
  }
  main {
    width: min(100% - 2rem, 70ch);
    margin-inline: auto;
  }
  a {
    color: var(--rang-asosiy);
  }
  nav[aria-label="Non yo'li"] {
    font-size: 0.875rem;
  }
  nav[aria-label="Non yo'li"] ol {
    display: flex;
    gap: 0.5rem;
    list-style: none;
    padding-left: 0;
  }
  nav[aria-label="Non yo'li"] li {
    display: flex;
    flex: none;
  }
  nav[aria-label="Non yo'li"] li + li::before {
    content: "/" / "";
    margin-inline-end: 0.5rem;
    color: var(--rang-ikkinchi);
  }
  nav[aria-label="Non yo'li"] li:last-child {
    flex-shrink: 1;
    min-width: 0;
  }
  nav[aria-label="Non yo'li"] [aria-current="page"] {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
</style>
<main id="asosiy">
  <nav aria-label="Non yo'li">
    <ol>
      <li><a href="../../">Bosh sahifa</a></li>
      <li><a href="../">Loyihalar</a></li>
      <li>
        <a href="./" aria-current="page">Choyxona «Bahor» sayti:
        menyu, bron formasi va 404</a>
      </li>
    </ol>
  </nav>
</main>

Nozik joylar:

  • Havola (aria-current) — oxirgi li ning flex elementi, unda overflow: hidden bor. «overflow bilan bog'liqlik» qoidasi: unga min-width: 0 shart emas. Lekin li ning o'zi ol ning flex elementi va unda overflow yo'q — unga min-width: 0 kerak. Ikki qavat, ikki qaror.
  • Ro'yxatlar stili darsidagi li { display: inline; } va ajratgichdagi margin-inline: 0.5em shu qoidalarga almashdi — eskilarini o'chiring. Belgi va chekinishni esa o'sha darsdagi nav ul, nav ol qoidasi olib tashlashda davom etadi.
  • flex: none — "Bosh sahifa" va "Loyihalar" qisqarmaydi. Oxirgi li ga flex-shrink: 1 qaytarildi — yetishmovchilikni u yolg'iz ko'taradi.
  • Chrome'da 360 piksel enda o'lchadik: joriy sahifa havolasi 143.86 piksel, uning to'liq matni esa 326 piksel. Sahifada gorizontal skroll yo'q.
  • content: "/" / "" — ekranda "/" chiziladi, ekran o'quvchi uchun alternativ matn bo'sh. Malika "Bosh sahifa, Loyihalar, Choyxona…" ni eshitadi — "slesh" siz. Kesilgan matn ham ekran o'quvchi uchun to'liq qoladi (Overflow). Joriy sahifaning to'liq nomi esa tepadagi h1 da bor — ko'radigan odam ham hech narsa yo'qotmaydi.
  • 4-band: CSS nima darsidan beri biz order va teskari yo'nalish ishlatmadik — fokus doim HTML tartibida va ekrandagi tartibda yuradi. Tekshiruvni har yangi layout darsidan keyin takrorlang.

Oxirida loyiha nomini asl holiga qaytaring.

8. Real ishda

  • margin-left: auto — navbar'larda "Kirish" yoki "Profil" tugmasini o'ngga surishning eng keng tarqalgan yo'li. Ortiqcha o'rovchi div kerak emas.
  • min-width: 0 — chat ilovalari (Telegram'dagi suhbatlar ro'yxati: ism va oxirgi xabar "…" bilan), jadval qatorlari, fayl nomlari. Bu tuzoqni bilmagan dasturchi soatlab overflow: hidden ni har joyga yozib chiqadi.
  • order va a11y — accessibility auditlarida (Lighthouse emas, qo'lda Tab testi) tez-tez topiladigan xato. CSS'da accessibility darsida auditni to'liq o'rganamiz.
  • Intervyuda so'raladi: "Flex elementni qanday qilib o'ng chetga surasiz?", "order ning kamchiligi nima?", "Nega text-overflow: ellipsis flex ichida ishlamayapti?".

Xulosa

  • align-self — bitta element uchun align-items; flex'da justify-self yo'q.
  • order faqat ko'rinishni o'zgartiradi; Tab va ekran o'quvchi HTML tartibida yuradi — ma'noli tartib HTML'da bo'lsin.
  • reading-flow Baseline emas (faqat Chrome va Edge 137+) — zaxira: to'g'ri HTML tartibi.
  • auto margin bo'sh joyni birinchi bo'lib oladi: margin-left: auto — o'ngga, ustunda margin-top: auto — pastga.
  • Flex element sukut bo'yicha mazmunidan torroq qisqarmaydi; ichki bolada "…" yoki skroll kerak bo'lsa — min-width: 0 yoki min-height: 0.
  • overflow si visible bo'lmagan flex elementning kontent minimumi o'zi 0.

Keyingi dars: Flex naqshlari va markazlashning barcha usullari — navbar, sticky footer, maydon va tugma guruhi va "div'ni markazga qo'yish"ning har bir yo'li.

Manbalar

  • MDN: "align-self", "order", "Ordering flex items", "min-width" (auto qiymati), "reading-flow" — developer.mozilla.org
  • W3C: "CSS Flexible Box Layout Module Level 1", 4.5 "Automatic Minimum Size of Flex Items", 8.1 "Aligning with auto margins" — w3.org/TR/css-flexbox-1
  • W3C WAI: "Understanding SC 1.3.2: Meaningful Sequence", "Understanding SC 2.4.3: Focus Order" — w3.org/WAI/WCAG22/Understanding
  • web-features (Baseline ma'lumotlari): "reading-flow" — github.com/web-platform-dx/web-features
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
CSS align-self, order va auto margin: flex tuzoqlari va min-width: 0 — IlmHamroh