IlmHamroh
JavaScript Full-stack/6-qism. CSS: harakat, zamonaviy CSS va dizayn30/57-dars17 daqiqa
Mundarija (34)

CSS Modules: komponentga lokal class'lar

Qisqacha: CSS Modules — .module.css bilan tugagan fayldagi har class nomini build vositasi avtomatik noyob qiladigan usul: .narx brauzerga _narx_19o62_7 bo'lib boradi. Shuning uchun ikki komponentdagi bir xil nom to'qnashmaydi. Class JavaScript'dan olinadi: styles.narx. Vite va Next.js buni sozlanmasdan qo'llab-quvvatlaydi; :global() lokal qilishni o'chiradi, composes esa boshqa class'ni qo'shib oladi.

Bu darsda

  • Global class nomlari muammosini va CSS Modules uni qanday hal qilishini tushuntira olasiz.
  • *.module.css faylni Vite build'idan o'tkazib, haqiqiy natijadagi noyob nomlarni o'qiysiz.
  • :global(), composes va element selektorlarining "sizib chiqishi"ni bilasiz.
  • CSS Modules'ni BEM va @scope bilan solishtira olasiz va kamchiliklarini ayta olasiz.

Oldin bilishingiz kerak: CSS metodologiyalari, Kaskadni boshqarish: @layer va @scope, PostCSS va Lightning CSS.

1. Nega bu kerak?

CSS metodologiyalari darsida CSS'ning asosiy og'rig'ini ko'rgan edik: hamma class nomlari global — butun sahifa uchun bitta umumiy "nomlar bozori". Ikki dasturchi bir-birini bilmasdan bir xil nom tanlasa, qoidalar to'qnashadi. O'sha darsdagi Sherzodni eslang: u aksiya sahifasidagi narxni qizil qilmoqchi edi, ertasiga esa menyudagi hamma narx ham qizil bo'lib qoldi.

Masalan, «Bahor»da ikki fayl bor: menyu kartasi uchun va aksiya bloki uchun. Ikkalasida ham .narx:

html
<style>
  /* taom-karta.css */
  .narx {
    color: #b4461a;
  }
  /* aksiya.css — boshqa dasturchi yozgan */
  .narx {
    color: #1a5d1a;
    font-size: 1.5rem;
  }
  body { font-family: system-ui, sans-serif; }
</style>
<article>
  <h3>Osh</h3>
  <p class="narx">35 000 so'm</p>
</article>
<p class="narx">Bugun ko'k choy — 5 000 so'm!</p>

Nimaga qarang: osh narxi ham yashil va katta bo'lib qoldi — aksiya uchun yozilgan qoida menyuga "sizib" o'tdi. Kaskad qoidasi bo'yicha pastdagi yutdi (Kaskad). Hech kim xato qilmagan, ikkalasi ham o'z faylida to'g'ri yozgan.

Bunga uch xil javob bor:

  1. Kelishuv — nomlash qoidasi: BEM'da .taom-karta__narx va .aksiya__narx (CSS metodologiyalari). Ishlaydi, lekin odamlar intizomiga tayanadi.
  2. Brauzer — @scope (.taom-karta) qoidani DOM bo'lagiga chegaralaydi (Kaskadni boshqarish).
  3. Vosita — build paytida nomlarni avtomatik noyob qilish. Bu — CSS Modules.

Maktab o'xshatishi: sinfda ikkita Ali bor. Kelishuv — "familiyasi bilan chaqiraylik". Vosita esa har bolaga avtomatik raqamli ID beradi: Ali_7B_12. O'qituvchi jurnalga "Ali" deb yozadi, tizim esa kimligini aniq biladi.

2. CSS Modules qanday ishlaydi

2.1 Muhim eslatma: bu build vositasi ishi

