IlmHamroh
JavaScript Full-stack/5-qism. CSS asoslari va layout4/63-dars21 daqiqa
Mundarija (41)

CSS pseudo-klasslari: hover, focus-visible va forma holatlari

Qisqacha: Pseudo-klass elementni hozirgi holatiga qarab tanlaydi: a:hover — ustida sichqoncha turgan havola, input:checked — belgilangan tugma. Bu holatlarni HTML'ga hech kim yozmaydi — brauzer ularni o'zi kuzatadi. Klaviatura fokusini :focus-visible bilan bezang va outline ni o'rniga boshqasini bermasdan hech qachon o'chirmang. Forma xatosini :invalid bilan emas, :user-invalid bilan ko'rsating: u mehmon maydon bilan ishlab bo'lgach yoki yuborishga uringach yonadi.

Bu darsda

  • Pseudo-klass nima ekanini va u qanday yozilishini tushuntira olasiz.
  • Havola va tugmaga :hover, :active, :focus-visible holatlarini berasiz va LVHA tartibini bilasiz.
  • :visited nega cheklanganini va unda qaysi xususiyatlar ishlashini aytasiz.
  • Forma maydonlarini :checked, :disabled, :user-invalid bilan bezaysiz.
  • :target, :lang(), :dir() va :defined qachon kerakligini bilasiz.

Oldin bilishingiz kerak: Atribut selektorlari, Klaviatura va fokus boshqaruvi, Brauzer validatsiyasi, Qulay va accessible forma.

1. Nega bu kerak?

O'tgan darsda holatni atribut bo'yicha bezadik: details[open], [aria-current="page"], [aria-invalid="true"]. Bu holatlar HTML'da yozilgan edi. Brauzer yoki dasturchi atributni qo'yadi, CSS esa uni o'qiydi.

Lekin ba'zi holatlar HTML'da umuman yo'q:

  • sichqoncha hozir qaysi havola ustida turibdi?
  • mehmon hozir qaysi maydonga yozyapti?
  • qaysi radio tugma tanlangan?
  • telefon raqami to'g'ri kiritilganmi?

Bularni hech kim atribut qilib yozmaydi. Ular har soniyada o'zgaradi va ularni faqat brauzer biladi.

Taksi tepasidagi "bo'sh" chirog'ini eslang. Haydovchi har safar yozuv yopishtirib o'tirmaydi. Mashina bo'sh bo'lsa, chiroq o'zi yonadi, yo'lovchi o'tirsa — o'zi o'chadi. CSS'da ham shunday "chiroqlar" bor. Brauzer ularni o'zi yoqadi va o'chiradi, siz esa "chiroq yonganda element qanday ko'rinsin" deb yozasiz.

«Bahor» menyusi va bron havolasi. Sichqonchani havolalar ustiga olib boring, tugmani bosib turing:

html
<style>
  nav a {
    color: #2f6b3a;
  }
  nav a:hover {
    color: #b4461a;
  }
  .bron-havola {
    background-color: #2f6b3a;
    color: #ffffff;
    padding: 8px 16px;
  }
  .bron-havola:hover {
    background-color: #1a5d1a;
  }
  .bron-havola:active {
    background-color: #1f2a24;
  }
</style>
<nav aria-label="Asosiy menyu">
  <a href="menyu/">Menyu</a> ·
  <a href="aloqa/">Aloqa</a>
</nav>
<p><a class="bron-havola" href="bron/">Stolni band qilish</a></p>

Nimaga qarang: sichqoncha tekkan havola qizg'ish bo'ladi, uzoqlashganda yashilga qaytadi. "Stolni band qilish" ustida to'qroq yashil, bosib turganingizda esa deyarli qora. HTML'da hech narsa o'zgarmadi — holatni brauzer kuzatdi.

2. Pseudo-klass qanday yoziladi

2.1 Bitta ikki nuqta

Pseudo-klass (pseudo-class) — elementni nomi yoki atributi bo'yicha emas, hozirgi holati bo'yicha tanlaydigan selektor qismi. "Pseudo" — "go'yo": u class kabi ishlaydi, lekin HTML'da bunday class yozilmagan.

Yozilishi: selektor, bitta ikki nuqta va holat nomi — bo'sh joysiz. a:hover, .bron-havola:active, [aria-current="page"]:hover. Pseudo-klass selektorga xuddi .taom-karta.mashhur dagi ikkinchi class kabi yopishadi (Asosiy selektorlar).

Diqqat: nav a:hover va nav a :hover — boshqa-boshqa selektorlar. Bo'sh joy — avlod kombinatori. Ikkinchisi "havola ichidagi, ustida sichqoncha turgan element" degani. Havola ichida boshqa teg bo'lmasa, u hech narsani topmaydi — Chrome'da tekshirdik, rang o'zgarmadi.

Og'irligi bo'yicha pseudo-klass class bilan teng. To'qnashuvda qaysi qoida yutishini Specificity darsida hisoblaymiz.

2.2 Pseudo-klasslar oilasi

