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

CSS subgrid: kartalar ichidagi sarlavha va narxni bir chiziqqa tekislash

Qisqacha: subgrid — ichki grid o'z qatorlarini chizmasdan, ota to'rning qatorlari (yoki ustunlari)ni ishlatishi. Kartaga grid-row: span 4 va grid-template-rows: subgrid yozsangiz, karta ota to'rning to'rtta qatorini oladi — qo'shni kartalardagi sarlavha, tavsif va tugmalar bir chiziqda turadi. subgrid 2026-yil martdan beri keng qo'llab-quvvatlanadi (Baseline).

Bu darsda

  • Qo'shni kartalardagi elementlar nega bir chiziqda turmasligini tushuntirasiz.
  • grid-row: span N va grid-template-rows: subgrid bilan kartalar ichini ota to'rga ulaysiz.
  • gap va nomli chiziqlar subgrid'ga qanday meros o'tishini bilasiz.
  • Forma yorliqlari va maydonlarini grid-template-columns: subgrid bilan tekislaysiz.
  • span soni xato bo'lganda nima bo'lishini ko'rib, tuzatasiz.

Oldin bilishingiz kerak: Grid'da tekislash, Joylashtirish: chiziqlar va span, repeat() va minmax(), align-self va auto margin.

1. Nega bu kerak?

«Bahor» menyusining yangi sahifasi: taomlar kartalar to'rida. Har kartada to'rt narsa — nom, tavsif, narx va "Stol band qilish" havolasi. Kartalar teng balandlikda — Grid'da tekislash darsidagi stretch shuni qildi. Lekin ichiga qarang:

