IlmHamroh
JavaScript Full-stack/5-qism. CSS asoslari va layout58/63-dars19 daqiqa
Mundarija (31)

Intrinsic layout: media query'siz responsive CSS

Qisqacha: Intrinsic layout — brauzerga "qaysi ekranda nima" deb emas, "karta kamida 18rem bo'lsin" kabi qoida berish; qolganini brauzer o'zi hal qiladi. Asosiy vositalar: repeat(auto-fit, minmax(min(18rem, 100%), 1fr)) to'ri, flex-wrap bilan o'raladigan qatorlar va "switcher" hiylasi — flex-basis: calc((40rem - 100%) * 999), u konteyner 40rem dan tor bo'lsa hammasini ustunga, keng bo'lsa bitta qatorga qo'yadi. Every Layout kitobidagi primitivlar — Stack, Cluster, Sidebar, Switcher, Center, Cover — shu g'oyaning tayyor retseptlari.

Bu darsda

  • Nega media query'lar ba'zan noqulay va intrinsic layout nimani yaxshilashini tushuntirasiz.
  • auto-fit + minmax(min(...), 1fr) to'rini toshib ketmaydigan qilib yozasiz.
  • "Switcher" hiylasini raqamlar bilan tushuntirasiz.
  • Every Layout primitivlarining oltitasini soddalashtirilgan ko'rinishda yozasiz.
  • Portfoliongizdan media query'larni olib tashlab, uni "o'zi moslashadigan" qilasiz.

Oldin bilishingiz kerak: repeat(), minmax() va auto-fit, Fluid tipografiya, flex algoritmi, Mobile-first.

1. Nega bu kerak?

Media queries darsida taom kartalarini 40rem va 64rem breakpointlar bilan qurdik. Ikki muammo qoldi:

  1. Ekran — konteyner emas. Media query oyna eniga qaraydi. Kartalar esa ba'zan keng ustunda, ba'zan tor yon panelda turadi. Keng ekrandagi tor panelda uch ustunli to'r kartalarni qisib qo'yadi — "ekran keng" sharti bajarilgan-ku.
  2. Ko'p breakpoint — ko'p holat. Har yangi komponent o'z breakpointini so'raydi.

Yechim g'oyasi: brauzerga aniq buyruq emas, cheklov bering. "768 da ikki ustun" emas, "karta 18rem dan tor bo'lmasin, sig'gancha joylashtir". Brauzer har ekranda, har konteynerda o'zi hisoblaydi.

Ofitsiant Otabekka har holat uchun qoida yozmaysiz ("10 kishi kelsa, ikkita stol"). "Har odamga kamida 60 santimetr joy" deysiz — u stollarni o'zi joylaydi.

Bu yondashuvni dizayner Jen Simmons 2018-yilda intrinsic web design deb atadi. "Intrinsic" — "ichki": layout tashqi ekranga emas, kontentning ichki o'lchamiga qarab quriladi.

2. Grid: auto-fit va minmax()

2.1 Eslatma: RAM

repeat(), minmax() va auto-fit darsidagi retsept:

html
<style>
  body {
    font-family: system-ui, sans-serif;
    background-color: #fffaf0;
  }
  section {
    display: grid;
    grid-template-columns:
      repeat(auto-fit, minmax(min(18rem, 100%), 1fr));
    gap: 1rem;
  }
  .taom-karta {
    padding: 0 1rem;
    border: 2px solid #2f6b3a;
    border-radius: 0.5rem;
  }
  .narx {
    color: #b4461a;
  }
</style>
<section>
  <article class="taom-karta">
    <h3>Osh</h3>
    <p><span class="narx">35 000 so'm</span></p>
  </article>
  <article class="taom-karta">
    <h3>Lag'mon</h3>
    <p><span class="narx">28 000 so'm</span></p>
  </article>
  <article class="taom-karta">
    <h3>Manti</h3>
    <p><span class="narx">30 000 so'm</span></p>
  </article>
</section>

Nimaga qarang: Media queries darsidagi uch holat — 360 da bitta, 768 da ikkita, 1280 da uchta ustun — endi bitta qator CSS bilan. Chrome'da o'lchadik: 360 da karta 344 piksel, 768 da 368, 1280 da 410.7. Hech qanday media query yo'q.