CSS Modules — brauzer imkoniyati emas, CSS standarti ham emas. Bu build vositasi (bundler) qiladigan o'zgartirish. Bundler — loyihadagi ko'plab JS va CSS fayllarni saytga chiqarishdan oldin yig'ib, qayta ishlab, tayyor fayllarga aylantiradigan dastur. Xuddi bosmaxona kabi: siz qo'lyozma sahifalarni berasiz, u tartiblab, bitta kitob qilib chiqaradi. Mashhurlari — Vite, webpack; Next.js ichida ham bundler bor. Brauzer oddiy CSS va oddiy class nomlarini ko'radi, faqat ular endi g'alati ko'rinishda. Bundler'larni 16-qismda o'rganamiz. Bugun o'zingiz sozlashingiz shart emas — darsdagi natijalarni biz Vite 8.3.1 da haqiqiy build qilib oldik va o'zgarishsiz ko'rsatamiz.

Ikkinchi eslatma: class'ni HTML'ga qo'yish uchun JavaScript kerak. JavaScript'ni 08-qismdan o'rganasiz. Quyidagi JS qatorlarini hozir faqat o'qing — har birining ma'nosini oddiy so'z bilan yozamiz.

flowchart LR
  A["taom-karta.module.css<br/>.narx"] --> V["Vite build"]
  J["main.js<br/>import"] --> V
  V --> C["index-hash.css<br/>._narx_19o62_7"]
  V --> M["JS obyekt<br/>narx → _narx_19o62_7"]
  M --> H["HTML'da<br/>class=&quot;_narx_19o62_7&quot;"]

Nimaga qarang: Vite ikki narsa yasaydi — noyob nomli CSS fayl va "eski nom → yangi nom" lug'ati. JavaScript lug'atdan nomni olib, HTML'ga qo'yadi.

2.2 Fayl nomi — kalit

Bundler faqat nomi .module.css bilan tugagan faylni modul deb biladi. taom-karta.css — oddiy global CSS. taom-karta.module.css — CSS Module. Ichidagi yozuv esa oddiy CSS:

css
.taom-karta {
  padding: 1rem;
  border: 2px solid #2f6b3a;
  border-radius: 0.5rem;
}

.narx {
  color: #b4461a;
  font-weight: bold;
}

.tugadi {
  opacity: 0.6;
}

aksiya.module.css — boshqa dasturchining fayli, yana .narx:

css
.narx {
  color: #1a5d1a;
  font-size: 1.5rem;
}

2.3 JavaScript'dan ulash

src/main.js:

js
import karta from "./taom-karta.module.css";
import aksiya from "./aksiya.module.css";

document.querySelector("#menyu").innerHTML = `
  <article class="${karta["taom-karta"]}">
    <h3>Osh</h3>
    <p class="${karta.narx}">35 000 so'm</p>
  </article>
  <p class="${aksiya.narx}">Bugun ko'k choy — 5 000 so'm!</p>
`;

