Specificity — qaysi stil ustunlik qiladi va nima uchun

~15 daq · CSS · CSS Asoslari

Muammodan boshlaylik

Siz tugma rangini o'zgartirdingiz:

.btn-primary {
  background: green;
}

Saqlaysiz, sahifani yangilaysiz — tugma hali ham ko'k. Keshni tozalaysiz — ko'k. Faylni tekshirasiz — qoida joyida. Nima bo'lyapti?

DevTools ni ochasiz (1-dars) va ko'rasiz: sizning qatoringiz chizib tashlangan, tepada esa:

#checkout-form .actions button.btn-primary {
  background: blue;
}

Bu qoida aniqroq — va u yutadi. Ko'p dasturchilar shu yerda !important yozib, muammoni "hal qiladi" — va kelajakdagi o'zlariga katta muammo tashlab ketadi. To'g'ri yo'l — specificity qanday hisoblanishini tushunish.


Specificity — "aniqlik bali"

Bitta elementga bir nechta qoida mos kelsa, brauzer har bir selektorning aniqlik balini hisoblaydi. Bal uchta raqamdan iborat:

(ID, CLASS, TEG)
Ustun Nima sanaladi
ID #header
CLASS .btn, [type="text"] (attribute), :hover (pseudo-class)
TEG div, p, ::before (pseudo-element)