Bu naqshning ingliz tilidagi laqabi — RAM: Repeat, Auto, Minmax. Qanday o'qiladi: "Ustunlar kamida 18rem (yoki konteyner butun eni, qaysi biri kichik bo'lsa), bo'sh joy teng taqsimlansin; nechta sig'sa — shuncha ustun."

2.2 Ustunlar sonini o'zingiz hisoblang

Brauzer shunday hisoblaydi: nechta 18rem ustun va ular orasidagi gap konteynerga sig'adi?

text
ustunlar = (konteyner + gap) ÷ (eng kichik ustun + gap), pastga yaxlitlanadi
Konteyner Hisob Ustun
344 (360 ekran) (344 + 16) ÷ (288 + 16) = 1.18 1
752 (768 ekran) (752 + 16) ÷ 304 = 2.53 2
1264 (1280 ekran) (1264 + 16) ÷ 304 = 4.21 4

1280 da to'rtta ustun sig'adi, kartalar esa uchta. auto-fit bo'sh to'rtinchi ustunni 0 ga "yig'adi" va uchala karta butun enni bo'lib oladi. DevTools'da ko'rinadi: 410.656px 410.672px 410.656px 0px. auto-fill bo'lsa, bo'sh ustun joyni egallab qolardi (auto-fit darsidagi farq).

Breakpoint endi kontentning o'zidan chiqadi: 18rem × 2 + gap. Aynan Media queries darsida qo'lda hisoblagan son — faqat brauzer uni o'zi hisoblayapti.

2.3 min(18rem, 100%) nega kerak

Ichki min() bo'lmasa-chi? Kartani biroz kengroq — 23rem (368 piksel) qilamiz:

html
<style>
  body {
    font-family: system-ui, sans-serif;
    background-color: #fffaf0;
  }
  section {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(23rem, 1fr));
    gap: 1rem;
  }
  .taom-karta {
    padding: 0 1rem;
    border: 2px solid #2f6b3a;
  }
</style>
<section>
  <article class="taom-karta"><h3>Osh</h3></article>
  <article class="taom-karta"><h3>Manti</h3></article>
</section>

Telefon tugmasini bosing. Nimaga qarang: karta ekrandan o'ngga chiqib ketdi — gorizontal skroll. Chrome'da o'lchadik: 360 piksellik oynada ustun 368 piksel, sahifa eni 376. Konteyner atigi 344 — minmax ning pastki chegarasi undan katta, grid esa chegarani buzmaydi.

min(23rem, 100%) — "23rem, lekin konteynerdan katta emas". Tor ekranda 100% kichikroq va ustun konteynerga sig'adi. "Tahrirlab ko'rish" bilan tuzatib ko'ring. Bu — Matematik funksiyalar darsidagi min() ning eng foydali ishlatilishi.

Tekshirib ko'ring: repeat(auto-fit, minmax(min(15rem, 100%), 1fr)), gap: 1rem. Konteyner 1000 piksel. Nechta ustun sig'adi?

Javob

(1000 + 16) ÷ (240 + 16) = 3.97 — pastga yaxlitlanadi, 3 ta. To'rttasiga 4 × 240 + 3 × 16 = 1008 piksel kerak — 8 piksel yetmaydi. Uch ustun bo'sh joyni bo'lib oladi: har biri (1000 − 32) ÷ 3 = 322.7 piksel.

3. Flex: o'raladigan qatorlar va "switcher"

3.1 Grid'dagi "yolg'iz karta"

768 pikselda ikki karta yuqorida, uchinchisi pastda yolg'iz — grid'da oxirgi qator to'lmasa, bo'sh qoladi. Ba'zan boshqa narsa kerak: yo hammasi bitta qatorda, yo hammasi ustma-ust, 2 + 1 holatisiz.

3.2 Switcher hiylasi

Buni flex'ning bitta formulasi qiladi:

html
<style>
  body {
    font-family: system-ui, sans-serif;
    background-color: #fffaf0;
  }
  section {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
  }
  section > * {
    flex-grow: 1;
    flex-basis: calc((40rem - 100%) * 999);
  }
  .taom-karta {
    padding: 0 1rem;
    border: 2px solid #2f6b3a;
    border-radius: 0.5rem;
  }
  .narx {
    color: #b4461a;
  }