html
<style>
  body { font-family: system-ui, sans-serif; }
  section {
    display: grid;
    grid-template-columns:
      repeat(auto-fit, minmax(min(12rem, 100%), 1fr));
    gap: 1rem;
    max-width: 42rem;
  }
  .taom-karta {
    display: grid;
    align-content: start;
    gap: 0.5rem;
    padding: 1rem;
    border: 2px solid #2f6b3a;
    border-radius: 0.5rem;
  }
  .taom-karta > * { margin: 0; }
  .narx { color: #b4461a; font-weight: bold; }
  .bron-havola {
    justify-self: start;
    padding: 0.5rem 0.75rem;
    border-radius: 0.5rem;
    background-color: #2f6b3a;
    color: #fff;
    text-decoration: none;
  }
</style>
<section>
  <article class="taom-karta">
    <h3 class="taom-nomi">Osh</h3>
    <p>Toshkentcha to'y oshi, bedana tuxumi bilan.</p>
    <p class="narx">35 000 so'm</p>
    <a class="bron-havola" href="bron/">Stol band qilish</a>
  </article>
  <article class="taom-karta">
    <h3 class="taom-nomi">Tandirda pishgan qo'y go'shti</h3>
    <p>Uch soat tandirda.</p>
    <p class="narx">60 000 so'm</p>
    <a class="bron-havola" href="bron/">Stol band qilish</a>
  </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 ko'katlar bilan qovurilgan sabzavot.</p>
    <p class="narx">28 000 so'm</p>
    <a class="bron-havola" href="bron/">Stol band qilish</a>
  </article>
</section>

Nimaga qarang: uchta narx uch xil balandlikda, yashil tugmalar ham "zinapoya" bo'lib turibdi. O'rtadagi kartada nom ikki qatorga tushgan, o'ngdagisida tavsif uzun. Har karta o'z ichini o'zicha joylaydi — qo'shnisida nima borligini bilmaydi.

Ko'z esa kartalarni qatorlab solishtiradi: "osh — 35 000, lag'mon — 28 000". Narxlar bir chiziqda bo'lsa, solishtirish oson. Do'kon javonini tasavvur qiling: hamma mahsulotning narx yorlig'i javonning bitta chetiga yopishtirilgan. Yorliqlar har xil balandlikda bo'lsa, xaridor narxlarni qidirib charchaydi.

2. Eski yechimlar va ularning chegarasi

2.1 Auto margin — faqat pastki qism

align-self va auto margin darsidagi hiylani eslang: kartani ustunli flex qilib, tugmaga margin-top: auto beramiz.

css
.taom-karta {
  display: flex;
  flex-direction: column;
}

.bron-havola {
  margin-top: auto; /* bo'sh joyni yutib, pastga tushadi */
}

Tugmalar endi kartaning pastida, bir chiziqda. Lekin nom va tavsif o'z joyida qoldi. Narxlar ham avvalgidek har xil balandlikda. Bu hiyla faqat bitta elementni pastga itaradi.

2.2 Qat'iy balandlik — mo'rt

Boshqa "yechim" — sarlavhaga min-height: 3em, tavsifga min-height: 5em. Bugun ishlaydi. Ertaga Rustam aka uzunroq tavsif yozadi yoki foydalanuvchi shriftni kattalashtiradi — matn qutidan toshadi. Kontent o'zgarganda buziladigan kod — mo'rt kod.

2.3 Asl muammo

Muammoning ildizi bitta: har karta o'zining to'ri. Ota to'rda kartalar qatori bor, lekin karta ichidagi qatorlar ota to'rga bog'lanmagan. Birinchi kartaning "nom qatori" ikkinchi kartaning "nom qatori" bo'yini bilmaydi.

Bizga shunday narsa kerak: "karta ichidagi qatorlar o'zinikini emas, ota to'rning qatorlarini ishlatsin". Shunda hamma kartadagi nom bitta qatorda turadi va o'sha qatorning balandligi eng uzun nomga teng bo'ladi. subgrid aynan shu.

Tekshirib ko'ring: Nega stretch kartalarni teng balandlikka keltirdi-yu, ichidagi narxlarni bir chiziqqa keltira olmadi?

Javob

stretch faqat ota to'r katagi ichida ishlaydi — kartaning o'zini katak bo'yicha cho'zadi. Narx esa kartaning ichki to'rida turibdi. Ichki to'rning qatorlari qo'shni kartaning ichki to'ri bilan bog'lanmagan. Har biri o'z kontentiga qarab qator balandligini hisoblaydi.

3. subgrid bilan kartalar

3.1 Ikki qator kod

html
<style>
  body { font-family: system-ui, sans-serif; }
  section {
    display: grid;
    grid-template-columns:
      repeat(auto-fit, minmax(min(12rem, 100%), 1fr));
    gap: 1rem;
    max-width: 42rem;
  }
  .taom-karta {
    display: grid;
    grid-row: span 4;
    grid-template-rows: subgrid;
    row-gap: 0.5rem;
    padding: 1rem;
    border: 2px solid #2f6b3a;
    border-radius: 0.5rem;
  }
  .taom-karta > * { margin: 0; }
  .narx { color: #b4461a; font-weight: bold; }
  .bron-havola {
    justify-self: start;
    padding: 0.5rem 0.75rem;
    border-radius: 0.5rem;
    background-color: #2f6b3a;
    color: #fff;
    text-decoration: none;
  }
</style>
<section>
  <article class="taom-karta">
    <h3 class="taom-nomi">Osh</h3>
    <p>Toshkentcha to'y oshi, bedana tuxumi bilan.</p>
    <p class="narx">35 000 so'm</p>
    <a class="bron-havola" href="bron/">Stol band qilish</a>
  </article>
  <article class="taom-karta">
    <h3 class="taom-nomi">Tandirda pishgan qo'y go'shti</h3>
    <p>Uch soat tandirda.</p>
    <p class="narx">60 000 so'm</p>
    <a class="bron-havola" href="bron/">Stol band qilish</a>
  </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 ko'katlar bilan qovurilgan sabzavot.</p>
    <p class="narx">28 000 so'm</p>
    <a class="bron-havola" href="bron/">Stol band qilish</a>
  </article>
</section>

Nimaga qarang: uchala nom bitta qatorda, tavsiflar bitta qatorda, narxlar va tugmalar ham bir chiziqda. "Osh" nomi ostida bo'sh joy qoldi — uning qatori qo'shni kartadagi ikki qatorli nomga moslashdi. Chrome'da o'lchadik: uchala narxning yuqori cheti sahifa tepasidan bir xil — 197 piksel. 360 tugmasini bosing: telefonda kartalar ustma-ust tushadi va har biri o'z to'rtta qatorini oladi.

Oldingi natijadan farq — kartadagi uch qator:

css
.taom-karta {
  display: grid;                /* 1. karta — grid */
  grid-row: span 4;             /* 2. ota to'rda 4 qator egallaydi */
  grid-template-rows: subgrid;  /* 3. o'sha qatorlarni ishlatadi */
}

align-content: start va gap: 0.5rem o'rniga esa row-gap: 0.5rem yozildi — nega, pastda, «gap merosi» bo'limida ko'ramiz.

3.2 Qadamma-qadam: nima bo'ldi

  1. display: grid — karta grid konteyner bo'ladi. Subgrid ham grid, shuning uchun bu qator majburiy.
  2. grid-row: span 4 — Joylashtirish darsidagi span: karta ota to'rda ketma-ket to'rtta qatorni egallaydi. Ota to'rda grid-template-rows yozilmagan. Qatorlar auto o'lchamli implicit qatorlar bo'lib o'zi yaratiladi.
  3. grid-template-rows: subgrid — "o'z qatorlaringni chizma, ota to'rdan olgan to'rtta qatoringni ishlat". Karta ichidagi to'rt element shu to'rt qatorga birma-bir tushadi.
flowchart TD
  O["Ota to'r: section"] --> Q1["1-qator: nomlar"]
  O --> Q2["2-qator: tavsiflar"]
  O --> Q3["3-qator: narxlar"]
  O --> Q4["4-qator: tugmalar"]
  Q1 --> B["Balandlik = eng uzun nom"]
  Q2 --> C["Balandlik = eng uzun tavsif"]

Nimaga qarang: qatorlar endi kartaga emas, ota to'rga tegishli. Ota to'r har qator balandligini hamma kartalardagi elementlarga qarab hisoblaydi. auto qator eng baland kontentga teng bo'ladi. Shuning uchun uzun nom birinchi qatorni hamma kartalar uchun kattalashtirdi.

Maslahat: Karta padding va border i birinchi va oxirgi qatorga qo'shiladi. Hamma kartada ular bir xil bo'lgani uchun tekislash buzilmaydi. Kartalarga har xil padding bersangiz — chiziqlar siljiydi.

3.3 Subgrid bitta o'qda

Kartada faqat grid-template-rows: subgrid yozdik. Ustunlar-chi? Karta ota to'rda bitta ustunda turibdi, ichida esa o'z ustunlari (bittagina, sukut bo'yicha) bor. Subgrid har o'q uchun alohida yoqiladi:

Yozuv Qatorlar Ustunlar
grid-template-rows: subgrid Otadan O'ziniki
grid-template-columns: subgrid O'ziniki Otadan
grid-template: subgrid / subgrid Otadan Otadan

Ustunli subgrid'ni pastda, forma misolida ko'ramiz.

Tekshirib ko'ring: Kartada besh element bo'lishi kerak: rasm, nom, tavsif, narx, tugma. Kodda nima o'zgaradi?

Javob

grid-row: span 5. Karta ota to'rdan beshta qator olishi kerak — har elementga bittadan. grid-template-rows: subgrid o'zgarmaydi: u qatorlar sonini span dan oladi.

4. gap merosi

4.1 Sukutda — otaning gap i

Subgrid ota to'rning qatorlari bilan birga ularning orasidagi masofani ham meros oladi. Ota section da gap: 1rem. Agar kartaga hech narsa yozmasak, nom va tavsif orasi ham 1rem bo'ladi — xuddi kartalar orasidagidek.

Ko'pincha bu keraksiz: karta ichidagi elementlar kartalar orasidagi masofadan zichroq tursa, ko'z ularni bitta guruh deb o'qiydi. Shuning uchun kartada row-gap: 0.5rem bor.

4.2 O'z gap ingizni bering

Subgrid'da gap ni qayta yozish mumkin. U faqat karta ichidagi qatorlar orasiga ta'sir qiladi:

css
.taom-karta {
  grid-template-rows: subgrid;
  row-gap: 0.5rem; /* karta ichida — 0.5rem */
}

Chrome'da telefon enida (360 piksel) o'lchadik: nom va tavsif orasi 8 piksel. Ustma-ust tushgan ikki karta orasi esa 16 piksel qoldi — u ota section ning gap i. Karta o'z ichini boshqaradi, kartalar orasini esa ota boshqaradi.

gap o'rniga row-gap yozganimiz sababi — faqat keraklisini o'zgartirish. Karta ichida ustunlar oralig'i yo'q, lekin kelajakda bu qoida ustunli subgrid bilan birga ishlatilsa, ota ustunlar orasini tasodifan buzmaydi.

Tekshirib ko'ring: Ota to'rda gap: 2rem, kartada row-gap: 0. Karta ichidagi nom va tavsif orasi qancha? Ikki karta qatori orasi-chi?

Javob

Karta ichida — 0: subgrid o'z row-gap ini berdi. Kartalar orasi — 2rem: bu ota to'rning qatorlari orasidagi masofa, uni kartaning qoidasi o'zgartirmaydi.

5. Forma: yorliq va maydonlarni tekislash

5.1 Muammo

«Bahor»ning bron formasi (Qulay va accessible forma darsidagi). "Tashrif" guruhida uchta maydon. Har yorliq va maydon jufti div ichida, maydon yo'riqnomasi — span. Keng ekranda yorliq chapda, maydon o'ngda tursin.

Grid'ga kirish darsida aytganimizdek, label bu yerda to'rning nevarasi — fieldset ni grid qilsak, uning elementlari div lar bo'ladi, label emas. Shuning uchun har div ni alohida grid qilamiz:

html
<style>
  fieldset {
    display: grid;
    gap: 0.75rem;
    max-width: 30rem;
    font-family: system-ui, sans-serif;
  }
  fieldset div {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 0.25rem 1rem;
  }
</style>
<form action="https://example.com/bron" method="post">
  <fieldset>
    <legend>Tashrif</legend>
    <div>
      <label for="sana">Sana</label>
      <input id="sana" name="sana" type="date">
    </div>
    <div>
      <label for="vaqt">Vaqt</label>
      <select id="vaqt" name="vaqt">
        <option value="">Vaqtni tanlang</option>
        <option value="18:00">18:00</option>
      </select>
    </div>
    <div>
      <label for="odam">Mehmonlar soni</label>
      <input id="odam" name="odam" type="number" min="1" max="20">
    </div>
  </fieldset>
</form>

Nimaga qarang: maydonlar har xil joydan boshlanadi — "zinapoya". Har div o'z ustunlarini o'zi hisobladi: max-content "Vaqt" uchun kichik, "Mehmonlar soni" uchun katta. Qatorlar bir-birini bilmaydi — kartalardagi muammoning o'zi, faqat endi ustunlarda.

5.2 Yechim: ustunli subgrid

Ustunlarni fieldset chizadi, har div esa ularni meros oladi:

html
<style>
  fieldset {
    display: grid;
    grid-template-columns:
      [yorliq-start] max-content
      [yorliq-end maydon-start] 1fr [maydon-end];
    gap: 0.75rem 1rem;
    max-width: 30rem;
    font-family: system-ui, sans-serif;
  }
  fieldset div {
    display: grid;
    grid-column: 1 / -1;
    grid-template-columns: subgrid;
    row-gap: 0.25rem;
  }
  label { align-self: center; }
  div > :is(input, select) { grid-column: maydon; grid-row: 1; }
  div > span { grid-column: maydon; grid-row: 2; color: #5b6660; }
</style>
<form action="https://example.com/bron" method="post">
  <fieldset>
    <legend>Tashrif</legend>
    <div>
      <label for="sana">Sana</label>
      <span id="sana-yordam">Bron 30 kun oldindan ochiq.</span>
      <input id="sana" name="sana" type="date"
             aria-describedby="sana-yordam">
    </div>
    <div>
      <label for="vaqt">Vaqt</label>
      <select id="vaqt" name="vaqt">
        <option value="">Vaqtni tanlang</option>
        <option value="18:00">18:00</option>
      </select>
    </div>
    <div>
      <label for="odam">Mehmonlar soni</label>
      <input id="odam" name="odam" type="number" min="1" max="20">
    </div>
  </fieldset>
</form>

Nimaga qarang: hamma maydon bitta vertikal chiziqdan boshlanadi. Yorliqlar ustuni eng uzun yorliqqa ("Mehmonlar soni") teng. Sana ostidagi yo'riqnoma ham maydonlar ustunida. Chrome'da o'lchadik: uchala maydon va yo'riqnomaning chap cheti bir xil — 155 piksel, 800 enda ham, 360 enda ham.

Qatorma-qator:

  • fieldset — ikki ustun: yorliqlar uchun max-content, maydonlar uchun 1fr. Chiziqlarga nom berdik — ular haqida pastroqda.
  • fieldset div — grid-column: 1 / -1 bilan ikkala ustunni egallaydi. grid-template-columns: subgrid — o'sha ikki ustunni ichida ishlatadi.
  • label — birinchi bo'sh katakka, ya'ni chap ustunga o'z-o'zidan tushadi. align-self: center — yorliq maydonning o'rtasi baravarida (Grid'da tekislash).
  • Maydon (input yoki select) — grid-column: maydon va grid-row: 1 bilan o'ng ustunning birinchi qatoriga.
  • span — grid-row: 2 bilan maydon ostiga.

max-content ustun eng uzun yorliqni hisobga oladi, chunki hamma yorliq endi bitta ustunning elementi. Kartalardagi "eng uzun nom" qoidasi — ustunlarda.

Diqqat: HTML'da yo'riqnoma maydondan oldin turibdi (Qulay va accessible forma darsida shunday tanlagan edik). Ekranda esa u maydon ostida. Ekran o'quvchidagi Malika uni HTML tartibida eshitadi: yorliq, yo'riqnoma, maydon — bu to'g'ri. span fokus olmaydi, shuning uchun Bobur uchun Tab tartibi o'zgarmadi. Joylashtirish ko'rinishni o'zgartiradi, ma'no tartibini emas.

5.3 Nomli chiziqlar merosi

Joylashtirish darsida chiziqlarga nom berishni o'rgandik. Formada ikki nom bor: yorliq va maydon. Har biri -start va -end jufti. Bunday juftlik ichidagi joyni grid-column: maydon bilan to'g'ridan-to'g'ri chaqirish mumkin.

Subgrid ota to'rning chiziq nomlarini ham meros oladi. Maydon va span div ning ichida, div esa subgrid. maydon nomi div da e'lon qilinmagan — u fieldset dan keldi. Shuning uchun grid-column: maydon ishladi.

Subgrid o'ziga qo'shimcha nom ham qo'sha oladi. Nomlar subgrid so'zidan keyin, chiziqlar tartibida yoziladi:

css
fieldset div {
  grid-template-columns: subgrid [chap] [orta] [ong];
}

Endi div ichidagi uchta chiziq otadan kelgan nomlar bilan birga chap, orta va ong nomlariga ham ega. Bu faqat div ichida ishlaydi: ota to'r bu nomlarni ko'rmaydi. Oddiy loyihada ota nomlari yetarli.

5.4 display: contents bilan farqi

display darsida display: contents ni ko'rgansiz: element qutisi yo'qoladi, bolalari to'g'ridan-to'g'ri otaning grid elementiga aylanadi. Formada ham ishlaydi: fieldset div { display: contents; } — label va maydon fieldset ning ustunlariga tushadi.

Lekin div ning qutisi yo'qoladi: unga margin, border yoki fon berib bo'lmaydi. O'sha darsda aytilgan accessibility xavfi ham bor: ba'zi brauzerlarda bunday elementlarning ma'nosi ekran o'quvchidan yo'qolgan. Subgrid qutini saqlaydi va faqat ustunlarni ulaydi. Shuning uchun bugun subgrid — to'g'ri tanlov.

Tekshirib ko'ring: "Tashrif" guruhiga uzun yorliqli yangi maydon qo'shildi: "Qo'shimcha istaklaringiz". Qaysi maydonlarning joyi o'zgaradi?

Javob

Hammasining. Yorliqlar ustuni max-content — endi eng uzun yorliq yangisi. Ustun kengayadi va hamma maydon bir xil masofaga o'ngga suriladi. Ular yana bir chiziqda qoladi — subgrid'ning foydasi shu.

Tor telefonda yorliq juda uzun bo'lsa, maydonga joy qolmaydi. Bunday holda yorliqni maydon ustiga qo'yish yaxshiroq (Grid'da tekislash darsidagi portfolio formasi kabi).

6. Brauzerlar va DevTools

6.1 Baseline holati

Baseline ma'lumotiga ko'ra, subgrid 2023-yil sentabrda hamma asosiy brauzerga yetib keldi (Firefox 71, Safari 16, Chrome va Edge 117). 2026-yil martdan beri u keng qo'llab-quvvatlanadi (Baseline Widely available). Bugun uni bemalol ishlating.

Juda eski brauzerda nima bo'ladi? CSS nima darsidagi qoida: tushunilmagan deklaratsiya tashlab yuboriladi. grid-template-rows: subgrid tashlanadi va karta oddiy grid bo'lib qoladi — «Nega bu kerak?» bo'limidagi "zinapoya". Kartalar o'qiladi, faqat chiziqlar tekis emas.

Sahifa buzilmaydi — bu progressive enhancement. Yangi imkoniyatni shart bilan qo'shadigan @supports qoidasini Brauzer mosligi darsida o'rganamiz, hozir bilish shart emas.

6.2 DevTools'da subgrid

Elements panelida grid konteyner yonida grid belgisi chiqadi (Grid'ga kirish). Subgrid elementi yonida esa subgrid belgisi. Uni bossangiz, ota to'r va subgrid chiziqlari birga chiziladi. Karta chegarasidan o'tib ketgan ota qatorlarini ko'rasiz.

7. Ko'p uchraydigan xatolar

7.1 span soni elementlar sonidan kam

Kartaga "Yangi" yozuvi qo'shildi — endi beshta element, lekin span 4 qoldi:

html
<style>
  body { font-family: system-ui, sans-serif; }
  section {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
    max-width: 28rem;
  }
  .taom-karta {
    display: grid;
    grid-row: span 4;
    grid-template-rows: subgrid;
    row-gap: 0.5rem;
    padding: 1rem;
    border: 2px solid #2f6b3a;
  }
  .taom-karta > * { margin: 0; }
  .narx { color: #b4461a; font-weight: bold; }
  .bron-havola {
    justify-self: start;
    background-color: #2f6b3a;
    color: #fff;
  }
</style>
<section>
  <article class="taom-karta yangi">
    <h3 class="taom-nomi">Osh</h3>
    <strong>Yangi</strong>
    <p>Toshkentcha to'y oshi.</p>
    <p class="narx">35 000 so'm</p>
    <a class="bron-havola" href="bron/">Stol band qilish</a>
  </article>
  <article class="taom-karta">
    <h3 class="taom-nomi">Manti</h3>
    <p>Qovoqli.</p>
    <p class="narx">30 000 so'm</p>
    <a class="bron-havola" href="bron/">Stol band qilish</a>
  </article>
</section>

Nimaga qarang: chap kartada tugma narxning ustiga chiqib, uni yopib qo'ydi. Qo'shni kartada "Yangi" yo'q, lekin uning tavsifi "Yangi" qatoriga tushdi va chiziqlar siljidi.

Sabab: subgrid o'zi yangi qator yarata olmaydi — unda implicit qatorlar yo'q. Joylashtirish darsida oddiy grid ortiqcha elementga yangi qator qo'shardi, subgrid esa faqat otadan olgan to'rtta qatorga ega.

Beshinchi element oxirgi qatorga, to'rtinchi element ustiga tushdi. Chrome'da tekshirdik: narx va tugma bitta qatorda, ustma-ust.

Tuzatish: span soni = elementlar soni. Kartalarda elementlar soni har xil bo'lsa — hammasiga eng katta sonni bering (span 5). Kam elementli kartada oxirgi qator bo'sh qoladi, lekin tartib buzilmaydi.

7.2 Kartada display: grid unutilgan

grid-template-rows: subgrid faqat grid konteynerda ishlaydi. display: grid bo'lmasa, deklaratsiya hech narsa qilmaydi va karta oddiy blok qoladi. Tuzatish: uchala qatorni doim birga yozing.

7.3 Ichki masofa juda katta

Karta ichida elementlar kartalar orasidagi masofada tarqalib turibdi. Sabab — gap merosi. Tuzatish: kartaga row-gap bering.

7.4 Kartani o'rab olgan qo'shimcha div

section > div > article — karta endi section ning bolasi emas, div niki. Subgrid faqat to'g'ridan-to'g'ri ota grid bilan bog'lanadi. Oradagi div grid bo'lmasa, zanjir uziladi. Tuzatish: keraksiz o'ramni olib tashlang yoki uni ham subgrid qiling.

7.5 fieldset ni subgrid qilish

Bron formasida ikki guruh bor: "Siz haqingizda" va "Tashrif". Ikkala guruhdagi yorliqlarni bitta ustunga tekislash uchun formani grid, har fieldset ni esa subgrid qilish tabiiy tuyuladi. Chrome'da tekshirdik (154-versiya): fieldset ga grid-template-columns: subgrid yozilganda ichidagi div lar ustunlarni olmadi. Yorliqlar va maydonlar bitta ustunda ustma-ust tushdi.

Nega? fieldset — legend bilan birga o'ziga xos chiziladigan element, subgrid zanjiri unda uzildi.

Tuzatish: har fieldset ni o'zi grid qiling ("Ustunli subgrid" misolidagi kabi), div lar esa uning subgrid'i bo'lsin. Ikki guruhdagi yorliqlar ham bir chiziqda tursin desangiz — yorliq ustuniga ikkala fieldset da bir xil qat'iy en bering, masalan [yorliq-start] 9rem.

8. Mashqlar

Mashqlarni kurs/mashqlar/05/ papkasida bajaring: har mashqqa alohida papka, ichida index.html va asosiy.css.

1-mashq (oson): Ikki qatorli kartalar

«Bahor» ichimliklar kartalari: har kartada faqat nom (h3) va narx (p class="narx"). Kartalar to'ri tayyor:

css
section {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}

Nomlar "Ko'k choy", "Limonli qora choy va asal" va "Kompot". Narxlar bir chiziqda tursin. Kartaga uch qator yozing.

Ishora: nechta element — shuncha span.

Yechim
css
.taom-karta {
  display: grid;
  grid-row: span 2;
  grid-template-rows: subgrid;
  row-gap: 0.25rem;
}

Kartada ikki element bor — span 2. Uzun nom ikki qatorga tushsa, birinchi ota qatori hamma kartalar uchun baland bo'ladi va narxlar bir chiziqda qoladi. row-gap — ixtiyoriy: usiz nom va narx orasi 1rem bo'lardi.

2-mashq (o'rta): Bo'sh joyni to'ldiring

Aloqa formasi: yorliqlar chapda, maydonlar o'ngda, bir chiziqda. Bo'sh joylarni to'ldiring.

css
form {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.75rem 1rem;
}

form p {
  display: grid;
  grid-column: 1 / -1;
  grid-template-columns: ___;
  margin: 0;
}
  1. grid-template-columns qiymati:
  2. grid-column: 1 / -1 o'rniga qaysi span yozuvi bir xil natija beradi (ikki ustunli formada)?
Javob
  1. subgrid — p o'z ustunlarini chizmaydi, formaning ikki ustunini ishlatadi.
  2. span 2 — ikki ustun. 1 / -1 "birinchi chiziqdan oxirgisigacha" deydi, ustunlar soni o'zgarsa ham ishlaydi. span 2 esa aniq ikkita. Ikki ustunli formada natija bir xil.

3-mashq (qiyin): Ikki xato

Stajyor menyu kartalarini subgrid qildi. Kartalarda to'rt element: nom, tavsif, narx va "Stol band qilish" havolasi. Birinchi karta — mashhur. Kod:

css
section {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}

.taom-karta {
  display: grid;
  grid-row: span 3;
  grid-template-rows: subgrid;
  padding: 1rem;
}

.taom-karta.mashhur {
  padding-top: 2rem;
}

Jasur aka ikki narsadan shikoyat qildi: "tugmalar narxni yopib qo'ygan" va "mashhur kartada nom boshqalardan pastroqda". HTML'da section va kartalar orasida hech narsa yo'q. Ikkala xatoning sababini toping va tuzating.

Ishora: "Ko'p uchraydigan xatolar" dagi span qoidasi va karta padding'i haqidagi maslahat.

Yechim
  1. span 3, elementlar esa to'rtta. Subgrid'da implicit qator yo'q, to'rtinchi element — havola — oxirgi qatorga, narxning ustiga tushdi. Tuzatish: span 4.

  2. Mashhur kartaning padding-top i boshqacha. Karta padding'i birinchi qatorga qo'shiladi. Chrome'da o'lchadik: mashhur kartada nom 16 piksel pastroqdan boshlanadi. Tavsif, narx va tugma esa hamma kartada bir chiziqda qoladi — faqat nom siljiydi.

    Tuzatish: hamma kartaga bir xil padding. Mashhur kartani boshqa usul bilan ajrating, masalan chegara rangi bilan.

css
.taom-karta {
  display: grid;
  grid-row: span 4;
  grid-template-rows: subgrid;
  padding: 1rem;
  border: 2px solid #2f6b3a;
}

.taom-karta.mashhur {
  border-color: #b4461a;
}

Saboq: subgrid'da kartaning "ramkasi" (padding va border) ham chiziqlarga ta'sir qiladi. Ularni kartadan kartaga o'zgartirmang. Chegara qalinligi ham ramkaning bir qismi. Shuning uchun mashhur kartada faqat rang o'zgardi, qalinlik esa hamma kartada 2px.

4-mashq: Portfolio qadami — loyiha kartalari bir chiziqda

Portfolioning loyihalar/index.html sahifasida kartalar div.loyihalar to'rida (Grid'ga kirish va repeat() va minmax() darslaridan). Har article da to'rt narsa: h2 nom, sana (p ichida time), tavsif p va havolalar ro'yxati ul. Nomlar va tavsiflar uzunligi har xil — sanalar va havolalar "zinapoya" bo'lib turibdi.

  1. Kartalarni subgrid qiling: nomlar, sanalar, tavsiflar va havolalar ro'yxatlari qo'shni kartada bir chiziqda tursin.
  2. Karta ichidagi oraliq 0.5rem bo'lsin. Kartalar orasidagi oraliq .loyihalar dagi kabi qolsin.
  3. Karta ichidagi elementlarning margin'ini nolga tushiring, karta padding'ini 1rem qiling.

Ishora: portfolio'da karta — .loyihalar > article. Nechta element — shuncha span. Oldingi darslardagi karta qoidalari (chegara, burchak, soya) o'zgarmaydi.

Yechim

asosiy.css ga:

css
/* Loyiha kartalari: ichi ota to'rga ulanadi */
.loyihalar > article {
  display: grid;
  grid-row: span 4;
  grid-template-rows: subgrid;
  row-gap: 0.5rem;
  padding: 1rem;
}

.loyihalar > article > * {
  margin: 0;
}

Loyihalar sahifasi taxminan shunday ko'rinadi (.loyihalar to'ri — repeat() va minmax() darsidagi, o'zgarmaydi):

html
<style>
  body {
    font-family: system-ui, sans-serif;
    color: #1f2a24;
    background-color: #f7faf8;
  }
  main { width: min(100% - 2rem, 70ch); margin-inline: auto; }
  h1, h2 { color: #1f6f4a; }
  .loyihalar {
    display: grid;
    grid-template-columns:
      repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
    gap: 1.5rem;
  }
  .loyihalar > article {
    display: grid;
    grid-row: span 4;
    grid-template-rows: subgrid;
    row-gap: 0.5rem;
    padding: 1rem;
    border: 1px solid #c9d6cf;
    border-radius: 0.5rem;
  }
  .loyihalar > article > * { margin: 0; }
  .loyihalar ul { padding-left: 1.25rem; }
</style>
<main>
  <h1>Loyihalar</h1>
  <div class="loyihalar">
    <article>
      <h2>Choyxona «Bahor» sayti</h2>
      <p><time datetime="2026-09">2026-yil sentabr</time></p>
      <p>To'rt sahifali sayt: menyu jadvali, stol band qilish
      formasi va 404 sahifasi. Validatordan xatosiz o'tgan.</p>
      <ul>
        <li><a href="bahor/">Loyiha haqida batafsil</a></li>
        <li>
          <a href="https://example.com/bahor/">Saytni ochish</a>
        </li>
      </ul>
    </article>
    <article>
      <h2>Semantik blog maqolasi</h2>
      <p><time datetime="2026-08">2026-yil avgust</time></p>
      <p>"Osh sirlari" maqolasi: landmarklar va izohli rasmlar.</p>
      <ul>
        <li><a href="https://example.com/blog/">Saytni ochish</a></li>
      </ul>
    </article>
  </div>
</main>
  • span 4 — kartada to'rtta bola: h2, ikkita p, ul. Loyiha kartasiga yangi element qo'shsangiz (masalan, skrinshot), span ni ham oshiring.
  • Kompyuter enida (1280) ikki karta yonma-yon: sanalar va havolalar ro'yxatlari bir chiziqda. Telefonda (360) kartalar ustma-ust — har biri o'z to'rt qatorini oladi.
  • Margin'larni nolga tushirdik: subgrid'da ular qatorlarga qo'shiladi va masofani ikki joydan boshqarib qo'yardi. Endi masofa bitta joyda — row-gap da.
  • Kartaning eski padding: 0.25em 1em i endi 1rem: margin'lar yo'qolgach, matn chegaraga yopishib qolmasin.

9. Real ishda

  • Internet-do'konlar va narx jadvallari. "Tarif" kartalari (oddiy / premium / biznes) — subgrid'ning eng mashhur ishi: har kartada imkoniyatlar ro'yxati, narx va tugma bir chiziqda. Ilgari buni JavaScript bilan balandlikni o'lchab tekislashardi.
  • Formalar. Yorliq va maydonni tekislash — admin panellar va sozlamalar sahifalarida har kuni uchraydi.
  • Dizayn tizimlari. Figma'dagi "auto layout" kartalari ko'pincha subgrid bilan CSS'ga ko'chiriladi. Karta komponenti o'zini qaysi to'rga qo'yishganini bilmasa ham, subgrid uni ota qatorlarga moslaydi.
  • Intervyuda: "Kartalar teng balandlikda, lekin tugmalar bir chiziqda emas — qanday tuzatasiz?" Javob: margin-top: auto (faqat pastki element) yoki subgrid (hamma element).

Xulosa

  • Har grid karta o'z qatorlarini alohida hisoblaydi — shuning uchun qo'shni kartalardagi elementlar bir chiziqda turmaydi.
  • display: grid + grid-row: span N + grid-template-rows: subgrid — karta ota to'rning N ta qatorini ishlatadi.
  • Ota qatori balandligi hamma kartadagi eng baland elementga teng bo'ladi.
  • Subgrid otaning gap ini meros oladi. row-gap bilan faqat karta ichini o'zgartirasiz.
  • Nomli chiziqlar ham meros o'tadi: grid-column: maydon subgrid ichida ishlaydi.
  • span soni elementlar sonidan kam bo'lsa, ortiqcha element oxirgi qatorga, ustma-ust tushadi.
  • subgrid — Baseline Widely available (2026-yil martdan).

Keyingi dars: Layout naqshlari — full-bleed, rasm ustida matn, masonry va "flex yoki grid?" degan savolga yakuniy qoida.

Manbalar

  • MDN: "Subgrid", "grid-template-rows" — developer.mozilla.org
  • W3C: "CSS Grid Layout Module Level 2" (Subgrids bo'limi) — w3.org/TR/css-grid-2
  • web.dev: "CSS subgrid" — web.dev/articles/css-subgrid
  • web-features: "Subgrid" — web-platform-dx.github.io/web-features
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
CSS subgrid: kartalar ichidagi sarlavha va narxni bir chiziqqa tekislash — IlmHamroh