So'zlar bilan:

  • import karta from "./taom-karta.module.css" — "CSS faylni ula va uning nomlar lug'atini karta deb ata" (ESM import darsida to'liq).
  • karta.narx — "lug'atdan narx ning yangi nomini ol".
  • `...` ichidagi ${karta.narx} — "shu joyga lug'atdan olingan nomni qo'y". Natijada HTML'da class="_narx_19o62_7" paydo bo'ladi.
  • karta["taom-karta"] — xuddi shu, lekin nomda chiziqcha bor. JavaScript'da karta.taom-karta "karta.taom minus karta" deb o'qiladi, shuning uchun kvadrat qavs. Bu noqulaylikni pastda hal qilamiz.
  • Qolgani — HTML'ni sahifaga qo'yish (Kontentni o'zgartirish darsida, 09-qism).

2.4 Natija: haqiqiy build

npx vite build natijasidagi CSS fayl (dist/assets/index-...css, o'qish uchun siqilmagan holda):

css
._taom-karta_19o62_1 {
  padding: 1rem;
  border: 2px solid #2f6b3a;
  border-radius: 0.5rem;
}

._narx_19o62_7 {
  color: #b4461a;
  font-weight: bold;
}

._tugadi_19o62_12 {
  opacity: 0.6;
}
._narx_1ykee_1 {
  color: #1a5d1a;
  font-size: 1.5rem;
}

JavaScript'dagi lug'at — Vite yasagan kod ichidan:

js
var taom_karta_module_default = {
  "taom-karta": "_taom-karta_19o62_1",
  narx: "_narx_19o62_7",
  tugadi: "_tugadi_19o62_12"
};
var aksiya_module_default = { narx: "_narx_1ykee_1" };

Nomni bo'laklab o'qiymiz: _narx_19o62_7:

  • narx — asl nom. DevTools'da qaysi class ekanini taniysiz.
  • 19o62 — hash: fayl yo'lidan hisoblangan qisqa "barmoq izi". Bitta fayldagi hamma class'da bir xil (_taom-karta_19o62_1, _tugadi_19o62_12), boshqa faylda boshqa (_narx_1ykee_1).
  • 7 — manba fayldagi qator raqami: .narx 7-qatorda boshlangan.

Ikki .narx endi ikki xil nom. To'qnashuv jismonan imkonsiz.

Brauzer ko'radigan sahifa — Vite chiqargan CSS va JavaScript qo'ygan class'lar bilan:

html
<style>
  ._taom-karta_19o62_1 {
    padding: 1rem;
    border: 2px solid #2f6b3a;
    border-radius: 0.5rem;
  }
  ._narx_19o62_7 {
    color: #b4461a;
    font-weight: bold;
  }
  ._narx_1ykee_1 {
    color: #1a5d1a;
    font-size: 1.5rem;
  }
  body { font-family: system-ui, sans-serif; }
</style>
<article class="_taom-karta_19o62_1">
  <h3>Osh</h3>
  <p class="_narx_19o62_7">35 000 so'm</p>
</article>
<p class="_narx_1ykee_1">Bugun ko'k choy — 5 000 so'm!</p>

Nimaga qarang: osh narxi qizg'ish va qalin, aksiya narxi yashil va katta — har biri o'z qoidasini oldi. «Nega bu kerak?» bo'limidagi to'qnashuv yo'qoldi, ikkala faylda ham .narx degan qisqa nom qoldi.

2.5 Ichkarida kim ishlaydi

Vite bu ishni o'zi o'ylab topmagan. Uning sozlama tavsifida CSS Modules bo'limi postcss-modules plaginiga havola qiladi — ya'ni bu PostCSS va Lightning CSS darsidagi PostCSS'ning yana bir plagini. U AST'dagi har class nomini topadi, yangi nom yasaydi va lug'atni JavaScript'ga beradi.

Nom shakli ham sozlanadi: css.modules.generateScopedName sozlamasi bilan, masalan, faqat hash qoldirish mumkin — nom qisqaradi, lekin DevTools'da asl nomni tanib bo'lmay qoladi. Vite'da yana bir yo'l bor: CSS'ni PostCSS o'rniga Lightning CSS bilan qayta ishlash (css.transformer: "lightningcss"). Vite 8.3.1 tavsifida bu variant hali tajribaviy (experimental) deb belgilangan — standart holatda PostCSS ishlaydi.

Xulosa: CSS Modules — alohida "texnologiya" emas, build zanjiridagi bitta qadam. Uni tushunish uchun kutubxona emas, g'oya muhim: "nomni fayl bo'yicha noyob qil va lug'at ber".

Tekshirib ko'ring: Nega CSS Modules'da .narx kabi qisqa, oddiy nomlar ishlatish BEM'dagi .taom-karta__narx dan ko'ra xavfsiz?

Javob

Chunki noyoblikni odam emas, vosita kafolatlaydi. BEM'da __narx ni kimdir unutsa yoki ikki blok tasodifan bir xil nomlansa — to'qnashuv qaytadi. CSS Modules'da har fayl o'z hash'ini oladi: taom-karta.module.css dagi .narx va aksiya.module.css dagi .narx build'dan keyin albatta boshqa-boshqa nom. Qisqa nom faqat o'z fayli ichida ma'noga ega.

3. Lokal va global

3.1 Nima lokal bo'ladi, nima yo'q

Faqat class (va id) nomlari noyob qilinadi. Element va atribut selektorlari o'zgarmaydi. Kengroq fayl:

css
.taom-karta h3 {
  margin-top: 0;
}

p {
  margin: 0;
}

Build natijasi:

css
._taom-karta_1dime_1 h3 {
  margin-top: 0;
}

p {
  margin: 0;
}

.taom-karta h3 xavfsiz: h3 faqat karta ichida tanlanadi. Lekin yakka p — butun sahifadagi hamma paragraf. Modul faylda yozilgani uni lokal qilmadi. Qoida: modul faylda har selektor lokal class bilan boshlansin.

3.2 :global() — ataylab global

Ba'zan global class kerak: masalan, butun saytdagi .korinmas (CSS'da accessibility). :global() ichidagi nom o'zgarmaydi:

css
:global(.korinmas) {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

Natijada — oddiy .korinmas, hash'siz. Teskarisi ham bor — :local(), lekin standart holatda hamma narsa allaqachon lokal, shuning uchun u kam uchraydi.

Diqqat: :global() — CSS emas, CSS Modules sintaksisi. U faqat bundler ichida ma'noga ega. Oddiy .css faylda brauzer uni noto'g'ri selektor deb, butun qoidani tashlaydi.

3.3 composes — boshqa class'ni qo'shib olish

composes — "bu class'ga yana shu class'ni ham qo'sh":

css
.tugadi {
  composes: taom-karta;
  opacity: 0.6;
}

.mashhur {
  composes: taom-karta;
  composes: urgu from "./umumiy.module.css";
}

umumiy.module.css:

css
.urgu {
  border-color: #b4461a;
}

Vite natijasidagi lug'at:

js
{
  "taom-karta": "_taom-karta_1dime_1",
  narx: "_narx_1dime_11",
  tugadi: "_tugadi_1dime_16 _taom-karta_1dime_1",
  mashhur: "_mashhur_1dime_21 _taom-karta_1dime_1 _urgu_uhow8_1"
}

tugadi endi ikki class nomini qaytaradi. JavaScript class="${karta.tugadi}" yozsa, element ikkala class'ni oladi — karta ko'rinishi va xiralik. CSS'ning o'zida hech narsa nusxalanmadi: composes Sass/SCSS 2 darsidagi @extend kabi selektorlarni ko'paytirmaydi va mixin kabi deklaratsiyalarni ham nusxalamaydi. U faqat HTML'ga bir nechta class qo'yadi.

Qoidalar: composes qoida boshida yoziladi, faqat bitta class selektorli qoidada (.tugadi, .tugadi:hover da emas). Boshqa fayldan olganda — from "./fayl.module.css". Bu build'da Vite bir ogohlantirish ham chiqardi (A PostCSS plugin did not pass the from option...) — u Vite'ning ichki plagini haqida, natija to'g'ri chiqdi.

Tekshirib ko'ring: .aksiya { composes: narx; } yozildi. JavaScript aksiya.aksiya ni so'rasa, nechta class nomi qaytadi?

Javob

Ikkita: .aksiya ning o'z hash'li nomi va .narx ning hash'li nomi, bo'sh joy bilan. Masalan, "_aksiya_xxxx_1 _narx_xxxx_5" ko'rinishida — aniq hash fayl yo'liga bog'liq. Element ikkala qoidani ham oladi.

4. Amalda: sozlash, tiplar va dinamik class'lar

4.1 Vite va Next.js — sozlanmasdan

Vite'da *.module.css faylni import qilish yetarli — biz hech narsa sozlamadik. Next.js hujjati ham *.module.css ni tayyor qo'llab-quvvatlashini aytadi (Next.js'da stil darsida). .module.scss ham bor: avval Sass, keyin CSS Modules (Sass/SCSS 1).

Nom chiziqchali bo'lsa (karta["taom-karta"]) — JavaScript'da noqulay. Vite sozlamasi css.modules.localsConvention bilan lug'at kalitlarini camelCase'ga o'tkazish mumkin. vite.config.js:

js
export default {
  css: {
    modules: {
      localsConvention: "camelCaseOnly",
    },
  },
};

Natija lug'ati (tekshirdik):

js
{
  taomKarta: "_taom-karta_1dime_1",
  narx: "_narx_1dime_11",
  tugadi: "_tugadi_1dime_16 _taom-karta_1dime_1",
  mashhur: "_mashhur_1dime_21 _taom-karta_1dime_1 _urgu_uhow8_1"
}

CSS'da taom-karta qoldi, JavaScript'da esa karta.taomKarta. Shuning uchun CSS Modules loyihalarida ko'pincha class nomlarini CSS'da ham camelCase yozishadi: .taomKarta. Bu kursdagi kebab-case qoidasiga zid ko'rinadi — lekin bu faylning nomlari hech qachon HTML'da qo'lda yozilmaydi, ular JavaScript o'zgaruvchisidek ishlatiladi. Jamoa kelishuviga qarang.

4.2 TypeScript tiplari

TypeScript — JavaScript'ning turli tekshiruvli versiyasi (Nega TypeScript, 15-qism). U import karta from "./x.module.css" ni tushunishi uchun tip kerak. Vite buni o'zi beradi: Vite 8.3.1 paketidagi client.d.ts faylida *.module.css "kalitlari satr bo'lgan obyekt" (CSSModuleClasses) deb e'lon qilingan — tekshirdik. Faqat bu tip har qanday kalitga ruxsat beradi: karta.narxx (xato bilan) ham tekshiruvdan o'tadi. Aniq tiplar kerak bo'lsa, typed-css-modules kabi vositalar har modul uchun alohida tip fayli yasaydi.

4.3 Dinamik class'lar: clsx

Karta holatiga qarab class qo'shish kerak: taom tugagan bo'lsa — tugadi. Buni qulay qiladigan kichik kutubxona — clsx. Node'da tekshirdik (clsx 2.1.1):

js
import clsx from "clsx";

const styles = {
  "taom-karta": "_taom-karta_19o62_1",
  tugadi: "_tugadi_19o62_12",
};
const tugadi = true;
console.log(clsx(styles["taom-karta"], tugadi && styles.tugadi));
console.log(clsx(styles["taom-karta"], false && styles.tugadi));

Konsolda:

text
_taom-karta_19o62_1 _tugadi_19o62_12
_taom-karta_19o62_1

So'zlar bilan: clsx berilgan nomlarni bo'sh joy bilan birlashtiradi, false bo'lganlarini tashlab yuboradi. tugadi && styles.tugadi — "taom tugagan bo'lsa, tugadi class'i ham". React'da bu yozuvni har kuni ko'rasiz (React'da stil berish).

Tekshirib ko'ring: Nega class="${karta.narx} tugadi" deb yozish ishlamaydi, clsx(karta.narx, karta.tugadi) esa ishlaydi?

Javob

Birinchi yozuvda tugadi — qo'lda yozilgan oddiy nom. CSS'da esa .tugadi yo'q, u yerda hash'li ._tugadi_19o62_12 bor — xiralik qo'llanmaydi. Ikkinchi yozuvda ikkala nom ham lug'atdan olinadi, clsx ularni bo'sh joy bilan birlashtiradi. Qoida o'zgarmaydi: modul class'ining nomi doim lug'atdan.

5. Solishtirish va kamchiliklar

5.1 Uch yondashuv yonma-yon

BEM @scope CSS Modules
Kim kafolatlaydi Odam (kelishuv) Brauzer Build vositasi
JS kerakmi Yo'q Yo'q Ha (import)
HTML'da nom taom-karta__narx narx _narx_19o62_7
Qayerda ishlaydi Hamma joyda Yangi Baseline (2026) Vite, Next.js va boshqalar

@scope bilan farqni aniqroq ko'raylik. @scope (.taom-karta) { .narx { ... } } nomni o'zgartirmaydi — brauzer qoidani faqat karta ichidagi .narx ga qo'llaydi. Build ham, JavaScript ham kerak emas, HTML'da oddiy class="narx". Lekin @scope web-features ma'lumotiga ko'ra yangi Baseline (2026-yil mart) — eski brauzerlarda umuman ishlamaydi. Yana bir farq: @scope faqat qoidaning qayerda ishlashini chegaralaydi. Kartadan tashqaridagi boshqa .narx qoidasi esa kartaga baribir ta'sir qilishi mumkin. CSS Modules'da nom to'qnashuvi umuman bo'lmaydi.

Tekshirib ko'ring: «Bahor» — build'siz, oddiy HTML va CSS sayt. Menyu va aksiyadagi .narx to'qnashuvini qaysi yondashuv bilan hal qilasiz?

Javob

CSS Modules bu yerda ishlamaydi — build va JavaScript yo'q. Qoladi BEM (.taom-karta__narx, .aksiya__narx) yoki @scope. Hozircha eng ishonchlisi — kelishuv yoki zanjirli selektor (.aksiya .narx, CSS metodologiyalari darsidagi Sherzodning narxi mashqi kabi). @scope ni tanlasangiz, u yangi Baseline ekanini hisobga oling. CSS Modules — keyinroq, loyiha Vite'ga ko'chganda.

5.2 Kamchiliklari

  • Build shart. Oddiy HTML+CSS sayt (portfolio kabi) CSS Modules'dan foydalana olmaydi.
  • JS'siz HTML'da nom yo'q. Class'ni qo'lda yozib bo'lmaydi — nomni faqat lug'at biladi. Serverda HTML yasaydigan eski saytlar uchun noqulay.
  • Global stillar baribir kerak. Reset, body, shriftlar, CSS o'zgaruvchilari — oddiy global CSS'da qoladi.
  • Tashqaridan sozlash qiyin. Kutubxona komponentini ota komponentdan qayta bezash uchun uning hash'li nomini bilmaysiz. Yechim — CSS o'zgaruvchilari (CSS o'zgaruvchilari 2) yoki komponent className qabul qilishi.
  • Nomlar o'zgaradi. _narx_19o62_7 dagi 7 — qator raqami. Faylga yuqoridan qator qo'shsangiz, nom o'zgaradi. Testlarda yoki boshqa CSS'da hash'li nomga tayanmang.

5.3 Bugun qayerda

CSS Modules React ekotizimida 2015-yildan beri keng tarqalgan va hali ham Next.js'ning tavsiya etilgan variantlaridan biri. Muqobillari — Tailwind (Tailwind 1) va keyingi darsdagi CSS-in-JS. Uchalasini ham ish joyida uchratasiz.

6. Ko'p uchraydigan xatolar

6.1 .module unutilgan

Fayl taom-karta.css deb nomlangan va import karta from "./taom-karta.css" yozilgan. karta.narx — undefined, HTML'da class="undefined", stil qo'llanmaydi. Tuzatish: fayl nomi taom-karta.module.css.

6.2 Class nomini qo'lda yozish

<p class="narx"> — lekin CSS'da .narx yo'q, u yerda ._narx_19o62_7. Stil qo'llanmaydi. Tuzatish: nom doim lug'atdan: class="${karta.narx}".

6.3 Yakka element selektori

Modul faylda p { margin: 0; } — butun sayt paragraflariga tegdi. Tuzatish: .taom-karta p yoki paragrafga o'z class'i.

6.4 Chiziqchali nom va nuqta

karta.taom-karta — JavaScript buni ayirish deb o'qiydi va xato natija beradi. Tuzatish: karta["taom-karta"] yoki localsConvention: "camelCaseOnly" bilan karta.taomKarta.

6.5 Hash'li nomni boshqa joyda yozish

Boshqa CSS faylda yoki avtomatik testda ._narx_19o62_7 ni qo'lda yozdingiz. Ertasiga modul faylning boshiga bitta izoh qo'shildi — qator raqami o'zgardi, nom ._narx_19o62_8 bo'ldi va qoida jim ishlamay qoldi. Tuzatish: hash'li nomni hech qachon qo'lda ko'chirmang. Komponentni tashqaridan bezash kerak bo'lsa — CSS o'zgaruvchisi, testda esa matn yoki data- atribut bo'yicha qidiring (Atributlar va dataset).

7. Mashqlar

Bu mashqlar build vositasisiz bajariladi — natija fayllarni qo'lda "o'ynab" ko'rasiz. Vite loyihasida o'zingiz sinashni Vite I darsidan keyin qilasiz.

1-mashq (oson): nomni o'qing

Vite build qilingan saytda DevTools'da class="_bron-havola_k3p9a_14" ni ko'rdingiz. Uch bo'lakni tushuntiring. Manba faylni qanday topasiz?

Ishora: "Natija: haqiqiy build" bo'limidagi _narx_19o62_7 tahlili.

Yechim
  • bron-havola — asl class nomi. Loyihadan .bron-havola ni qidirasiz — u qaysidir *.module.css faylda.
  • k3p9a — shu fayl yo'lidan olingan hash. Bir xil hash'li boshqa class'lar ham shu fayldan.
  • 14 — manba fayldagi qator: .bron-havola qoidasi 14-qatorda.

Topish: VS Code'da Ctrl + Shift + F bilan .bron-havola ni qidiring, natijalardan .module.css bilan tugaganini oling va 14-qatorni tekshiring.

2-mashq (o'rta): nima sizib chiqadi?

menyu.module.css:

css
.menyu {
  display: grid;
  gap: 1rem;
}

.menyu a {
  text-decoration: none;
}

h2 {
  color: #2f6b3a;
}

:global(.aksiya) {
  color: #b4461a;
}

Build'dan keyin qaysi qoidalar faqat menyuga, qaysilari butun saytga ta'sir qiladi? Xavflisini tuzating.

Ishora: "Lokal va global" bo'limi — faqat class nomlari noyob qilinadi.

Yechim
  • .menyu va .menyu a — lokal: .menyu hash'li nom oladi, a faqat uning ichida tanlanadi.
  • h2 — global: saytdagi hamma h2 yashil bo'ladi. Bu xato.
  • :global(.aksiya) — ataylab global, hamma .aksiya ga. Agar bu menyuning ishi bo'lmasa — umumiy global CSS faylga ko'chirish kerak.

Tuzatilgan h2:

css
.menyu h2 {
  color: #2f6b3a;
}

3-mashq (qiyin): composes bilan tugma variantlari

tugma.module.css da uchta class kerak: .asos (padding, radius), .asosiy (yashil fon) va .xavfli (qizg'ish fon). .asosiy va .xavfli ikkalasi ham .asos ni qo'shib olsin. Faylni yozing va build'dan keyin lug'atda asosiy kaliti qanday qiymat olishini (hash'larni xxxxx deb) yozing.

Ishora: composes: asos; — qoida boshida. Bu class nomlari faqat shu mashq uchun (namoyish).

Yechim
css
.asos {
  padding: 0.5rem 1.5rem;
  border: 0;
  border-radius: 0.5rem;
}

.asosiy {
  composes: asos;
  background-color: #2f6b3a;
  color: #fffaf0;
}

.xavfli {
  composes: asos;
  background-color: #b4461a;
  color: #fffaf0;
}

Lug'atda (Vite 8.3.1 bilan tekshirdik, hash'lar sizda boshqa): asosiy: "_asosiy_qfgo3_7 _asos_qfgo3_1" — ikki nom: o'zining va .asos niki. Qator raqamlari — fayldagi joyiga qarab (.asos 1-qatorda, .asosiy 7-qatorda). HTML'da tugma class="${tugma.asosiy}" bilan ikkala class'ni oladi. CSS faylda padding bir marta yozilgan — nusxa yo'q.

4-mashq: Portfolio qadami — portfolio'ga CSS Modules kerakmi?

Portfolio'da JavaScript ham, build ham yo'q — CSS Modules'ni unda ishlatib bo'lmaydi. Shuning uchun bu qadam — tahlil: kelajakda (portfolio v2 Next.js'da, Next.js nima — 23-qism) qaysi qoidalar modulga, qaysilari global faylga tushishini hozirdan belgilab qo'yish.

sayt/assets/css/ dagi fayllaringizni (CSS metodologiyalari darsidagi bo'linish) ko'rib chiqing va jadval tuzing: har fayl — "global qoladi" yoki "komponent modulga". Komponentlardan bittasini — loyiha kartalarini — Loyihalar.module.css sifatida qanday yozilishini qog'ozda (faylda emas) ko'rsating.

Ishora: reset, tokenlar, body va sarlavhalar — butun sayt uchun. .loyihalar va uning ichidagi article — bitta sahifadagi bitta komponent.

Yechim
Fayl Qaror Nega
reset.css Global Hamma elementga
tokenlar.css Global :root o'zgaruvchilari hamma joyda kerak
asos.css Global html, body, sarlavha, havola
layout.css Global Sahifa skeleti (Next.js'da — layout faylida)
komponentlar.css Bo'linadi Menyu, non yo'li, kartalar, forma — har biri o'z moduliga
yordamchi.css Global .korinmas, chop etish

Loyihalar.module.css qanday bo'lardi (bir qismi):

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

.loyihalar > article {
  display: grid;
  grid-row: span 4;
  grid-template-rows: subgrid;
  row-gap: 0.5rem;
  padding: 1rem;
  border: 1px solid var(--rang-chegara);
  border-radius: 0.5rem;
}

Qiymatlar qisqalik uchun Dizayn tokenlari darsidan oldingi ko'rinishda. Sizning faylingizda ular allaqachon tokenlar (var(--masofa-m), var(--burchak-m)) — modulda ham xuddi shunday qoladi.

E'tibor bering: var(--rang-chegara) global tokenlardan keladi — CSS o'zgaruvchilari modul chegarasidan bemalol o'tadi, chunki ular class emas. .loyihalar > article xavfsiz: article faqat lokal .loyihalar ichida tanlanadi. Hozirgi komponentlar.css dagi details[name="savollar"] esa class'siz — modulga ko'chganda unga class kerak bo'lardi, aks holda u global qoladi.

Portfolio fayllarida bugun hech narsa o'zgarmaydi — npm run check oldingidek 0 xato.

8. Real ishda

  • React loyihalarida Button.module.css, Card.module.css — komponent fayli yonida o'z modul fayli. Next.js loyihasini ochsangiz, ko'pincha shunday tuzilmani ko'rasiz.
  • DevTools'da _narx_19o62_7 yoki Card_title__a1b2c kabi nomlarni ko'rsangiz — bu CSS Modules (yoki shunga o'xshash vosita). Asl nom — birinchi bo'lakda.
  • Katta jamoalarda CSS Modules'ning asosiy foydasi — qo'rqmasdan o'chirish. Komponent o'chirilsa, uning .module.css fayli ham o'chadi: bu class'larni boshqa hech kim ishlata olmaydi, chunki nomlar noyob. Global CSS'da esa "bu class boshqa joyda ishlatilganmi?" degan savol yillar davomida eski qoidalarni saqlab qoladi.
  • Intervyuda: "CSS Modules qanday muammoni hal qiladi?", "composes va Sass @extend farqi?", "Global stil qayerda turadi?" — endi javob bera olasiz.

Xulosa

  • CSS Modules — build vositasi .module.css dagi class nomlarini fayl bo'yicha noyob qiladi: .narx → _narx_19o62_7.
  • Nomlar JavaScript orqali lug'atdan olinadi: styles.narx; chiziqchali nom — styles["taom-karta"] yoki camelCase sozlamasi.
  • Faqat class'lar lokal; yakka element selektori butun saytga tegadi. :global() — ataylab global.
  • composes HTML'ga qo'shimcha class qo'yadi, CSS'ni nusxalamaydi.
  • Vite va Next.js'da sozlanmasdan ishlaydi; build va JS'siz saytda — yo'q. Muqobillari — BEM, @scope, Tailwind, CSS-in-JS.

Keyingi dars: CSS-in-JS: runtime va zero-runtime yondashuvlar — stilni to'g'ridan-to'g'ri JavaScript ichida yozish va uning narxi.

Manbalar

  • CSS Modules spetsifikatsiyasi — github.com/css-modules/css-modules
  • Vite: "CSS Modules" — vite.dev/guide/features
  • Next.js: "CSS Modules" — nextjs.org/docs
  • clsx — github.com/lukeed/clsx
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
CSS Modules: komponentga lokal class'lar — IlmHamroh