</style>
<section>
  <article class="taom-karta">
    <h3>Osh</h3>
    <p><span class="narx">35 000 so'm</span></p>
  </article>
  <article class="taom-karta">
    <h3>Lag'mon</h3>
    <p><span class="narx">28 000 so'm</span></p>
  </article>
  <article class="taom-karta">
    <h3>Manti</h3>
    <p><span class="narx">30 000 so'm</span></p>
  </article>
</section>

Nimaga qarang: 360 da uch karta ustma-ust, 768 da — uchalasi bir qatorda, har biri 240 piksel. 2 + 1 holati yo'q.

3.3 Raqamlar bilan

flex-basis — flex elementning "boshlang'ich eni" (flex algoritmi). Formulada 100% — konteyner eni, 40rem — chegara (640 piksel). Ikki holatni hisoblaymiz:

Tor konteyner, 344 piksel (360 ekran):

text
(640 − 344) × 999 = 296 × 999 = 295 704 piksel

Har karta "295 ming piksel bo'lmoqchi". Bitta qatorga hatto bittasi ham sig'maydi — flex-wrap har birini alohida qatorga tushiradi. Qatorda yolg'iz qolgan element konteynerdan keng bo'lolmaydi: flex-shrink uni 344 gacha qisadi. Natija — uch to'liq enli qator.

Keng konteyner, 752 piksel (768 ekran):

text
(640 − 752) × 999 = −112 × 999 = −111 888 piksel

Manfiy en bo'lmaydi — brauzer uni 0 ga tenglaydi. Uchala karta "0 piksel bo'lmoqchi" — bemalol bitta qatorga sig'adi. Keyin flex-grow: 1 bo'sh joyni teng bo'ladi: (752 − 2 × 16) ÷ 3 = 240 piksel. Aynan o'lchangan son.

× 999 nima uchun? Chegaraga 1 piksel yaqin bo'lsa ham natija keskin bo'lsin. Konteyner 639 bo'lsa, (640 − 639) × 999 = 999 piksel — baribir har karta alohida qatorda. 640 da esa 0 — bitta qatorda. Chrome'da o'lchadik: 655 piksellik oynada (konteyner 639) ustma-ust, 656 da (konteyner 640) — bir qatorda, har biri 202.7 piksel. Oraliq holat yo'q, shuning uchun "switcher" — "o'chirgich".

flowchart TD
  K{"Konteyner eni<br/>chegaradan tormi?"}
  K -->|Ha| U["flex-basis — juda katta<br/>musbat son"]
  U --> U2["Har element alohida qatorda:<br/>hammasi ustma-ust"]
  K -->|Yo'q| N["flex-basis — manfiy,<br/>brauzer uni 0 qiladi"]
  N --> N2["Hammasi bitta qatorda,<br/>flex-grow joyni teng bo'ladi"]

Nimaga qarang: brauzer faqat bitta savol beradi — konteyner chegaradan tormi? Javobga qarab ikki yo'ldan biri tanlanadi, uchinchi yo'l yo'q.

Diqqat: Chegara — konteyner eni, ekran emas. Shu kartalar tor yon panelga qo'yilsa, keng ekranda ham ustma-ust turadi. Media query buni qila olmaydi — u faqat ekranni biladi.

3.4 Oddiy flex-wrap bilan farqi

Faqat flex: 1 1 18rem yozilsa, kartalar ham o'raladi. Lekin 768 da uchinchisi pastda butun en bo'ylab cho'ziladi: flex'da har qator bo'sh joyini alohida bo'ladi. Teglar uchun oddiy wrap, teng kartalar uchun — grid yoki switcher.

Tekshirib ko'ring: Switcher chegarasi 30rem. Konteyner 500 piksel, gap: 1rem, ichida 2 element. Ular qanday joylashadi va har biri necha piksel?

Javob

30rem = 480 piksel. (480 − 500) × 999 = −19 980 — manfiy, 0 ga tenglanadi. Ikkalasi bir qatorda: (500 − 16) ÷ 2 = 242 piksel. Konteyner 480 dan tor bo'lganda ular ustma-ust tushadi.

4. Every Layout primitivlari

4.1 Kitob va g'oya

Heydon Pickering va Andy Bell "Every Layout" (every-layout.dev) sayt va kitobida intrinsic layout'ni kichik "g'ishtlar"ga bo'lishdi. Har g'isht — layout primitivi: bitta vazifani bajaradigan, qayerga qo'ysangiz ham ishlaydigan kichik CSS qoidasi. Katta sahifa shu g'ishtlardan yig'iladi. Ularda o'ndan ortiq primitiv bor (masalan, Box, Grid, Frame, Reel). Biz eng ko'p ishlatiladigan oltitasini ko'ramiz.