Guruh Pseudo-klasslar Nima haqida
Foydalanuvchi harakati :hover :active :focus :focus-visible :focus-within Sichqoncha, bosish, klaviatura
Havolalar :link :visited :any-link :target Havola va manzil
Forma :checked :disabled :required :user-invalid va boshqalar Maydon holati
Til va teglar :lang() :dir() :defined Matn tili, yo'nalish, maxsus teg

Yana ikki oila bor: elementning o'rni bo'yicha (Tuzilma pseudo-klasslari) va selektorlarni birlashtiruvchi (Mantiqiy pseudo-klasslar).

Ba'zi pseudo-klasslar qavs bilan yoziladi — :lang(en): qavs ichida qiymat beriladi. Ularni dars oxiriga yaqin ko'ramiz.

Jadvalni yodlash shart emas. Har birini alohida, misol bilan ko'rib chiqamiz — jadval esa keyin qaytib qarash uchun.

3. Sichqoncha: :hover va :active

3.1 Ikki holat

  • :hover — kursor element ustida turibdi. Istalgan elementda ishlaydi, nafaqat havolada: .taom-karta:hover ham to'g'ri.
  • :active — element hozir bosilyapti: sichqoncha tugmasi bosilgan, hali qo'yib yuborilmagan. Chrome'da tekshirdik: tugma qo'yib yuborilgan zahoti holat o'chadi.

Tugma bosilganda "botib ketgandek" ko'rinishi :active dan keladi. U mehmonga "bosilganingizni sezdim" deydi. Holatlar orasidagi silliq o'tishni Transition darsida qo'shamiz.

3.2 Telefonda sichqoncha yo'q

Sensorli ekranda kursor yo'q. Barmoq tekkanda brauzer :hover ni qisqa yoqadi, ba'zan esa u "yopishib" qoladi (Mobil qurilma tuzoqlari).

Qoida: :hover — faqat qo'shimcha bezak. Narx, tugma yoki muhim matnni faqat sichqoncha kelganda ko'rsatmang. Sensorli qurilmani CSS'da aniqlashni Foydalanuvchi afzalliklari darsida o'rganamiz.

3.3 Holatni DevTools'da "qotirish"

Sichqonchani DevTools'ga olib borsangiz, hover holati o'chadi. Yechim: Elements panelida elementni tanlang va Styles bo'limidagi :hov tugmasini bosing. Ro'yxatda :hover yoki :focus ni belgilasangiz, element o'sha holatda "qotib" qoladi.

Qolgan imkoniyatlar — DevTools'da CSS darsida.

Tekshirib ko'ring: .taom-karta:hover { background-color: #fffaf0; } yozildi. Sichqoncha kartaning ichidagi narx ustida turibdi. Karta hover holatidami?

Javob

Ha. Kursor bolaning ustida bo'lsa, uning hamma otalari ham hover holatida bo'ladi. Chrome'da tekshirdik: narx ustida turganda :hover narxga, paragrafga, kartaga, body ga va html ga birdan tushdi. Shuning uchun karta ichida qayerga kelsangiz ham, butun karta foni o'zgaradi.

4.1 Ochilgan va ochilmagan havola

  • :link — mehmon hali ochmagan manzilga havola.
  • :visited — mehmon avval ochgan manzilga havola. Brauzer buni o'z tarixidan biladi.
  • :any-link — ikkalasi birga: href i bor har qanday havola.

Chrome'da tekshirdik: href siz <a> teg bu uchalasining hech biriga tushmaydi. U havola emas, oddiy matn.

:visited maqolalar ro'yxatida foydali: «Bahor» blogida (blog/) o'qilgan maqola havolasi kulrangroq bo'lsa, mehmon nimani o'qiganini darhol ko'radi.

4.2 :visited — qattiq cheklangan holat

:visited da hamma xususiyat ishlamaydi. MDN ro'yxati bo'yicha faqat rang xususiyatlari ruxsat etilgan:

  • color, background-color;
  • border-color va har tomoni alohida (border-top-color va boshqalar);
  • outline-color, column-rule-color, text-decoration-color, text-emphasis-color;
  • SVG uchun fill va stroke.

font-weight, font-size yoki fon rasmi :visited da jimgina e'tiborsiz qoladi. Rangning shaffofligi ham hisobga olinmaydi. background-color esa oddiy holatda ham fon rangi berilgan bo'lsagina o'zgaradi.

Nega bunchalik qattiq? Javob — mehmonning maxfiyligi. Buni dars oxiridagi "Hujumchi nigohi" bo'limida ko'ramiz.

4.3 LVHA: tartib muhim

Bitta havolaga bir vaqtda bir necha holat mos kelishi mumkin. Ochilmagan havola ustida sichqoncha tursa — u ham :link, ham :hover. Ikki qoida ham mos va ikkalasi ham rang beradi. Og'irligi teng bo'lgani uchun kodda pastroqda turgani yutadi (Kaskad).

Buni sinab ko'ramiz. header dagi va footer dagi havolalarga bir xil ikki qoida berildi, faqat tartibi boshqacha:

html
<style>
  header a:hover { color: #b4461a; }
  header a:link { color: #2f6b3a; }

  footer a:link { color: #2f6b3a; }
  footer a:hover { color: #b4461a; }
</style>
<header>
  <p>Tepada: <a href="https://example.com/menyu">Menyu</a></p>
</header>
<footer>
  <p>Pastda: <a href="https://example.com/aloqa">Aloqa</a></p>
</footer>

Nimaga qarang: ikkala havola ustiga ham sichqonchani olib boring. Pastdagi "Aloqa" qizg'ish bo'ladi, tepadagi "Menyu" esa yashilligicha qoladi. Chrome'da tekshirdik: header da :link qoidasi pastda turibdi va :hover ni doim bosib ketadi.

To'g'ri tartib — Link, Visited, Hover, Active. Dasturchilar uni inglizcha "LoVe HAte" ("sevgi va nafrat") deb eslab qolishadi:

css
a:link { color: #2f6b3a; }
a:visited { color: #5b6660; }
a:hover { color: #b4461a; }
a:active { color: #1f2a24; }

Mantiq oddiy: umumiy holatlar tepada, vaqtincha holatlar pastda. :hover ochilgan havolada ham, ochilmaganida ham ishlashi kerak. Shuning uchun u :link va :visited dan keyin turadi. :active esa eng qisqa holat, u oxirida. :focus-visible odatda :hover bilan birga yoziladi — uni keyingi bo'limda ko'ramiz.

Tekshirib ko'ring: a:visited { color: #5b6660; font-weight: bold; } qoidasidan ochilgan havolada nima qo'llanadi?

Javob

Faqat rang. font-weight :visited uchun ruxsat etilgan ro'yxatda yo'q — brauzer uni e'tiborsiz qoldiradi. Aks holda ochilgan havola kengayib, qo'shni matnni surib yuborardi va buni o'lchab, mehmon qaysi saytlarda bo'lganini bilib olish mumkin bo'lardi.

5. Klaviatura fokusi

5.1 :focus va :focus-visible

Klaviatura va fokus boshqaruvi darsida ikki holatni farqlagan edik:

  • :focus — element fokusda, u qanday kelganidan qat'i nazar.
  • :focus-visible — element fokusda va brauzer "halqani ko'rsatish kerak" deb hisoblaydi.

Chrome'da yana bir bor tekshirdik. Sichqoncha bilan bosilgan tugma faqat :focus bo'ldi. Tab bilan kelingan tugma esa :focus-visible ham bo'ldi. Matn maydoni sichqoncha bilan bosilganda ham :focus-visible — unga yozish uchun qaysi maydon faolligini ko'rish kerak.

O'sha darsda va'da berilgan CSS mana. Tab tugmasini bosib, maydon va tugmalar bo'ylab yuring:

html
<style>
  :focus-visible {
    outline: 3px solid #1a5d1a;
    outline-offset: 2px;
  }
</style>
<p>
  <label for="ism">Ismingiz</label>
  <input id="ism" name="ism" type="text">
</p>
<button type="button">Tozalash</button>
<button type="submit">Stolni band qilish</button>

Nimaga qarang: Tab bilan kelgan har bir element atrofida qalin to'q yashil halqa paydo bo'ladi. Tugmani sichqoncha bilan bossangiz, halqa chiqmaydi — :focus-visible shunday ishlaydi. Maydonni bossangiz esa chiqadi.

outline — elementni surmaydigan, joy egallamaydigan chiziq (Asosiy selektorlar darsidagi * misolini eslang). outline-offset — halqa va element orasidagi bo'sh joy: halqa element chetiga yopishib qolmaydi. Ikkalasini Chegara va soyalar darsida to'liq o'rganamiz. #1a5d1a — «Bahor»ning to'q yashili, oq fonda 7.7:1 kontrast beradi.

5.2 outline: none — faqat o'rnini bosuvchi bilan

Internetda ko'p uchraydigan qator:

css
/* ❌ klaviaturadagi odam "kursorsiz" qoladi */
:focus {
  outline: none;
}

Brauzer uchun bu to'g'ri qoida. Lekin Bobur kabi faqat klaviatura bilan ishlaydigan mehmon endi qayerda turganini ko'rmaydi. WCAG'ning 2.4.7 mezoni (Focus Visible) klaviatura fokusi doim ko'rinib turishini talab qiladi — o'rnini bosuvchisiz outline: none uni buzadi.

Qoida: brauzer halqasi dizaynga mos kelmasa, uni o'chirmang — almashtiring: o'z outline ingiz, qalin ramka yoki fon. Eng oddiy yo'l — yuqoridagi :focus-visible qoidasi. Fokus dizaynining to'liq qoidalarini CSS'da accessibility darsida ko'ramiz.

5.3 :focus-within — ichida fokus bor

:focus-within — elementning o'zi yoki uning ichidagi biror narsa fokusda. Formada bu "hozir qaysi qator bilan ishlayapman" degan belgi bo'ladi:

html
<style>
  form div {
    padding: 4px 8px;
  }
  form div:focus-within {
    background-color: #fffaf0;
  }
</style>
<form action="https://example.com/bron" method="post">
  <div>
    <label for="ism">Ismingiz</label>
    <input id="ism" name="ism" type="text">
  </div>
  <div>
    <label for="telefon">Telefon raqamingiz</label>
    <input id="telefon" name="telefon" type="tel">
  </div>
</form>

Nimaga qarang: maydonni bossangiz, uning butun qatori — label bilan birga — qaymoq rangga kiradi. Chrome'da tekshirdik: :focus-within fokus olgan elementning hamma otalariga tushadi — div ga ham, form ga ham, body ga ham. Shuning uchun selektorni aniq yozdik: form div.

Tekshirib ko'ring: Stajyor "maydon fokusda bo'lganda uning label i yashil bo'lsin" deb input:focus + label { color: #2f6b3a; } yozdi. «Bahor» formasida ishlamadi. Nega?

Javob

«Bahor» formasida label maydondan oldin turadi. + esa faqat oldinga qaraydi: "input dan keyingi label" ni qidiradi va topmaydi. Hozircha yechim — otani tanlash: div:focus-within label. Keyingi darslardan birida bundan ham aniqroq yo'lni — :has() ni (Mantiqiy pseudo-klasslar) ko'rasiz.

6. Forma holatlari

6.1 :checked — tanlangan variant

:checked — belgilangan checkbox yoki radio tugma, shuningdek tanlangan option. «Bahor» formasidagi "Qayerda o'tirasiz?" guruhida radio tugma yorlig'idan oldin turadi. Demak, + bu yerda ishlaydi:

html
<style>
  input:checked + label {
    color: #2f6b3a;
    font-weight: bold;
  }
</style>
<fieldset>
  <legend>Qayerda o'tirasiz?</legend>
  <div>
    <input id="joy-zal" name="joy" type="radio"
           value="zal" checked>
    <label for="joy-zal">Umumiy zal</label>
  </div>
  <div>
    <input id="joy-ayvon" name="joy" type="radio"
           value="ayvon">
    <label for="joy-ayvon">Ayvon (ochiq havoda)</label>
  </div>
</fieldset>

Nimaga qarang: tanlangan joyning yorlig'i yashil va qalin. "Ayvon" ni bossangiz, belgi unga ko'chadi. Tugmaning o'zini bezash — rangini brend rangiga o'zgartirish — Forma elementlarini zamonaviy stillash darsida.

6.2 Boshqa forma holatlari

Qolgan forma holatlari bir xil qolipda ishlaydi: HTML'dagi atribut yoki maydon qiymati — "chiroq"ni yoqadi. Ularni ro'yxat qilib beramiz — yodlash shart emas, kerak bo'lganda qaytib qarang:

Pseudo-klass Qachon yonadi «Bahor» misoli
:disabled / :enabled disabled bor / yo'q band vaqt option
:read-only / :read-write tahrirlab bo'lmaydi / bo'ladi readonly narx maydoni
:required / :optional required bor / yo'q ism va izoh maydoni
:placeholder-shown maydon bo'sh, placeholder ko'rinib turibdi izoh maydoni
:default sukut bo'yicha tanlangan checked radio
:indeterminate checkbox na belgilangan, na bo'sh "hammasini tanlash"
:in-range / :out-of-range qiymat min–max ichida / tashqarisida mehmonlar soni 25

Chrome'da ikki kutilmagan narsa topdik: :read-only disabled maydonga, radio va checkbox'ga ham tushdi (ularga harf yozib bo'lmaydi), :default esa formaning yuborish tugmasiga ham tushdi. :indeterminate holatini faqat JavaScript yoqadi — HTML'da bunday atribut yo'q.

:disabled ni odatda xira rang bilan bezashadi: button:disabled { color: #5b6660; }. Lekin yuborish tugmasini "forma to'lmaguncha" o'chirib qo'ymang (Qulay va accessible forma).

6.3 :invalid va :user-invalid

Brauzer validatsiyasi darsida ikki xil "xato maydon" selektorini ko'rgan edik. Endi ularni haqiqiy «Bahor» maydonlarida solishtiramiz. Chrome'da ketma-ket sinadik:

Vaziyat :invalid :user-invalid
Sahifa endi ochildi, majburiy maydon bo'sh ha yo'q
Mehmon yozib, o'chirdi, hali maydonda ha yo'q
Maydondan Tab bilan chiqdi ha ha
"Yuborish" bosildi ha ha, hamma xato maydonda

Ya'ni :invalid hali hech narsa yozmagan mehmonni ham qizil ramka bilan qarshi oladi. :user-invalid esa mehmon maydonni o'zgartirib chiqquncha yoki yuborishga uringuncha kutadi:

flowchart LR
  A["Sahifa ochildi:<br/>hech narsa<br/>bo'yalmaydi"]
  B{"Yozib chiqdimi<br/>yoki yubordimi?"}
  C{"Qiymat<br/>to'g'rimi?"}
  A --> B
  B -->|"yo'q"| A
  B -->|"ha"| C
  C -->|"ha"| D[":user-valid"]
  C -->|"yo'q"| E[":user-invalid"]

Nimaga qarang: birinchi savolga "ha" javobi bo'lmaguncha ikkala holat ham o'chiq. Undan keyin brauzer har harfda qayta tekshiradi. Chrome'da sinadik: bo'sh qoldirilib qizargan ismga "Al" yozishimiz bilan u darhol :user-valid bo'ldi.

Bron formasida sinab ko'ring. Ismni yozib o'chiring va Tab bosing. Telefonga +998 90 yozib chiqing. Mehmonlar sonini 25 qiling:

html
<style>
  input:user-invalid {
    border: 2px solid #b4461a;
  }
  input:user-valid {
    border: 2px solid #2f6b3a;
  }
</style>
<form action="https://example.com/bron" method="post">
  <p>
    <label for="ism">Ismingiz</label>
    <input id="ism" name="ism" type="text" required>
  </p>
  <p>
    <label for="telefon">Telefon raqamingiz</label>
    <input id="telefon" name="telefon" type="tel" required
           pattern="[0-9 +\-]{9,17}">
  </p>
  <p>
    <label for="odam">Mehmonlar soni</label>
    <input id="odam" name="odam" type="number"
           min="1" max="20" value="2" required>
  </p>
  <button type="submit">Stolni band qilish</button>
</form>

Nimaga qarang: sahifa ochilganda bitta ham rangli ramka yo'q. Xato qiymat bilan chiqqan maydon qizg'ish, to'g'risi yashil ramka oladi. Sahifani yangilab, hech narsa yozmasdan "Stolni band qilish" ni bosing: ikki bo'sh maydon qizaradi, mehmonlar soni yashil bo'ladi — yuborishga urinish hamma maydonni "tekshirilgan" qiladi (Chrome'da tekshirdik).

:user-invalid va :user-valid 2023-yil noyabridan hamma asosiy brauzerlarda bor, 2026-yil mayidan esa Baseline'da "widely available" (Veb standartlari).

Diqqat: Rang yolg'iz yetmaydi. Qizil ramkani rangni ajratmaydigan odam ko'rmasligi mumkin, Malika esa uni umuman eshitmaydi. Xato matni kerak. JavaScript o'z tekshiruvidan keyin maydonga aria-invalid="true" qo'yadi va xato matnini ko'rsatadi (Atribut selektorlari). Ikkala holatni bitta qoidada bezash mumkin: input:user-invalid, input[aria-invalid="true"].

Yana bir kichik fakt: :invalid va :valid formaning o'ziga ham tushadi. Chrome'da tekshirdik: bitta maydon xato bo'lsa, form:invalid ham ishlaydi. Bundan foydalanishning chiroyli yo'lini Mantiqiy pseudo-klasslar darsida ko'ramiz.

7. Manzil, til va maxsus teglar

7.1 :target — sakralgan bo'lim

Sahifa ichidagi havolalar darsida ":target bilan sakralgan bo'limni belgilash mumkin" degan edik. :target — id'si hozir URL'dagi # dan keyingi qism bilan bir xil element:

html
<style>
  :target {
    background-color: #fffaf0;
    outline: 2px solid #b4461a;
  }
</style>
<nav aria-label="Menyu bo'limlari">
  <a href="#issiq-taomlar">Issiq taomlar</a> ·
  <a href="#ichimliklar">Ichimliklar</a>
</nav>
<section id="issiq-taomlar">
  <h2>Issiq taomlar</h2>
  <p>Osh, lag'mon, manti.</p>
</section>
<section id="ichimliklar">
  <h2>Ichimliklar</h2>
  <p>Ko'k choy — 5 000 so'm.</p>
</section>

Nimaga qarang: "Ichimliklar" havolasini bossangiz, o'sha bo'lim qaymoq fon va qizg'ish ramka oladi. Mehmon sahifa qayerga sakraganini darhol ko'radi. Boshqa havolani bossangiz, belgi unga ko'chadi. O'sha darsda tilga olingan qolgan ikki imkoniyat — scroll-margin-top va scroll-behavior — position: fixed va sticky va Skroll xulqi darslarida.

7.2 :lang() va :dir()

:lang(en) — inglizcha matn. O'tgan darsdagi [lang|="en"] ga o'xshaydi, lekin muhim farqi bor. lang meros bo'lib o'tadi (Ko'p tilli matn): lang="en" blok ichidagi paragraf ham inglizcha. :lang() bu merosni biladi, atribut selektori esa bilmaydi:

html
<style>
  p:lang(en) {
    font-style: italic;
    color: #5b6660;
  }
</style>
<p>Mehmonlar sharhi:</p>
<blockquote lang="en">
  <p>Amazing plov and very kind staff!</p>
</blockquote>

Nimaga qarang: sharh paragrafi qiya va kulrang. Unda lang atributi yo'q — u tilni blockquote dan meros oldi. Chrome'da tekshirdik: p[lang|="en"] bu paragrafni topmadi, p:lang(en) esa topdi. Qoida: tilga qarab bezashda :lang() ni tanlang.

:dir(rtl) — matn yo'nalishi o'ngdan chapga (arabcha kabi) bo'lgan element. U ham merosni hisobga oladi va dir="auto" da brauzer o'zi aniqlagan yo'nalishni ham biladi. Chrome'da tekshirdik: dir="auto" li arabcha paragraf p:dir(rtl) ga tushdi, [dir="rtl"] esa uni topmasdi.

:dir() 2023-yil dekabridan hamma asosiy brauzerlarda bor va 2026-yil iyunidan widely available.

7.3 :defined va yangi holatlar

Zamonaviy forma imkoniyatlari darsida o'z tegingizni yaratish mumkinligini ko'rgan edik — masalan, <yulduz-baho>. Bunday tegni JavaScript "ro'yxatdan o'tkazadi". :defined — ro'yxatdan o'tgan element. Skript hali yuklanmagan bo'lsa, <yulduz-baho> :defined emas — Chrome'da tekshirdik. Buning foydasi: skript yuklanguncha "chala" tegni yashirib turish mumkin. O'z teglarini yaratishni Web Components'ga kirish darsida o'rganamiz — hozir bilish shart emas.

Yana ikki yangi holatni tanib qo'ying:

  • :open — ochiq details, dialog yoki select. details:open o'tgan darsdagi details[open] bilan bir xil. Lekin u 2026-yil mayida Baseline bo'ldi — yangi, eski brauzerlarda ishlamaydi. Hozircha [open] ishonchliroq.
  • :popover-open — ochiq popover. Uni Top layer darsida bezaymiz.

8. Hujumchi nigohi

:visited cheklovlari bekorga qo'yilmagan. 2010-yillar boshigacha brauzerlar :visited da hamma narsaga ruxsat berardi. Hujumchi sahifasiga yuzlab yashirin havola qo'yardi: banklar, klinikalar, ish qidirish saytlari. Keyin JavaScript bilan har havolaning rangini o'qirdi. Rang "ochilgan" bo'lsa — mehmon o'sha saytda bo'lgan. Mehmon hech narsa bosmasdan, sayt uning ko'rish tarixini bilib olardi.

Brauzerlar bu yo'lni uch devor bilan yopdi (MDN):

  1. Faqat rang. O'lcham o'zgarmaydi — joylashuvni o'lchab ham bilib bo'lmaydi.
  2. JavaScript'ga yolg'on. Rangni so'rasa, brauzer doim "ochilmagan" holatdagi qiymatni qaytaradi.
  3. Qidiruv bo'sh. JavaScript :visited bo'yicha element qidirsa, bitta ham topilmaydi.

Forma holatlari haqida ham eslatma: :user-invalid — faqat ko'rinish. Brauzer validatsiyasi darsidagi "Hujumchi nigohi" ni eslang: hujumchi required ni DevTools'da o'chirib, formani baribir yuboradi. Qizil ramka halol mehmonga yordam beradi, himoyani esa faqat server beradi.

9. Ko'p uchraydigan xatolar

9.1 Ikki nuqta oldida bo'sh joy

nav a :hover — "havola ichidagi hover element". Hech narsa topilmaydi, xato ham chiqmaydi. Tuzatish: nav a:hover — bo'sh joysiz.

9.2 LVHA tartibi buzilgan

a:hover fayl boshida, a:link esa pastroqda. Hover hech qachon ko'rinmaydi. Tuzatish: tartib — :link, :visited, :hover, :active.

9.3 outline: none o'rnini bosuvchisiz

Klaviaturadagi odam sahifada adashadi. Tuzatish: halqani o'chirmang yoki o'sha zahoti :focus-visible uchun boshqa aniq belgi bering.

9.4 :invalid bilan xato ko'rsatish

Sahifa ochilishi bilan hamma bo'sh majburiy maydon qizil. Mehmon hali hech narsa qilmasdan "xato qildim" deb o'ylaydi. Tuzatish: :user-invalid.

9.5 + bilan orqaga qarash

input:focus + label — label maydondan oldin tursa, ishlamaydi. Tuzatish: otani tanlang (div:focus-within label) yoki :has() ni kuting (Mantiqiy pseudo-klasslar).

9.6 Muhim narsa faqat :hover da

Telefonda "sichqoncha ustiga kelish" yo'q. Tuzatish: hover — faqat bezak, ma'lumot doim ko'rinib tursin.

10. Mashqlar

1-mashq (oson): Qaysi pseudo-klass?

Har vaziyat uchun pseudo-klass nomini ikki nuqtasiz yozing.

  • Mehmon sichqonchani menyu havolasi ustiga olib keldi —
  • Bobur Tab bilan "Stolni band qilish" tugmasiga keldi —
  • Mehmon "Ayvon" radio tugmasini tanladi —
  • Mehmon ismni bo'sh qoldirib, keyingi maydonga o'tdi —
  • Mehmon #ichimliklar havolasi orqali bo'limga sakradi —
  • Mehmon "Menyu" sahifasini oldin ochgan —
Yechim
  • :hover — kursor element ustida.
  • :focus-visible — klaviatura bilan kelingan fokus. :focus ham to'g'ri bo'ladi, lekin u sichqoncha bosganda ham yonadi. Klaviatura uchun bezak — :focus-visible da.
  • :checked — tanlangan radio yoki checkbox.
  • :user-invalid — mehmon maydon bilan ishlab chiqdi va qiymat xato. :invalid bu yerda ham mos, lekin u sahifa ochilganda ham yonardi.
  • :target — id'si URL'dagi # qismiga teng element.
  • :visited — tarixdagi manzil. Unga faqat rang beriladi.

2-mashq (o'rta): Bron havolasining to'rt holati

.bron-havola uchun asosiy.css ga qoidalar yozing:

  1. Oddiy holat: fon #2f6b3a, matn #ffffff, ichki bo'sh joy 8px 16px.
  2. Sichqoncha ustida: fon #1a5d1a.
  3. Klaviatura fokusida: sichqonchadagi bilan bir xil fon va 3px solid #1a5d1a halqa, outline-offset: 2px.
  4. Bosilganda: fon #1f2a24.

Ishora: 2 va 3-bandda fon bir xil — Asosiy selektorlar darsidagi vergul bilan guruhlang. Tartibni LVHA qoidasi bo'yicha tuzing: bosilgan holat oxirida.

Yechim
html
<style>
  .bron-havola {
    background-color: #2f6b3a;
    color: #ffffff;
    padding: 8px 16px;
  }
  .bron-havola:hover,
  .bron-havola:focus-visible {
    background-color: #1a5d1a;
  }
  .bron-havola:focus-visible {
    outline: 3px solid #1a5d1a;
    outline-offset: 2px;
  }
  .bron-havola:active {
    background-color: #1f2a24;
  }
</style>
<p><a class="bron-havola" href="bron/">Stolni band qilish</a></p>
  • Guruhlash sichqoncha va klaviatura foydalanuvchisiga bir xil javob beradi. Bobur ham, sichqonchadagi mehmon ham tugma "tayyor" ekanini ko'radi.
  • Halqa alohida qoidada — u faqat klaviaturada kerak.
  • :active eng pastda: bosilganda boshqa holatlar ham yonib turadi, pastdagi qoida esa ularning fonini bosib ketadi.

3-mashq (qiyin): Stajyorning CSS'i

Stajyor «Bahor» sayti uchun shunday CSS yozdi. Jasur aka to'rtta shikoyat bilan keldi: "sichqoncha kelganda havola o'zgarmaydi", "Bobur saytda adashib qoldi", "mehmonlar formani ochishi bilan qizil ramkadan qo'rqib ketyapti", "ochilgan sahifalar qalin bo'lmayapti".

css
a:hover { color: #b4461a; }
a:link { color: #2f6b3a; }
a:visited { color: #5b6660; font-weight: bold; }
:focus { outline: none; }
input:invalid { border: 2px solid #b4461a; }

Har shikoyatning sababini toping va CSS'ni tuzating.

Ishora: CSS sintaksisi to'g'ri — brauzer hamma qatorni o'qiydi. Muammo tartibda, cheklovda va noto'g'ri tanlangan holatlarda. LVHA tartibi, :visited cheklovi, outline: none va :user-invalid haqidagi bo'limlarni qayta ko'ring.

Yechim
css
a:link { color: #2f6b3a; }
a:visited { color: #5b6660; }
a:hover { color: #b4461a; }
:focus-visible {
  outline: 3px solid #1a5d1a;
  outline-offset: 2px;
}
input:user-invalid { border: 2px solid #b4461a; }
  1. Hover ko'rinmaydi. a:hover a:link dan tepada. Og'irligi teng, shuning uchun pastdagi :link yutadi. Tartib — LVHA.
  2. Bobur adashdi. outline: none fokus halqasini o'chirdi va o'rniga hech narsa bermadi. Tuzatishda uni olib tashladik va :focus-visible ga aniq halqa berdik.
  3. Qizil ramka darhol chiqadi. :invalid sahifa ochilishi bilan bo'sh majburiy maydonlarga tushadi. :user-invalid mehmon maydon bilan ishlaguncha kutadi.
  4. Qalin bo'lmayapti. :visited da font-weight taqiqlangan — maxfiylik uchun. Jasur akaga tushuntirasiz: ochilgan sahifa faqat rangi bilan farq qiladi.

Bitta ham qator brauzer uchun "xato" emas edi. Bunday xatolarni VS Code topmaydi — ularni sahifani sichqoncha va klaviatura bilan sinab topasiz.

4-mashq: Portfolio qadami — havola va forma holatlari

Portfolioga holatlarni qo'shamiz. HTML'ga yana tegmaymiz.

  1. Hamma havolalar: sichqoncha ustida foni #e8f1ec bo'lsin.
  2. Hamma fokuslanadigan elementlar: klaviatura fokusida 3px solid halqa portfolio rangingizda (namuna — #1f6f4a), outline-offset: 2px. O'tgan darsdagi joriy sahifa havolasi ham shu ikki qoida bilan hover va fokus oladi.
  3. Aloqa formasi: mehmon xato qiymat bilan chiqqan input va textarea — 2px solid #b4461a ramka.
  4. "Qaysi mavzuda?" guruhida tanlangan radio'ning yorlig'i — qalin.

Ishora: 1-band uchun a:hover, 2-band uchun :focus-visible selektori yolg'iz — u har qanday fokuslanadigan elementga tushadi. 3-band — vergul bilan ikki selektor. 4-band — input:checked + label: portfolio formasida ham radio yorlig'idan oldin turadi.

Yechim

asosiy.css ning oxiriga:

css
/* Havola ustida sichqoncha */
a:hover {
  background-color: #e8f1ec;
}

/* Klaviatura fokusi — hamma elementlar uchun */
:focus-visible {
  outline: 3px solid #1f6f4a;
  outline-offset: 2px;
}

/* Aloqa formasi: xato faqat mehmon ishlab bo'lgach */
input:user-invalid,
textarea:user-invalid {
  border: 2px solid #b4461a;
}

/* Tanlangan mavzu */
input:checked + label {
  font-weight: bold;
}

Aloqa sahifasining forma qismi:

html
<style>
  body {
    font-family: system-ui, sans-serif;
    color: #1f2a24;
    background-color: #f7faf8;
  }
  h1, h2 { color: #1f6f4a; }
  a:hover { background-color: #e8f1ec; }
  :focus-visible {
    outline: 3px solid #1f6f4a;
    outline-offset: 2px;
  }
  input:user-invalid,
  textarea:user-invalid {
    border: 2px solid #b4461a;
  }
  input:checked + label { font-weight: bold; }
</style>
<main id="asosiy">
  <h2>Xabar yuborish</h2>
  <form action="https://example.com/aloqa" method="post">
    <p>
      <label for="email">Email</label>
      <input id="email" name="email" type="email"
             autocomplete="email" required>
    </p>
    <fieldset>
      <legend>Qaysi mavzuda?</legend>
      <p>
        <input id="mavzu-ish" name="mavzu" type="radio"
               value="ish" required>
        <label for="mavzu-ish">Ish taklifi</label>
      </p>
      <p>
        <input id="mavzu-savol" name="mavzu" type="radio"
               value="savol">
        <label for="mavzu-savol">Savol</label>
      </p>
    </fieldset>
    <button type="submit">Yuborish</button>
  </form>
  <p>
    Yoki yozing:
    <a href="mailto:aziz@example.com">aziz@example.com</a>
  </p>
</main>

Nozik joylar:

  • Emailga ali deb yozib chiqing — ramka qizaradi. @ bilan to'g'ri manzil yozsangiz, darhol o'chadi.
  • :focus-visible oldida hech narsa yo'q — u *:focus-visible bilan bir xil. Havolalar, tugmalar, maydonlar, summary — hammasi bitta qoida bilan halqa oladi.
  • Joriy sahifa havolasi ham a — hover foni va fokus halqasi unga ham tushadi. Rangi esa o'zgarmaydi: a:hover faqat fon beradi.

Sichqonchani chetga qo'yib, Tab bilan har sahifani oxirigacha yuring. Har qadamda halqa ko'rinib tursin.

11. Real ishda

  • Har bir tugma va havola dizayn tizimlarida kamida besh holatda chiziladi: oddiy, hover, fokus, bosilgan, o'chirilgan. Dasturchi ularni aynan shu pseudo-klasslar bilan yozadi (Tugmalar tizimi).
  • Accessibility auditlari birinchi navbatda fokusni tekshiradi. outline: none topilsa — bu deyarli har doim xato deb yoziladi.
  • Tailwind (tayyor class'lar to'plami, kursda alohida o'rganamiz) hover:, focus-visible:, disabled: kabi yozuvlarni ishlatadi. Ularning ortida aynan shu pseudo-klasslar turadi (Tailwind variantlari).
  • Intervyuda so'raladi: ":focus va :focus-visible farqi?", "LVHA nima?", "Nega :visited da font-size ishlamaydi?", ":invalid o'rniga nimani ishlatasiz?".

Xulosa

  • Pseudo-klass — holat bo'yicha selektor: bitta ikki nuqta, bo'sh joysiz (a:hover). Holatni brauzer o'zi yoqadi va o'chiradi.
  • :hover — faqat bezak: telefonda sichqoncha yo'q. :active — bosib turilgan payt.
  • Havola holatlari tartibi — LVHA: :link, :visited, :hover, :active.
  • :visited maxfiylik uchun cheklangan: faqat rang xususiyatlari ishlaydi.
  • Fokus uchun :focus-visible; outline: none — faqat o'rniga boshqa belgi bilan. :focus-within — ichida fokus bor ota.
  • Forma xatosi — :user-invalid: mehmon maydon bilan ishlaguncha kutadi. Rang yonida xato matni ham bo'lsin.

Keyingi dars: Tuzilma pseudo-klasslari va An+B formulasi — birinchi, oxirgi, har uchinchi elementni class qo'shmasdan tanlashni o'rganamiz.

Manbalar

  • MDN: "Pseudo-classes", ":hover", ":focus-visible", ":visited" (maxfiylik cheklovlari), ":user-invalid", ":target", ":lang()", ":dir()" — developer.mozilla.org
  • W3C: "Selectors Level 4" — w3.org/TR/selectors-4
  • WCAG 2.2: 2.4.7 Focus Visible — w3.org/TR/WCAG22
  • web-features (Baseline ma'lumotlari): "user-pseudos", "dir-pseudo", "open-pseudo" — github.com/web-platform-dx/web-features
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
CSS pseudo-klasslari: hover, focus-visible va forma holatlari — IlmHamroh