BEM — Block Element Modifier metodologiyasi
Muammodan boshlaylik
Loyiha boshida CSS fayl 200 qator, hammasi tushunarli. Bir yildan keyin — 5000 qator va uch dasturchi:
.title { font-size: 24px; } /* qaysi title? */
.card .title { font-size: 18px; }
.sidebar .card .title { font-size: 14px; }
.header .nav .list .item .link.active { color: blue; } /* 5-dars: specificity (0, 6, 0) */
.active { color: red !important; } /* kimdir urushda yutqazdi */
Muammolar:
- Nomlar to'qnashadi:
.titlesahifaning o'nta joyida, har biri boshqacha - Specificity urushlari (5-dars): har bir yangi qoida oldingisini yengish uchun uzunroq
- O'chirishdan qo'rqish: "bu class qayerda ishlatiladi?" — hech kim bilmaydi, shuning uchun hech narsa o'chirilmaydi
- Ko'chirish imkonsiz: kartochkani boshqa sahifaga ko'chirsangiz — uning stillari
.sidebarichida bo'lgani uchun buziladi
Bu muammolarning ildizi — nomlash. BEM — CSS class larini nomlashning qat'iy, oddiy qoidalari.
Uch tushuncha
BEM — Block, Element, Modifier.
Block — mustaqil komponent
.card { }
.header { }
.search-form { }
O'z-o'zidan ma'noga ega, sahifaning istalgan joyiga ko'chirilishi mumkin bo'lgan qism. Nomi — vazifasi bo'yicha (2-dars: .btn-danger, .red-button emas).
Element — blokning qismi
.card__image { }
.card__title { }
.card__price { }
Blokdan tashqarida ma'nosi yo'q qism. Yozilishi: blok__element — ikkita pastki chiziq.
Modifier — variant yoki holat
.card--featured { } /* blok varianti */
.btn--primary { }
.btn--large { }
.card__title--small { } /* element varianti */
Ko'rinish yoki xatti-harakatning o'zgarishi. Yozilishi: blok--modifier yoki blok__element--modifier — ikkita chiziqcha.
To'liq misol
<article class="card card--featured">
<img class="card__image" src="noutbuk.jpg" alt="Noutbuk">
<div class="card__body">
<h3 class="card__title">Noutbuk Pro 14</h3>
<p class="card__price card__price--sale">12 500 000 so'm</p>
<button class="btn btn--primary btn--small">Savatga</button>
</div>
</article>
.card {
border: 1px solid #e2e8f0;
border-radius: 12px;
overflow: hidden;
}
.card--featured {
border-color: #f59e0b;
box-shadow: 0 0 0 3px rgb(245 158 11 / 0.2);
}
.card__image {
width: 100%;
aspect-ratio: 4 / 3;
object-fit: cover;
}
.card__body {
padding: 16px;
}
.card__title {
font-size: 1.125rem;
}
.card__price--sale {
color: #dc2626;
}
.btn { padding: 10px 20px; border-radius: 8px; }
.btn--primary { background: #2563eb; color: white; }
.btn--small { padding: 6px 12px; font-size: 0.875rem; }
Bir qarashda: HTML da class nomining o'zidan element qaysi komponentga tegishli ekani va qanday holatda ekani ko'rinadi. CSS da esa barcha selektorlar — bitta class.
Asosiy qoidalar
1. Faqat class — ichma-ich selektorlarsiz
/* ❌ */
.card h3 { }
.card .title { }
/* ✅ */
.card__title { }
Hamma selektorning specificity si (0, 1, 0) — 5-darsdagi "past va tekis specificity" o'z-o'zidan ta'minlanadi. Tartib va modifier lar har doim kutilganday ishlaydi.
2. Element — doim blokka bog'lanadi, ichma-ich emas
<div class="card">
<div class="card__body">
<h3 class="card__title">...</h3> <!-- ✅ card__body__title EMAS -->
</div>
</div>
card__body__title — xato. HTML qanchalik chuqur bo'lmasin, element nomi — blok__element. HTML tuzilmasi o'zgarsa (yana bitta div qo'shilsa) — class nomlari o'zgarmaydi.
3. Modifier — asosiy class bilan birga
<button class="btn btn--primary"> <!-- ✅ -->
<button class="btn--primary"> <!-- ❌ asosiy stillar yo'q -->
Modifier faqat farqni saqlaydi; asosiy stillar .btn da.
4. Ichki blok — o'z nomi bilan
Kartochka ichidagi tugma — kartochkaning elementi emas, mustaqil .btn bloki. Lekin kartochka ichida joylashuvi kerak bo'lsa — aralash (mix):
<button class="btn btn--primary card__action">Savatga</button>
.btn— tugma qanday ko'rinadi (o'zining blok stillari).card__action— kartochka ichida qayerda turadi (margin, joylashuv)
Tugmaning o'zi kartochkadan mustaqil qoladi.
Holatlar
Vaqtinchalik holatlar (ochiq, faol, yuklanmoqda) uchun ikki yondashuv:
.menu__item--active { } /* BEM modifier */
.menu__item.is-active { } /* "is-" yoki "has-" prefiksli holat class i (SMACSS uslubi) */
.menu__item[aria-current="page"] { } /* ARIA atributi — eng yaxshisi, agar mavjud bo'lsa */
ARIA atributlari (aria-expanded, aria-current, aria-selected) — ham stil uchun, ham ekran o'quvchilar uchun: bitta manba, ikki foyda.
BEM va zamonaviy vositalar
BEM 2010-yillarda Yandex da yaratilgan. Bugun xuddi shu muammolarni hal qiladigan boshqa yondashuvlar ham bor:
| Yondashuv | Qanday hal qiladi |
|---|---|
| BEM | Nomlash qoidalari — qo'shimcha vosita kerak emas |
| CSS Modules | Build vositasi class nomlarini avtomatik noyob qiladi (.title → .Card_title_x7f2) |
| Tailwind CSS | Utility class lar to'g'ridan-to'g'ri HTML da: class="p-4 rounded-lg border" |
| Scoped styles (Vue, Svelte) | Komponent stillari faqat shu komponentga tegishli |
@scope (yangi CSS) |
Stillarni DOM qismiga cheklash |
Freymvork va build vositalarisiz oddiy CSS yozganda (bu DevDocs saytining ko'p qismi kabi) — BEM eng sodda va ishonchli tanlov. Va boshqa yondashuvlardan foydalanganda ham BEM ning g'oyalari — komponentlar, past specificity, ma'noli nomlar — o'z kuchini saqlaydi.
Nima uchun shunday?
Nima uchun BEM nomlari bunchalik uzun va "xunuk" — card__price--sale o'rniga .sale qisqaroq emasmi?
Chunki qisqa nomlar global — va CSS da hamma class lar global. .sale bugun sizning kartochkangizda, ertaga boshqa dasturchi uni bannerda boshqa ma'noda ishlatadi va ikkalasi bir-birini buzadi. Uzun nom — bu nomlar fazosi (namespace): card__price--sale faqat bitta narsani anglatadi va boshqa hech narsa bilan to'qnashmaydi. Bundan tashqari, uzunlik o'zi ma'lumot beradi: HTML ni ochib, CSS faylga qaramasdan, har bir element qaysi komponentga tegishli va qanday holatda ekanini bilasiz. Yozishda bir necha harf ko'p — lekin bir yildan keyin "bu class ni o'chirsam nima buziladi?" degan savolga darhol javob bera olasiz. Katta loyihada bu soatlab tejalgan vaqt.
Xulosa
Eslab qoling:
- Block — mustaqil komponent:
.card - Element — blok qismi, ikkita pastki chiziq:
.card__title - Modifier — variant/holat, ikkita chiziqcha:
.card--featured,.btn--primary - Faqat bitta class li selektorlar — specificity doim (0, 1, 0)
- Element nomi —
blok__element, HTML chuqurligidan qat'i nazar (card__body__titleemas) - Modifier — asosiy class bilan birga:
class="btn btn--primary" - Ichki blok — o'z nomi + joylashuv uchun aralash:
class="btn card__action" - Holatlar — modifier,
is-class yoki ARIA atributlari
Kurs yakuni
Tabriklaymiz — siz CSS kursini tugatdingiz! Endi siz:
- Kaskad, specificity va meros qanday ishlashini tushunasiz va "stil nega ishlamayapti?" savoliga DevTools da javob topasiz
- Box model, birliklar va tipografiya bilan o'qilishi oson, toza sahifalar yasaysiz
- Flexbox va Grid bilan har qanday layoutni qurasiz — header dan dashboard gacha
position,z-indexva stacking context bilan ustma-ust elementlarni boshqarasiz- Mobile First va fluid qiymatlar bilan har qanday ekranga moslashadigan sayt yasaysiz
- Silliq va tez animatsiyalar yozasiz, foydalanuvchi sozlamalarini hurmat qilgan holda
- Zamonaviy selektorlar, funksiyalar va BEM bilan katta loyihada ham tartibli CSS yozasiz
Keyingi qadamlar
- Amaliyot: sevimli saytingizdan bitta sahifani noldan takrorlab ko'ring — eng yaxshi mashq
- Flexbox Froggy va Grid Garden — o'yin shaklidagi mashqlar
- JavaScript kursi — sahifalarga hayot qo'shish
- React kursi — komponentlar bilan katta interfeyslar
- MDN Web Docs — har bir CSS xususiyati bo'yicha eng ishonchli ma'lumotnoma