Quyida — asl retseptlarning bizning soddalashtirilgan versiyamiz; kitobdagi to'liq variantlarda qo'shimcha sozlamalar bor. Kitobda har primitiv alohida class yoki maxsus HTML element. Biz yangi nom kiritmaymiz — primitivlarni «Bahor»ning mavjud teg va class'lariga qo'llaymiz.

4.2 Stack — ustma-ust, teng oraliq bilan

Vazifasi: bolalar orasida bir xil vertikal joy. Muammo: har element o'z margin ini keltiradi — h3 bir xil, p boshqa, ul uchinchi. Stack ularni nolga tushirib, faqat orasiga joy qo'yadi:

css
.taom-karta > * {
  margin-block: 0;
}
.taom-karta > * + * {
  margin-block-start: 0.75rem;
}

* + * — "boshqa elementdan keyin turgan har element" (Asosiy selektorlar). Birinchi bolaning tepasida va oxirgisining ostida joy qolmaydi — kartaning padding i buzilmaydi. Margin sirlari darsidagi portfolio qadamida article + article ham aynan shu g'oya edi. Grid yoki flex ustunda gap ham xuddi shunday ishlaydi.

4.3 Cluster — o'raladigan guruh

Vazifasi: teglar, tugmalar, havolalar — sig'gancha qatorga, sig'masa keyingi qatorga, orasida teng joy:

html
<style>
  body {
    font-family: system-ui, sans-serif;
    background-color: #fffaf0;
  }
  .taom-karta {
    max-inline-size: 22rem;
    padding: 1rem;
    border: 2px solid #2f6b3a;
    border-radius: 0.5rem;
  }
  .taom-karta > * {
    margin-block: 0;
  }
  .taom-karta > * + * {
    margin-block-start: 0.75rem;
  }
  .taom-karta ul {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    padding: 0;
    list-style: none;
  }
  .taom-karta li {
    padding: 0.125rem 0.625rem;
    border-radius: 1rem;
    background-color: #e8f1ec;
  }
  .narx {
    color: #b4461a;
  }
</style>
<article class="taom-karta">
  <h3 class="taom-nomi">Lag'mon</h3>
  <p>Qo'lda cho'zilgan xamir, mol go'shti va sabzavotlar.</p>
  <ul>
    <li>Achchiq</li>
    <li>Go'shtli</li>
    <li>Rustam akaning tavsiyasi</li>
    <li>Yangi</li>
  </ul>
  <p><span class="narx">28 000 so'm</span></p>
</article>

Nimaga qarang: karta ichida ikki primitiv. Stack — nom, tavsif, teglar va narx orasida bir xil 12 piksel (Chrome'da o'lchadik). Cluster — teglar qatori: "Achchiq" va "Go'shtli" bitta qatorda, uzun "Rustam akaning tavsiyasi" keyingi qatorga o'tdi, "Yangi" uning yonida. Bitta ham breakpoint yo'q.