* va kombinatorlar (>, +, ~, bo'shliq) — 0.

Misollar

Selektor Bal
p (0, 0, 1)
.btn (0, 1, 0)
p.izoh (0, 1, 1)
.menu a (0, 1, 1)
.btn:hover (0, 2, 0)
#header (1, 0, 0)
#header .nav a (1, 1, 1)
#checkout-form .actions button.btn-primary (1, 2, 1)

Taqqoslash — chapdan o'ngga

Ballar ustunma-ustun, chapdan boshlab solishtiriladi — xuddi so'zlarni alifbo bo'yicha solishtirgandek:

(1, 0, 0)  >  (0, 15, 0)     ← bitta ID har qancha class dan kuchli
(0, 2, 0)  >  (0, 1, 9)      ← ikkita class to'qqizta tegdan kuchli
(0, 1, 1)  >  (0, 1, 0)      ← class teng — teg hal qiladi

[!INFO] Bu o'nlik son emas: 11 ta class (0, 11, 0) bitta ID (1, 0, 0) ni yengmaydi. Har bir ustun mustaqil — yuqori ustundagi bitta birlik pastdagi har qanday miqdordan kuchli.

Darsning boshidagi muammo: .btn-primary = (0, 1, 0), uning raqibi (1, 2, 1). ID ustunida 1 > 0 — raqib yutadi.


To'liq ustunlik tartibi

Brauzer ziddiyatni shu tartibda hal qiladi (1-darsdagi kaskad):

1. !important                         ← eng kuchli (ishlatmang!)
2. Inline stil  style="..."           ← (1, 0, 0, 0) — har qanday selektordan kuchli
3. Specificity — (ID, CLASS, TEG)
4. Tartib — keyinroq yozilgani yutadi ← bal teng bo'lganda
<p class="izoh" style="color: purple">Matn</p>
#content p.izoh { color: red; }   /* (1, 1, 1) — baribir yutqazadi */

Inline style — binafsha. Shuning uchun inline stillar keyinchalik o'zgartirish uchun juda noqulay (1-dars).

Meros — eng kuchsiz

body { color: black; }
<body>
  <p>Qora</p>
</body>

Meros orqali kelgan qiymatning specificity si yo'q — har qanday to'g'ridan-to'g'ri qoida, hatto * (0, 0, 0) ham uni yengadi.


!important — nega yomon

.btn-primary {
  background: green !important;
}

Endi bu qoida specificity dan qat'i nazar yutadi. Muammo "hal bo'ldi"... Bir oydan keyin:

.btn-primary.btn-small {
  background: yellow;     /* ishlamaydi! */
}
.btn-primary.btn-small {
  background: yellow !important;   /* endi ishlaydi... */
}

!important urushlari boshlanadi: har bir yangi !important keyingisini talab qiladi, va oxir-oqibat CSS ni boshqarib bo'lmaydi.

Qachon oqlanadi:

  • Utility class lar, ular har doim yutishi kerak: .hidden { display: none !important; }
  • Tashqi kutubxonaning o'zgartirib bo'lmaydigan inline stillarini yengish
  • Foydalanuvchi stillari (accessibility)

Qolgan barcha holatlarda — specificity ni to'g'ri boshqaring.


Specificity ni to'g'ri boshqarish

1. Past va tekis specificity

/* ❌ */
#sidebar ul li a.active { ... }      /* (1, 1, 3) */

/* ✅ */
.sidebar-link.is-active { ... }      /* (0, 2, 0) */

Agar deyarli barcha selektorlaringiz (0, 1, 0) yoki (0, 2, 0) bo'lsa — ularni o'zgartirish oson: kerakli qoidani keyinroq yozish yoki bitta class qo'shish yetarli. Shu sababli ID lar stil uchun ishlatilmaydi (2-dars).

2. Tartibdan foydalaning

Bal teng bo'lsa — keyingisi yutadi. CSS faylni umumiydan xususiyga tartiblang:

/* 1. Reset va bazaviy */
a { color: #2563eb; }

/* 2. Komponentlar */
.btn { background: #e2e8f0; }
.btn-primary { background: #2563eb; }

/* 3. Holatlar va utility lar */
.is-disabled { opacity: 0.5; }

3. Specificity ni oshirish kerak bo'lsa — class bilan

.btn.btn-primary { ... }   /* (0, 2, 0) — ID qo'shishdan ko'ra yaxshiroq */

4. Pasaytirish — :where()

:where(.card) a { color: inherit; }   /* (0, 0, 1) — :where ichidagisi 0 */

:where() ichidagi hamma narsaning specificity si nol. Kutubxonalar va bazaviy stillar uchun ideal: foydalanuvchi ularni osongina o'zgartira oladi. Uning "egizagi" :is() esa ichidagi eng yuqori balni oladi.

5. Cascade layers — @layer

@layer reset, base, components, utilities;

@layer components {
  #header .btn { background: blue; }   /* (1, 1, 0) */
}

@layer utilities {
  .bg-green { background: green; }     /* (0, 1, 0) — baribir yutadi! */
}

Qatlamlar specificity dan oldin tekshiriladi: keyingi qatlam oldingisidan har doim kuchli. Katta loyihalarda tartibni nazorat qilishning zamonaviy usuli.


Tashxis: "stilim ishlamayapti"

  1. DevTools → element → Styles: qoidangiz bormi? Chizilganmi?
  2. Chizilgan bo'lsa — uni yutgan qoidani toping (ro'yxatda tepada). Specificity ni solishtiring
  3. Qoida umuman yo'q bo'lsa — selektor elementga mos kelmayapti (class nomida xato?) yoki fayl ulanmagan, yoki oldingi qatorda sintaksis xatosi (; yo'q)
  4. Yechim: selektorni aniqlashtiring, tartibni o'zgartiring yoki raqib qoidaning specificity sini pasaytiring — !important emas

[!TIP] DevTools da selektor ustiga sichqonchani olib borsangiz, ko'p brauzerlar uning specificity sini ko'rsatadi: Specificity: (1, 2, 1).


Nima uchun shunday?

Nima uchun CSS ziddiyatlarni "aniqlik" bo'yicha hal qiladi — shunchaki keyingi qoida yutsa sodda bo'lmasmidi?

Chunki "aniqroq" qoida odatda "muhimroq" niyatni bildiradi. p — "barcha paragraflar", .izoh — "izoh paragraflari", #ogohlantirish — "aynan shu paragraf". Agar faqat tartib hal qilsa, umumiy qoidani faylning oxiriga qo'yish (yoki boshqa faylni keyinroq ulash) barcha xususiy holatlarni jimgina buzar edi. Specificity bu xavfni kamaytiradi: umumiy qoidalar xususiylarni tasodifan yeng olmaydi. Lekin bu kuch ehtiyotkorlikni talab qiladi — yuqori specificity "beton" ga aylanadi. Shuning uchun zamonaviy yondashuv: past va bir xil specificity, tartib va @layer bilan boshqarish.


Xulosa

Eslab qoling:

  • Specificity — (ID, CLASS, TEG); chapdan o'ngga solishtiriladi
  • CLASS ustuni: class, attribute, pseudo-class; TEG: teg, pseudo-element; * va kombinatorlar — 0
  • Bitta ID har qancha class dan kuchli — bu o'nlik son emas
  • Tartib: !important → inline → specificity → keyingisi yutadi; meros — eng kuchsiz
  • !important — faqat utility lar va istisnolar uchun
  • Past va tekis specificity: class lar, ID siz, qisqa selektorlar
  • :where() — nol specificity; @layer — qatlamlar bilan tartib
  • Muammo bo'lsa — DevTools dagi chizilgan qatorga qarang

Keyingi dars

6-dars: CSS o'zgaruvchilar — Custom Properties, var()