gap ikki qiymatni birdan beradi: qatorlar orasiga ham, elementlar orasiga ham (Flex'da tekislash). Oldin buning uchun margin va manfiy margin hiylalari ishlatilardi.

4.4 Sidebar — yon panel, joy yetmasa pastga

Vazifasi: ikki element yonma-yon — biri tor (yon panel), biri keng (asosiy). Joy yetmasa — ustma-ust. «Bahor»ning bron sahifasi: forma va "Ish vaqti" paneli:

html
<style>
  body {
    font-family: system-ui, sans-serif;
    background-color: #fffaf0;
  }
  main {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
  }
  aside {
    flex-basis: 15rem;
    flex-grow: 1;
    padding: 0 1rem;
    background-color: #e8f1ec;
  }
  form {
    flex-basis: 0;
    flex-grow: 999;
    min-inline-size: 50%;
  }
  input {
    box-sizing: border-box;
    width: 100%;
    padding: 0.5rem;
    font: inherit;
  }
</style>
<main>
  <form action="https://example.com/bron" method="post">
    <h1>Stol band qilish</h1>
    <label for="ism">Ismingiz</label>
    <input id="ism" name="ism" autocomplete="name">
  </form>
  <aside>
    <h2>Ish vaqti</h2>
    <p>Har kuni 7:00 dan 23:00 gacha.</p>
  </aside>
</main>

Uch qoida birgalikda ishlaydi:

  • aside { flex-basis: 15rem; } — panel tabiiy eni 240 piksel (ichki bo'sh joy bilan 272).
  • form { flex-grow: 999; } — bo'sh joyning deyarli hammasini forma oladi. 999 ga 1 — panel faqat mingdan bir ulushni oladi.
  • form { min-inline-size: 50%; } — forma konteynerning yarmidan tor bo'lmaydi. Bo'lolmasa — panel pastga tushadi.

Qachon o'raladi? Bir qatorga sig'ish uchun: 272 + 16 + konteynerning yarmi ≤ konteyner. Ya'ni konteyner kamida 576 piksel. Chrome'da o'lchadik: 591 piksellik oynada (konteyner 575) panel pastda, 592 da (konteyner 576) yonma-yon — forma 288, panel 272. 768 da forma 463.5, panel 272.5; 1280 da forma 975, panel 273. Panel deyarli qotib turadi, forma o'sadi.

4.5 Center, Cover va Switcher

Center — kontentni o'rtaga qo'yib, enini cheklash. Portfolio'da bu Matematik funksiyalar darsidan beri bor:

css
main {
  width: min(100% - 2rem, 70ch);
  margin-inline: auto;
}

Every Layout'dagi variant max-inline-size va ichki padding bilan yoziladi — g'oyasi o'sha: "ko'pi bilan shuncha, chetlarda kamida shuncha joy".

Cover — blok kamida bir ekran baland, asosiy element vertikal o'rtada, qolganlari tepada va pastda. Viewport birliklari darsidagi «Bahor» "tabriknomasi"ning davomi:

html
<style>
  body {
    margin: 0;
    font-family: system-ui, sans-serif;
  }
  header {
    display: flex;
    flex-direction: column;
    min-block-size: 100vh;
    min-block-size: 100svh;
    padding: 1rem;
    box-sizing: border-box;
    background-color: #2f6b3a;
    color: #fffaf0;
  }
  header > * {
    margin-block: 0.5rem;
  }
  header > h1 {
    margin-block: auto;
    text-align: center;
  }
</style>
<header>
  <p>Choyxona «Bahor»</p>
  <h1>Xush kelibsiz!</h1>
  <p>Har kuni 7:00 dan 23:00 gacha</p>
</header>

Bu natija oynasining balandligi 400 piksel — 100svh shunga teng. Nimaga qarang: nom tepada, ish vaqti pastda, "Xush kelibsiz!" roppa-rosa o'rtada — Chrome'da o'lchadik, markazi 200 pikselda. margin-block: auto ustun flex'da bo'sh joyni tepaga va pastga teng bo'ladi (Margin sirlari, Flex naqshlari). Kontent ko'p bo'lsa, min-block-size blokni cho'zadi — hech narsa kesilmaydi.

Switcher — «Flex: o'raladigan qatorlar va "switcher"» bo'limida ko'rgan hiylamiz. Every Layout'da chegara --threshold o'zgaruvchisi bilan beriladi. Yana bir himoya bor: elementlar beshta va undan ko'p bo'lsa, :nth-last-child(n+5) miqdor so'rovi (Tuzilma pseudo-klasslari) ularni baribir ustma-ust qo'yadi — bitta qatorda beshta karta juda tor bo'lardi.

Primitiv Vazifasi Asosiy qoida
Stack Vertikal teng oraliq > * + * { margin-block-start }
Cluster O'raladigan guruh flex-wrap: wrap; gap
Sidebar Tor panel + keng asosiy flex-grow: 999; min-inline-size: 50%
Switcher Hammasi qatorda yoki ustunda calc((chegara - 100%) * 999)
Center O'rtada, eni cheklangan margin-inline: auto
Cover Bir ekran, o'rtada asosiy min-block-size: 100svh; margin-block: auto

5. Media query qachon baribir kerak

Intrinsic layout breakpointlarni kamaytiradi, lekin butunlay yo'q qilmaydi. Media query kerak bo'ladigan holatlar:

  • Tuzilma o'zgaradi, o'lcham emas. Telefonda menyu "Menyu" tugmasi ortiga yashirinadi, kompyuterda ochiq turadi (Navbar va mobil menyu). Bu joy masalasi emas, xulq masalasi.
  • Grid hududlari qayta chiziladi. grid-template-areas bilan sahifa sxemasi butunlay o'zgarsa.
  • Foydalanuvchi sozlamalari va chop etish: qorong'i rejim, kamroq harakat, printer (Foydalanuvchi afzalliklari).

Komponent o'z konteyneriga qarab tuzilishini o'zgartirishi kerak bo'lsa (masalan, keng joyda rasm yonida, tor joyda ostida) — buning uchun Container queries bor. Bu keyingi dars.

6. Ko'p uchraydigan xatolar

6.1 minmax da min() yo'q

minmax(23rem, 1fr) — tor ekranda karta konteynerdan chiqadi («min(18rem, 100%) nega kerak» qismi). Tuzatish: minmax(min(23rem, 100%), 1fr).

6.2 Switcher'da chegara ekran deb o'ylash

"40rem dan keng ekranda qatorga o'tadi" — yo'q, konteyner 40rem dan keng bo'lganda. Kartalar padding li ota ichida bo'lsa, ekran 700 bo'lsa ham konteyner 640 dan tor bo'lishi mumkin. Tuzatish: chegarani konteyner eniga qarab tanlang, DevTools'da konteyner enini o'lchang.

6.3 Sidebar'da min-inline-size unutilgan

Chrome'da tekshirdik: usiz 420 piksellik oynada forma atigi 116 piksel, panel esa yonida 272. Endi o'ralish nuqtasini formadagi eng uzun so'z belgilaydi (min-width: 0 darsidagi avtomatik minimum). Tuzatish: asosiy elementga min-inline-size: 50%.

6.4 Hamma narsani intrinsic qilishga urinish

Menyu tugmasi yoki grid hududlari uchun murakkab hiylalar. Tuzatish: xulq yoki tuzilma o'zgarsa — media yoki container query.

7. Mashqlar

1-mashq (oson): Nechta ustun?

grid-template-columns: repeat(auto-fit, minmax(min(12rem, 100%), 1fr)); gap: 1rem;

  • Konteyner 300 piksel → ustun
  • Konteyner 500 piksel → ustun
  • Konteyner 1000 piksel → ustun

Ishora: (konteyner + gap) ÷ (192 + gap), pastga yaxlitlang.

Yechim
  • (300 + 16) ÷ 208 = 1.52 → 1.
  • (500 + 16) ÷ 208 = 2.48 → 2.
  • (1000 + 16) ÷ 208 = 4.88 → 4.

192 — 12rem pikselda. Konteyner 192 dan tor bo'lsa, min() ustunni konteyner eniga tushiradi va toshib ketish bo'lmaydi.

2-mashq (o'rta): Switcher chegarasi

«Bahor» aloqa sahifasida uchta blok bor: manzil, telefon, ish vaqti. Ular yo bir qatorda, yo ustma-ust bo'lsin. Har blok kamida 12rem kerak, orasida gap: 1rem.

  1. Switcher chegarasini hisoblang: uch blok bir qatorga qachon sig'adi?
  2. CSS'ni yozing (ota — address, bolalari — p).
  3. Konteyner 560 va 700 piksel bo'lganda flex-basis nimaga teng bo'ladi?
Yechim
  1. 3 × 12rem + 2 × 1rem = 36rem + 2rem = 38rem (608 piksel).
css
address {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}
address > * {
  flex-grow: 1;
  flex-basis: calc((38rem - 100%) * 999);
}
  1. Konteyner 560 da: (608 − 560) × 999 = 47 952 piksel — har blok alohida qatorda. Konteyner 700 da: (608 − 700) × 999 = −91 908, ya'ni 0. Uchalasi bir qatorda, har biri (700 − 32) ÷ 3 = 222.7 piksel.

3-mashq (qiyin): Sidebar qachon o'raladi?

Menyu sahifasida: chapda taom kartalari (section), o'ngda "Bugungi aksiya" (aside). aside { flex-basis: 20rem; flex-grow: 1; } — ichki bo'sh joysiz. section { flex-basis: 0; flex-grow: 999; min-inline-size: 60%; }. gap: 2rem.

  1. Konteyner eni qanchadan boshlab ikkalasi yonma-yon turadi?
  2. 1000 piksellik konteynerda aside taxminan necha piksel?
  3. Nega section ga 999, aside ga 1?
Yechim
  1. Shart: 320 + 32 + 0.6 × W ≤ W → 352 ≤ 0.4 × W → W ≥ 880 piksel. Undan tor konteynerda aside pastga tushadi.
  2. Flex avval boshlang'ich enlarni qo'yadi: aside 320, section 0, oraliq 32. Qolgan 648 piksel 999 : 1 nisbatda bo'linadi — aside ga atigi 0.65 piksel. Demak aside ≈ 320.6 piksel, section ≈ 647.4. Bu 60% (600) dan keng — min-inline-size bu yerda ishga tushmaydi.
  3. aside o'z tabiiy enida qolsin, o'sishni deyarli butunlay section olsin. flex-grow: 1 — "juda kerak bo'lsa, ozgina o'sa olaman" (masalan, pastga tushib, yolg'iz qolganda butun enni egallash uchun).

4-mashq: Portfolio qadami — media query'siz portfolio

Mobile-first darsida portfolio'ga ikki breakpoint qo'ydik, Fluid tipografiya darsida 64rem ni olib tashladik. Endi 40rem ni ham intrinsic yechimlar bilan almashtiring.

  1. Header — Cluster. header ni media query'siz qiling: flex, o'raladigan, ism va menyu ikki chetda, vertikal markazda. Joy yetmasa, menyu o'zi keyingi qatorga tushsin.
  2. Loyihalar — RAM. .loyihalar dagi (width >= 40rem) blokni olib tashlang. Karta kamida 16rem bo'lsin, toshib ketmasin.
  3. asosiy.css da @media qidiring: header va loyihalar uchun en bo'yicha birorta ham blok qolmasin. Bosh sahifa "rasm"idagi blok (grid-template-areas) hozircha turadi — uning taqdirini yakuniy loyihada hal qilamiz.
  4. 320, 360, 500, 768 va 1280 pikselda tekshiring: header qaysi endan bir qatorga o'tadi? Loyihalar qachon ikki ustun bo'ladi?

Ishora: header — flex-wrap: wrap va justify-content: space-between (Cluster). Qatorlar orasiga joy kerak emas — column-gap yetadi. RAM — «Grid: auto-fit va minmax()» bo'limida.

Yechim
css
/* Header — Cluster: joy yetsa bir qatorda, yetmasa o'raladi */
header {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  column-gap: 1rem;
}

/* Loyihalar — RAM: karta kamida 16rem */
.loyihalar {
  display: grid;
  grid-template-columns:
    repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
  gap: clamp(1rem, 0.6087rem + 1.7391vw, 2rem);
}

(width >= 40rem) blokidan header va .loyihalar qoidalari o'chiriladi. Header qoidasi tanish: bu Flex naqshlari darsidagi navbar — Media queries darsida uni blok ichiga olgan edik, endi asosga qaytdi.

html
<style>
  :root {
    --rang-matn: #1f2a24;
    --rang-fon: #f7faf8;
    --rang-asosiy: #1f6f4a;
    --rang-chegara: #c9d6cf;
  }
  body {
    margin: 0;
    font-family: system-ui, sans-serif;
    font-size: clamp(1rem, 0.9511rem + 0.2174vw, 1.125rem);
    line-height: 1.5;
    color: var(--rang-matn);
    background-color: var(--rang-fon);
  }
  header,
  main {
    width: min(100% - 2rem, 70ch);
    margin-inline: auto;
  }
  header {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    column-gap: 1rem;
  }
  header a {
    color: var(--rang-asosiy);
  }
  nav [aria-current="page"] {
    color: var(--rang-matn);
    font-weight: bold;
  }
  nav ul {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1rem;
    margin: 0;
    padding: 0;
    list-style: none;
  }
  h1,
  h2 {
    color: var(--rang-asosiy);
    line-height: 1.2;
  }
  h1 {
    font-size: clamp(1.75rem, 1.4565rem + 1.3043vw, 2.5rem);
  }
  h2 {
    font-size: clamp(1.375rem, 1.3261rem + 0.2174vw, 1.5rem);
    margin-top: 0;
  }
  .loyihalar {
    display: grid;
    grid-template-columns:
      repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
    gap: clamp(1rem, 0.6087rem + 1.7391vw, 2rem);
  }
  .loyihalar article {
    padding: 1rem;
    border: 1px solid var(--rang-chegara);
    border-radius: 0.5rem;
  }
</style>
<header>
  <p><a href="../">Aziz Karimov</a></p>
  <nav aria-label="Asosiy menyu">
    <ul>
      <li><a href="../">Bosh sahifa</a></li>
      <li><a href="../haqimda/">Men haqimda</a></li>
      <li><a href="./" aria-current="page">Loyihalar</a></li>
      <li><a href="../aloqa/">Aloqa</a></li>
    </ul>
  </nav>
</header>
<main id="asosiy">
  <h1>Loyihalar</h1>
  <p>HTML va CSS qismida qilgan ishlarim.</p>
  <div class="loyihalar">
    <article>
      <h2>Choyxona «Bahor» sayti</h2>
      <p>To'rt sahifali sayt: menyu jadvali, stol band qilish
      formasi va 404 sahifasi.</p>
    </article>
    <article>
      <h2>Semantik blog maqolasi</h2>
      <p>"Osh sirlari" maqolasi: landmarklar, sarlavhalar
      daraxti va izohli rasmlar.</p>
    </article>
  </div>
</main>

Chrome'da o'lchadik:

Ekran Header Menyu Loyihalar
320, 360 Ism tepada, menyu ostida Ikki qatorga o'ralgan 1 ustun
500 Bir qatorda Bitta qator (341 piksel) 1 ustun (468)
768 Bir qatorda Bitta qator 2 ustun (306.9)
1280 Bir qatorda Bitta qator 2 ustun (323.6)

Nozik joylar:

  • Header 500 pikselda bir qatorga o'tdi — 40rem (640) breakpointdan ancha oldin. Cluster ism va menyu haqiqatan sig'adigan enni o'zi topdi.
  • Loyihalar 560 pikselda hali bitta ustun, 640 da ikkita (DevTools'da 293.562px 293.578px). 1280 da ham ikkita: main 70ch (679 piksel), uchinchi ustun sig'maydi.
  • Header va loyihalar uchun en bo'yicha @media qolmadi. Menyuni telefonda tugma ortiga yashirish (xohlasangiz) — Navbar va mobil menyu darsida.

8. Real ishda

  • Dizayn tizimlari va komponent kutubxonalarida (kursda keyin) Stack, Cluster, Grid nomli layout komponentlarini ko'p uchratasiz — ichida aynan shu CSS.
  • Qo'llab-quvvatlash arzonlashadi: yangi komponentga breakpoint kerak emas — u o'zi moslashadi.
  • Intervyuda so'raladi: "Media query'siz responsive karta to'rini qanday qilasiz?", "auto-fit va auto-fill farqi?", "Nega minmax ichida min()?". Bu darsdan keyin uchalasiga javob bera olasiz.

Xulosa

  • Intrinsic layout — brauzerga buyruq emas, cheklov berish: "karta kamida 18rem", qolganini brauzer hisoblaydi.
  • RAM: repeat(auto-fit, minmax(min(18rem, 100%), 1fr)) — ustunlar soni kontentdan chiqadi, min() toshib ketishdan saqlaydi.
  • Switcher: flex-basis: calc((chegara - 100%) * 999) — konteyner chegaradan tor bo'lsa hammasi ustunda, keng bo'lsa bitta qatorda; 2 + 1 holati yo'q.
  • Every Layout primitivlari (Heydon Pickering, Andy Bell): Stack, Cluster, Sidebar, Switcher, Center, Cover — kichik, qayta ishlatiladigan layout g'ishtlari.
  • Media query — xulq va tuzilma o'zgarganda; komponent o'lchami uchun — container query.

Keyingi dars: Container queries — komponent ekranga emas, o'z konteyneriga qarab tuzilishini o'zgartiradi.

Manbalar

  • Heydon Pickering, Andy Bell — "Every Layout" (every-layout.dev): The Stack, The Cluster, The Sidebar, The Switcher, The Center, The Cover
  • Jen Simmons — "Intrinsic Web Design" (2018)
  • MDN: "repeat()", "minmax()", "flex-basis", "Auto-placement in grid layout" — developer.mozilla.org
  • web.dev: "Learn CSS — Grid", "Learn CSS — Flexbox" — web.dev/learn/css
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Intrinsic layout: media query'siz responsive CSS — IlmHamroh