Mundarija (34)
- Bu darsda
- 1. Nega bu kerak?
- 2. Maydon anatomiyasi
- 2.1 To'rt qism
- 2.2 Maydon va uning holatlari
- 2.3 Ikki xil xato manbai
- 2.4 Kodni o'qiymiz
- 3. Maxsus checkbox va radio
- 3.1 Avval — accent-color
- 3.2 appearance: none + ::before
- 4. Radio'dan segmentli tanlov
- 5. O'chirgich (switch)
- 5.1 Checkbox yoki switch
- 5.2 Chizamiz
- 6. Prefiksli maydon va suzuvchi yorliq
- 6.1 Prefiks va suffiks
- 6.2 Suzuvchi yorliq
- 7. :autofill: brauzer to'ldirgan maydon
- 8. «Bahor»ning komponentlar.css iga
- 9. Ko'p uchraydigan xatolar
- 9.1 Placeholder — yorliq o'rnida
- 9.2 Hamma bo'sh maydon ochilishda qizil
- 9.3 Xato faqat qizil ramka
- 9.4 Checkbox display: none
- 9.5 Majburiy ranglar rejimida belgi yo'q
- 9.6 Och kulrang ramka
- 10. Mashqlar
- 1-mashq (oson): muvaffaqiyat belgisi
- 2-mashq (o'rta): checkbox'ning uchinchi holati
- 3-mashq (qiyin): o'chirgichda holat so'zi
- 4-mashq: Portfolio qadami — aloqa formasi komponentlari
- 11. Real ishda
- Xulosa
- Manbalar
CSS forma komponentlari: input, checkbox, switch va xato holatlari
Qisqacha: Forma komponenti — yorliq, yordam matni, maydon va xato matni bitta o'ramda. Holatlar (hover, fokus, xato, nofaol) o'ramga
:has()orqali tarqaladi:div:has(> :user-invalid) label— xato maydonning yorlig'i. Maxsus checkbox va radioappearance: none+::beforebilan chiziladi, o'chirgich esarole="switch"li checkbox. Qoida: avvalaccent-colorni sinang; o'zingiz chizsangiz — fokus, nofaol holat va majburiy ranglar rejimini ham o'zingiz chizasiz.
Bu darsda
- Maydonning to'liq tuzilishini (yorliq, yordam, maydon, xato) CSS bilan tartibga keltirasiz.
- Fokus, xato, nofaol holatlarni yozasiz va xatoni faqat rang bilan emas, belgi va so'z bilan ko'rsatasiz.
- Maxsus checkbox, radio va o'chirgichni (switch) accessible qilib chizasiz.
- Radio guruhini segmentli tanlovga aylantirasiz, prefiksli maydon va suzuvchi yorliq yasaysiz.
- Brauzer avtomatik to'ldirgan maydonni (
:autofill) qanday bezash mumkinligini va mumkin emasligini bilasiz.
Oldin bilishingiz kerak: Forma elementlarini zamonaviy stillash, Qulay va accessible forma, Holat pseudo-klasslari, Tugmalar tizimi.
1. Nega bu kerak?
O'tgan darsda navbar qurdik. Endi saytning eng "ishchi" qismiga o'tamiz — formaga. Mehmon stol band qilmoqchi: ism, telefon, sana, odam soni. Forma noqulay bo'lsa, u shunchaki telefon qiladi yoki boshqa choyxonaga ketadi.
«Bahor» bron formasi Qulay va accessible forma darsidan beri HTML jihatdan to'liq: har maydonning label i bor, yordam matni aria-describedby bilan ulangan, brauzer tekshiruvi ishlaydi. CSS esa unga deyarli tegmagan. O'sha darsda ikki va'da qolgan edi: "chiroyli joylashuvni keyinroq CSS bilan qilamiz" va "qizil rang va ikonka keyinroq CSS bilan qo'shiladi".
Yana uchta va'da bor. Birinchisi Zamonaviy forma imkoniyatlari va ARIA asoslari darslarida berilgan: hamma brauzerda o'chirgich — checkbox + role="switch" + CSS. Ikkinchisi — Forma elementlarini stillash darsidagi to'liq maxsus checkbox va radio. Uchinchisi — Tugmalar tizimi darsida: radio guruhini tugmalar ko'rinishiga keltirish.
2. Maydon anatomiyasi
2.1 To'rt qism
Har maydon to'rt qismdan iborat:
| Qism | «Bahor»da | Kim uchun |
|---|---|---|
| Yorliq | <label for="telefon"> |
Hamma: maydon nima haqida |
| Yordam matni | <span id="telefon-yordam"> |
Xato qilmaslik uchun oldindan |
| Maydon | <input id="telefon"> |
Kiritish |
| Xato matni | <span id="telefon-xato"> |
Nima noto'g'ri va qanday tuzatish |
«Bahor»da ular div ga o'ralgan (Qulay va accessible forma). O'ram — bizning komponentimiz: uning ichidagi holat (xato, fokus, nofaol) :has() orqali hamma qismga tarqaladi.
Tartib muhim: yordam matni maydondan oldin. Ekran o'quvchi uni aria-describedby orqali maydon bilan birga o'qiydi, ko'zi ko'radigan mehmon esa yozishni boshlashdan oldin ko'radi. Maydon ostidagi yordam matnini telefon klaviaturasi ko'pincha yopib qo'yadi.
2.2 Maydon va uning holatlari
<style>
:root {
--rang-fon: #fffaf0;
--rang-matn: #1f2a24;
--rang-asosiy: #2f6b3a;
--rang-asosiy-toq: #1a5d1a;
--rang-ikkinchi: #5b6660;
--rang-xato: oklch(52% 0.19 27);
}
body {
font-family: system-ui, sans-serif;
background: var(--rang-fon);
color: var(--rang-matn);
}
form > div {
display: grid;
gap: 0.25rem;
max-inline-size: 22rem;
margin-block-end: 1rem;
}
label { font-weight: 600; }
span[id$="-yordam"] {
font-size: 0.875rem;
color: var(--rang-ikkinchi);
}
span[id$="-xato"] {
font-size: 0.875rem;
font-weight: 600;
color: var(--rang-xato);
}
span[id$="-xato"]::before { content: "⚠ " / ""; }
input {
box-sizing: border-box;
min-block-size: 2.75rem;
padding: 0.5em 0.75em;
border: 2px solid var(--rang-ikkinchi);
border-radius: 0.5rem;
background: white;
color: var(--rang-matn);
font: inherit;
}
@media (hover: hover) {
input:not(:disabled):hover { border-color: var(--rang-matn); }
}
input:focus-visible {
border-color: var(--rang-asosiy);
outline: 3px solid var(--rang-asosiy-toq);
outline-offset: 2px;
box-shadow: 0 0 0 2px var(--rang-fon);
}
input:is(:user-invalid, [aria-invalid="true"]) {
border-color: var(--rang-xato);
}
div:has(> :is(:user-invalid, [aria-invalid="true"])) label {
color: var(--rang-xato);
}
div:has(> :user-invalid) span[id$="-yordam"] {
color: var(--rang-xato);
}
div:has(> :user-invalid) span[id$="-yordam"]::before {
content: "⚠ " / "Xato: ";
}
input:disabled {
border-style: dashed;
background: transparent;
color: var(--rang-ikkinchi);
cursor: not-allowed;
}
</style>
<form action="https://example.com/bron" method="post">
<div>
<label for="ism">Ismingiz</label>
<input id="ism" name="ism" autocomplete="name" required>
</div>
<div>
<label for="telefon">Telefon raqamingiz</label>
<span id="telefon-yordam">Masalan: +998 90 000 00 00</span>
<input id="telefon" name="telefon" type="tel"
autocomplete="tel" required pattern="[0-9 +\-]{9,17}"
aria-describedby="telefon-yordam">
</div>
<div>
<label for="odam">Mehmonlar soni</label>
<input id="odam" name="odam" type="number" min="1" max="20"
value="25" aria-invalid="true"
aria-describedby="odam-xato">
<span id="odam-xato">20 kishidan ko'p bo'lsa, qo'ng'iroq
qiling.</span>
</div>
<div>
<label for="stol">Stol raqami</label>
<input id="stol" name="stol" value="4" disabled>
</div>
</form>Nimaga qarang: uchinchi maydon ("Mehmonlar soni") allaqachon xato holatida — qizil ramka, qizil yorliq va ostida " 20 kishidan ko'p bo'lsa, qo'ng'iroq qiling." To'rtinchi maydon nofaol: punktir ramka, kulrang matn. Endi telefon maydoniga abc yozib, Tab bosing — telefon ham qizaradi, yordam matni oldida "" paydo bo'ladi.
Chrome'da tekshirdik: sahifa ochilganda bo'sh "Ismingiz" maydoni required bo'lsa ham qizil emas. Unga kirib-chiqib ketsangiz ham — yo'q. Faqat yozib, o'chirib, chiqib ketsangiz yoki formani yuborishga urinsangiz qizaradi. Bu :user-invalid — Holat pseudo-klasslari darsidagi "foydalanuvchi ishlab bo'lgach" qoidasi. :invalid esa sahifa ochilishi bilan hamma bo'sh majburiy maydonni qizartirardi — mehmon hali hech narsa qilmasdan "xato qildingiz" degan xabarni ko'rardi.
2.3 Ikki xil xato manbai
Formada xatoni ikki joy aniqlaydi:
- Brauzer —
required,pattern,min/maxbo'yicha. CSS'da:user-invalid.:user-validva:user-invalid— keng tarqalgan Baseline: ular 2023-yil noyabridan hamma asosiy brauzerda, 2026-yil mayidan "keng tarqalgan". - Server — "bu sanada bo'sh stol yo'q" kabi brauzer bilmaydigan narsalar. Server sahifani qaytarganda maydonga
aria-invalid="true"qo'yadi va xato matnini (-xato) yozadi. Keyinchalik JavaScript ham shunday qiladi (09-qismda o'rganasiz).
CSS ikkalasini bitta qoida bilan chizadi: :is(:user-invalid, [aria-invalid="true"]). Tashqi ko'rinish bir xil — mehmon uchun xato qayerdan kelgani ahamiyatsiz.
Diqqat: Xato matnini HTML'da oldindan yozib qo'yib, CSS bilan yashirish (
display: none) va faqat xatoda ko'rsatish — xato fikr. Sababi:aria-describedbyyashirin elementning matnini ham o'qiydi. Malika xato bo'lmasa ham "20 kishidan ko'p bo'lsa…" ni har safar eshitadi. Xato matni faqat xato bo'lganda HTML'da paydo bo'lsin — uni server yoki skript qo'shadi. CSS'ning vazifasi — tayyor holatni chizish.
2.4 Kodni o'qiymiz
- Ramka
--rang-ikkinchida, 2 piksel. WCAG 1.4.11: interfeys elementining chegarasi fonga nisbatan kamida 3:1 bo'lsin. Kulrang#5b6660oq fonda — 6.0:1. Ko'p saytlardagi och kulrang ramka (#ddd) 1.4:1 — ko'rish zaif odam maydonni umuman ko'rmaydi. - Halqa — ikki rangli (CSS'da accessibility): to'q
outlineva fon rangidagi ichki chiziq. «Bahor»da uasos.cssda umumiy; natijalarda namoyish uchun takrorlangan. :focus-visiblematn maydonida sichqoncha bilan ham ishlaydi. Brauzer matn maydonini "klaviatura kutayotgan joy" deb biladi — Chrome'da bosib tekshirdik, halqa chiqdi. Tugmadan farqli: tugmada halqa faqat klaviaturada.div:has(> :user-invalid) label— "ichida xato maydoni bor o'ramning yorlig'i" (Mantiqiy pseudo-klasslar).>— faqat bevosita bola: ichma-ich o'ramlar bir-birini "yuqtirmaydi".- Xato — rang + belgi + so'z. "" belgisining muqobil matni
"Xato: "— ekran o'quvchi "Xato: Masalan: +998…" deb o'qiydi (Pseudo-elementlar). Rang ko'r odam ham, ekran o'quvchi ham xatoni biladi — Rang nazariyasi darsidagi qoida. - Nofaol maydon — punktir ramka. Faqat rang emas, shakl ham o'zgaradi. Nofaol elementlar uchun WCAG kontrast talab qilmaydi, lekin matn baribir o'qilsin.
cursor: not-allowed—cursorBaseline emas (telefonda kursor yo'q), zaxira kerak emas. font: inheritva kamida 16 piksel — iPhone kichik shriftli maydonga fokus bo'lganda sahifani kattalashtiradi (Mobil qurilma tuzoqlari).
Tekshirib ko'ring: Nega xato qoidasi
:invalidemas,:user-invalidbilan yozilgan? Bo'sh bron formasi ochilganda farq qanday ko'rinadi?
Javob
Agar :invalid yozilsa, sahifa ochilishi bilan hamma bo'sh majburiy maydon (ism, telefon, sana) qizil bo'lardi. Mehmon hali hech narsa yozmagan, forma esa unga "xato" deb qichqiradi. :user-invalid faqat mehmon maydon bilan ishlab bo'lgach yoki formani yuborishga uringach mos keladi. Natijada qizil rang faqat haqiqiy xatoni bildiradi.
3. Maxsus checkbox va radio
3.1 Avval — accent-color
Forma elementlarini stillash darsida accent-color bilan checkbox va radio'ni bitta qatorda brend rangiga bo'yagan edik. Ko'p hollarda shu yetadi. O'zingiz chizish kerak bo'ladigan holatlar: dizayner belgining shakli, o'lchami yoki animatsiyasini boshqacha istaydi; yoki accent-color ishlamaydigan brauzer ham muhim (u Baseline emas: Android'dagi Chrome ro'yxatda yo'q).
3.2 appearance: none + ::before
O'sha darsda ko'rgan tuzoq: appearance: none checkbox'ni 0×0 pikselga aylantiradi. Endi hammasini o'zimiz chizamiz — va hech bir holatni unutmaymiz:
<style>
:root {
--rang-fon: #fffaf0;
--rang-matn: #1f2a24;
--rang-asosiy: #2f6b3a;
--rang-asosiy-toq: #1a5d1a;
--rang-ikkinchi: #5b6660;
}
body {
font-family: system-ui, sans-serif;
background: var(--rang-fon);
color: var(--rang-matn);
}
fieldset {
display: grid;
gap: 0.75rem;
max-inline-size: 22rem;
border: 0;
padding: 0;
}
legend { font-weight: 600; margin-block-end: 0.5rem; }
fieldset div {
display: flex;
align-items: center;
gap: 0.5rem;
}
input:is([type="checkbox"], [type="radio"]) {
appearance: none;
flex: none;
display: inline-grid;
place-content: center;
inline-size: 1.5rem;
block-size: 1.5rem;
margin: 0;
border: 2px solid var(--rang-ikkinchi);
border-radius: 0.375rem;
background: white;
font: inherit;
}
input[type="radio"] { border-radius: 50%; }
input:is([type="checkbox"], [type="radio"])::before {
content: "";
inline-size: 0.875rem;
block-size: 0.875rem;
background: var(--rang-fon);
scale: 0;
}
input[type="checkbox"]::before {
clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%,
80% 0, 43% 62%);
}
input[type="radio"]::before {
inline-size: 0.625rem;
block-size: 0.625rem;
border-radius: 50%;
}
input:checked {
border-color: var(--rang-asosiy);
background: var(--rang-asosiy);
}
input:checked::before { scale: 1; }
input:focus-visible {
outline: 3px solid var(--rang-asosiy-toq);
outline-offset: 2px;
box-shadow: 0 0 0 2px var(--rang-fon);
}
input:disabled {
border-style: dashed;
background: transparent;
}
input:disabled + label { color: var(--rang-ikkinchi); }
@media (prefers-reduced-motion: no-preference) {
input::before { transition: scale 0.12s ease-out; }
}
@media (forced-colors: active) {
input::before { background: CanvasText; }
}
</style>
<form action="https://example.com/bron" method="post">
<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>
<div>
<input id="joy-xona" name="joy" type="radio" value="xona"
disabled>
<label for="joy-xona">Alohida xona — bugun band</label>
</div>
</fieldset>
<p>
<input id="sms" name="sms" type="checkbox" checked>
<label for="sms">Bron haqida SMS eslatma yuborilsin</label>
</p>
</form>Nimaga qarang: radio'lar — dumaloq, belgilangani yashil to'la doira, markazida qaymoq nuqta. Checkbox — burchaklari yumaloq kvadrat, ichida qaymoq "" belgisi. "Alohida xona" nofaol: punktir doira, kulrang yozuv. "Ayvon" ni bosing — nuqta bir lahzada "o'sib" chiqadi. Tab bilan radio guruhiga kiring va strelkalar bilan yuring: tanlov almashadi, fokus halqasi ko'rinadi — klaviatura xulqi brauzerniki bo'lib qoldi.
Kodni o'qiymiz:
display: inline-grid; place-content: center—::beforemarkazda (Flex naqshlari dagi markazlash, grid bilan).- Belgi —
clip-path: polygon(...)— kvadratdan "" shaklini qirqib olamiz (clip-path). Rasm yoki SVG fayl kerak emas, rangi esa oddiybackground. - Belgilanmagan holatda
scale: 0— belgi bor, lekin ko'rinmaydi. Belgilangandascale: 1.scale— arzon, kompozitor xususiyati (Rendering pipeline). - Belgilangan holat faqat belgi bilan emas, fon bilan ham ko'rsatiladi.
input— "almashtiriladigan" element va unga::beforeqo'yish standartda to'liq kafolatlanmagan. Zamonaviy brauzerlarappearance: nonebo'lgan checkbox'da uni chizadi (Chrome'da tekshirdik). Lekin biror brauzer chizmasa ham, yashil fon "belgilangan" deb aytadi. @media (forced-colors: active)— mana eng ko'p unutiladigan joy. Majburiy ranglar rejimida (Tugmalar tizimi) brauzer fonlarni o'zining ranglariga almashtiradi. Chrome'da tekshirdik: bu qatorsiz belgilangan va belgilanmagan checkbox bir xil — ikkalasi ham qora kvadrat, "" yo'qoldi.CanvasText— tizim rangi (asosiy matn rangi), uni brauzer almashtirmaydi.
Accessibility daraxtida hech narsa o'zgarmadi: Chrome "checkbox, belgilangan" va "radio tugma" deb aytadi. Biz faqat ko'rinishni o'zgartirdik — element o'sha-o'sha.
Tekshirib ko'ring: Stajyor checkbox'ni
display: noneqilib,label::beforeda kvadrat chizdi. Sichqoncha bilan ishlaydi. Nima buzildi?
Javob
display: none element fokus tartibidan va accessibility daraxtidan chiqadi. Bobur Tab bilan checkbox'ga bora olmaydi, Malika uni eshitmaydi. appearance: none esa faqat ko'rinishni o'chiradi, elementni joyida qoldiradi. Checkbox'ni butunlay yashirish kerak bo'lsa — keyingi bo'limdagi kabi opacity: 0 va position: absolute bilan, display: none bilan emas.
4. Radio'dan segmentli tanlov
Tugmalar tizimi darsida birlashgan tugmalar guruhini ko'rdik va dedik: tanlov formada yuborilsa, tugma emas, radio kerak. Mana o'sha radio'lar tugmalar ko'rinishida:
<style>
:root {
--rang-fon: #fffaf0;
--rang-asosiy: #2f6b3a;
--rang-asosiy-toq: #1a5d1a;
}
body { font-family: system-ui, sans-serif; background: #fffaf0; }
fieldset { border: 0; padding: 0; }
legend { font-weight: 600; margin-block-end: 0.5rem; }
.tanlov {
display: inline-flex;
flex-wrap: wrap;
}
.tanlov input {
position: absolute;
opacity: 0;
inline-size: 1px;
block-size: 1px;
}
.tanlov label {
display: grid;
place-items: center;
min-block-size: 2.75rem;
padding-inline: 1em;
border: 2px solid var(--rang-asosiy);
color: var(--rang-asosiy);
font-weight: 600;
cursor: pointer;
}
.tanlov label:not(:first-of-type) { margin-inline-start: -2px; }
.tanlov label:first-of-type {
border-start-start-radius: 0.5rem;
border-end-start-radius: 0.5rem;
}
.tanlov label:last-of-type {
border-start-end-radius: 0.5rem;
border-end-end-radius: 0.5rem;
}
.tanlov input:checked + label {
background: var(--rang-asosiy);
color: var(--rang-fon);
}
.tanlov input:focus-visible + label {
position: relative;
outline: 3px solid var(--rang-asosiy-toq);
outline-offset: 2px;
box-shadow: 0 0 0 2px var(--rang-fon);
}
</style>
<form action="https://example.com/bron" method="post">
<fieldset>
<legend>Vaqt</legend>
<div class="tanlov">
<input id="v12" name="vaqt" type="radio" value="12:00">
<label for="v12">12:00</label>
<input id="v15" name="vaqt" type="radio" value="15:00">
<label for="v15">15:00</label>
<input id="v18" name="vaqt" type="radio" value="18:00"
checked>
<label for="v18">18:00</label>
<input id="v20" name="vaqt" type="radio" value="20:00">
<label for="v20">20:00</label>
</div>
</fieldset>
</form>Nimaga qarang: to'rtta vaqt bitta tasmada, "18:00" yashil — tanlangan. Boshqasini bosing — yashil unga ko'chadi. Tab bilan guruhga kiring: halqa tanlangan vaqt atrofida. Strelkalar bilan yuring — tanlov va halqa birga ko'chadi. Bu radio'ning o'z klaviatura xulqi: guruhga bitta Tab, ichida — strelkalar.
- Radio yashiringan, lekin yo'qolmagan:
position: absolute; opacity: 0va 1 piksellik o'lcham. U fokus oladi va ekran o'quvchi uni radio tugma deb aytadi — nomilabeldan.display: noneyokivisibility: hiddenemas — ular radio'ni o'chirib yuboradi. - Holatlar
input + labelorqali::checked + label— tanlangan,:focus-visible + label— fokus (Asosiy selektorlar dagi qo'shni kombinator). Shuning uchun HTML'da harinputo'zlabelidan oldin turadi. :first-of-type/:last-of-type— chetkilabellar; ular orasidainputlar bor, shuning uchun:first-childishlamaydi (Tuzilma pseudo-klasslari).- «Bahor» formasida vaqt hozir
select(Qulay va accessible forma). To'rt variant uchun segmentli tanlov telefonda tezroq: bitta bosish, ro'yxat ochilmaydi. Variantlar 5–6 tadan ko'p bo'lsa —selectqolsin.
Tekshirib ko'ring: HTML'da
labelni o'zinputidan oldin yozib qo'ydingiz.input:checked + labelnima bo'ladi?
Javob
Ishlamay qoladi: tanlangan vaqt yashil bo'lmaydi. + faqat keyingi qo'shnini tanlaydi — input dan keyin kelgan label ni. Label oldinda tursa, input dan keyin boshqa vaqtning label i keladi va yashil noto'g'ri tugmaga tushadi (yoki hech qayerga).
5. O'chirgich (switch)
5.1 Checkbox yoki switch
Zamonaviy forma imkoniyatlari darsidagi qoida: checkbox forma yuborilganda kuchga kiradi, o'chirgich — darhol. Bron formasidagi "SMS eslatma" — checkbox. "Qorong'i rejim" — o'chirgich: bosishingiz bilan sahifa qorayadi.
HTML'dagi yangi switch atributi hozircha faqat Safari'da. Hamma brauzerda ishlashi uchun oddiy checkbox'ga role="switch" qo'shamiz (ARIA asoslari): ekran o'quvchi "belgilash katakchasi" o'rniga "o'chirgich, yoqilgan/o'chirilgan" deydi.
5.2 Chizamiz
<style>
:root {
color-scheme: light;
--fon: light-dark(#fffaf0, #16301b);
--yuza: light-dark(white, #22402a);
--matn: light-dark(#1f2a24, #fffaf0);
--asosiy: light-dark(#2f6b3a, #8fd19e);
--ikkinchi: light-dark(#5b6660, #b5c1bb);
}
:root:has(#qorongi:checked) { color-scheme: dark; }
body {
font-family: system-ui, sans-serif;
background: var(--fon);
color: var(--matn);
}
p {
display: flex;
align-items: center;
gap: 0.75rem;
}
input[role="switch"] {
appearance: none;
position: relative;
flex: none;
inline-size: 2.75rem;
block-size: 1.5rem;
margin: 0;
border: 2px solid var(--ikkinchi);
border-radius: 999px;
background: var(--yuza);
}
input[role="switch"]::before {
content: "";
position: absolute;
inset-block-start: 2px;
inset-inline-start: 2px;
inline-size: calc(1.5rem - 8px);
aspect-ratio: 1;
border-radius: 50%;
background: var(--ikkinchi);
}
input[role="switch"]:checked {
border-color: var(--asosiy);
background: var(--asosiy);
}
input[role="switch"]:checked::before {
translate: 1.25rem 0;
background: var(--fon);
}
input[role="switch"]:focus-visible {
outline: 3px solid var(--asosiy);
outline-offset: 2px;
box-shadow: 0 0 0 2px var(--fon);
}
@media (prefers-reduced-motion: no-preference) {
input[role="switch"]::before { transition: translate 0.15s; }
}
@media (forced-colors: active) {
input[role="switch"]::before { background: CanvasText; }
}
</style>
<h1>Sozlamalar</h1>
<p>
<input id="qorongi" type="checkbox" role="switch">
<label for="qorongi">Qorong'i rejim</label>
</p>
<p>
<input id="katta" type="checkbox" role="switch" checked>
<label for="katta">Katta shrift</label>
</p>Nimaga qarang: ikki o'chirgich. "Katta shrift" yoqilgan — yashil yo'lak, qaymoq "tugmacha" o'ngda. "Qorong'i rejim" o'chirilgan — oq yo'lak, kulrang tugmacha chapda. "Qorong'i rejim" ni bosing: tugmacha o'ngga suriladi va butun sahifa darhol qorong'i yashilga o'tadi — JavaScript'siz.
:root:has(#qorongi:checked)— "ichida belgilangan#qorongibor hujjat". O'chirgich yoqilishi bilancolor-scheme: darkbo'ladi va hammalight-dark()rang ikkinchi qiymatini oladi (Qorong'i rejim). O'chirgich semantikasiga aynan mos: darhol kuchga kiradi.- Cheklovi: sahifa yangilansa, tanlov unutiladi. Tanlovni eslab qolish —
localStorageva JavaScript ishi; «Bahor»dagitema-tanlash.jsaynan shuni qiladi, uning kodini 09-qismda tushuntiramiz. - Tugmacha o'lchami: yo'lak ichki balandligi 24 − 4 = 20 piksel, tugmacha har tomondan 2 piksel bo'shliq bilan — 16 piksel (
1.5rem - 8px). Siljish: 44 − 4 − 16 − 4 = 20 piksel =1.25rem. - Holat faqat rangda emas: tugmachaning joyi (chap/o'ng) — asosiy signal. Rangni ajratmaydigan odam ham farqni ko'radi.
Chrome'ning accessibility daraxtida tekshirdik: "Qorong'i rejim — switch, belgilanmagan", "Katta shrift — switch, belgilangan". Ekran o'quvchi odatda buni "o'chirgich, o'chiq/yoqiq" deb aytadi.
Tekshirib ko'ring: Bron formasida "SMS eslatma yuborilsin" uchun o'chirgich chizish to'g'rimi?
Javob
Yo'q. O'chirgich "darhol kuchga kiradi" deb va'da beradi. SMS esa faqat forma yuborilganda buyuriladi — mehmon o'chirgichni yoqib, formani yubormasa, SMS kelmaydi va u aldangandek his qiladi. Formada — checkbox, sozlamalarda — o'chirgich.
6. Prefiksli maydon va suzuvchi yorliq
6.1 Prefiks va suffiks
Telefon maydonida "+998" doim bir xil — mehmon uni yozmasin. Mehmonlar soni yonida "kishi". Bular maydon ichida ko'rinadigan, lekin tahrirlanmaydigan qismlar:
<style>
:root {
--rang-fon: #fffaf0;
--rang-matn: #1f2a24;
--rang-asosiy: #2f6b3a;
--rang-asosiy-toq: #1a5d1a;
--rang-ikkinchi: #5b6660;
}
body {
font-family: system-ui, sans-serif;
background: var(--rang-fon);
color: var(--rang-matn);
}
form > div {
display: grid;
gap: 0.25rem;
max-inline-size: 18rem;
margin-block-end: 1rem;
}
label { font-weight: 600; }
.maydon-guruh {
display: flex;
border: 2px solid var(--rang-ikkinchi);
border-radius: 0.5rem;
background: white;
overflow: clip;
}
.maydon-guruh:focus-within {
border-color: var(--rang-asosiy);
outline: 3px solid var(--rang-asosiy-toq);
outline-offset: 2px;
box-shadow: 0 0 0 2px var(--rang-fon);
}
.maydon-guruh span {
display: grid;
place-items: center;
padding-inline: 0.75em;
background: color-mix(in oklch, var(--rang-ikkinchi) 12%,
white);
color: var(--rang-ikkinchi);
}
.maydon-guruh input {
flex: 1;
min-inline-size: 0;
min-block-size: 2.75rem;
padding: 0.5em 0.75em;
border: 0;
background: transparent;
color: inherit;
font: inherit;
}
.maydon-guruh input:focus-visible { outline: none; }
</style>
<form action="https://example.com/bron" method="post">
<div>
<label for="telefon">Telefon raqamingiz</label>
<div class="maydon-guruh">
<span id="telefon-prefiks">+998</span>
<input id="telefon" name="telefon" type="tel"
autocomplete="tel-national" placeholder="90 000 00 00"
aria-describedby="telefon-prefiks">
</div>
</div>
<div>
<label for="odam">Mehmonlar soni</label>
<div class="maydon-guruh">
<input id="odam" name="odam" type="number" min="1" max="20"
value="4" aria-describedby="odam-birlik">
<span id="odam-birlik">kishi</span>
</div>
</div>
</form>Nimaga qarang: "+998" kulrang katakchada maydonning chap chetida, "kishi" — o'ng chetida. Telefon maydonini bosing: halqa ichki maydon atrofida emas, butun guruh atrofida chiqadi — prefiks ham ichida.
- Ramka o'ramda, maydonda emas. Ichki
input— chegarasiz va shaffof, ko'zga u butun guruhning bir qismi. :focus-within— "ichida fokus bor element" (Holat pseudo-klasslari). Halqa o'ramga ko'chdi, shuning uchun ichki maydonning o'z halqasi o'chirildi.:focus-withinBaseline, 2020-yildan.min-inline-size: 0— tor ekranda maydon siqila olsin (min-width: 0).- Prefiks o'qilishi kerak. Ko'z uni ko'radi, ekran o'quvchi esa maydon ichidagi matnni o'zi o'qimaydi.
aria-describedby="telefon-prefiks"bilan Malika "Telefon raqamingiz, +998" ni eshitadi. autocomplete="tel-national"— brauzer raqamni mamlakat kodisiz to'ldiradi (autocomplete), "+998" ikki marta yozilmaydi.maydon-guruh— namoyish class'i.
6.2 Suzuvchi yorliq
Ba'zi dizaynlarda yorliq maydon ichida turadi va yozishni boshlaganingizda tepaga "suzib" chiqadi. CSS'da buni :placeholder-shown qiladi — "namuna matni hozir ko'rinib turibdi", ya'ni maydon bo'sh:
.suzuvchi {
position: relative;
}
.suzuvchi input {
padding: 1.25em 0.75em 0.25em; /* tepada yorliq uchun joy */
}
.suzuvchi label {
position: absolute;
inset-block-start: 0.35em;
inset-inline-start: 0.75em;
transform-origin: left top;
scale: 0.75;
pointer-events: none;
}
/* Maydon bo'sh va fokussiz — yorliq o'rtada, katta */
.suzuvchi input:placeholder-shown:not(:focus) + label {
translate: 0 0.55em;
scale: 1;
}HTML'da maydonga bo'sh joydan iborat namuna qo'yiladi — placeholder=" " — aks holda :placeholder-shown hech qachon mos kelmaydi. input esa label dan oldin turadi (+ kombinatori uchun).
Ehtiyot bo'ling: bu uslub chiroyli, lekin muammolari ko'p. Yozish paytida yorliq kichrayib, qiyin o'qiladi. Brauzer avtomatik to'ldirganda ba'zan yorliq va matn ustma-ust tushadi. Namuna matn (masalan, telefon formati) uchun joy qolmaydi — u yordam matniga ko'chadi. Ko'p dizayn tizimlari (masalan, GOV.UK) yorliqni doim maydon ustida saqlaydi. Tanlov sizniki; «Bahor»da oddiy yorliq qoladi.
7. :autofill: brauzer to'ldirgan maydon
Mehmon "Ismingiz" maydonini bossa, brauzer saqlangan ismni taklif qiladi. Tanlangach, maydon brauzerning o'z rangiga bo'yaladi. Chrome'da bu och ko'k fon (#e8f0fe) — qaymoq formada begona dog'.
CSS'da bunday maydon — :autofill. Chrome'ning o'z stilini tekshirdik: fon va matn rangi u yerda !important bilan yozilgan. Kaskad darsidan eslang: brauzerning !important i muallifning !important idan ham kuchli. Tekshirdik — background-color: ... !important ham ishlamadi.
Nima qilish mumkin:
input:autofill {
border-color: var(--rang-asosiy);
/* Fonni ichki soya bilan "bo'yash" — soya fon ustida chiziladi */
box-shadow: inset 0 0 0 100px var(--rang-yuza);
}- Chegara, halqa, soya — ruxsat. Chrome'da tekshirdik: ichki soya och ko'k fonni butunlay yopdi, ramka yashil bo'ldi. Faqat tartibga e'tibor bering:
input:autofillvainput:not([type="radio"])bir xil og'irlikda —:autofillqoidasi maydon qoidasidan keyin tursin, aks holda ramka o'zgarmaydi. - Matn rangi ham brauzer qo'lida (
fieldtext). Qorong'i rejimda u muammo bo'lishi mumkin — eski kodlarda buning uchun-webkit-text-fill-colorni uchratasiz. - Brauzer rangi — foydali signal: "bu yerni men to'ldirdim, tekshiring". Uni butunlay yo'qotmang: ramka rangi bilan belgilab qo'yish yaxshi murosa.
:autofill Baseline emas: Baseline ma'lumotiga ko'ra Chrome, Edge va Safari'da bor, Firefox ro'yxatda yo'q. Ishlamagan joyda brauzerning o'z ko'rinishi qoladi — hech narsa buzilmaydi.
Tekshirib ko'ring: Nega
input:autofill { background-color: white !important; }Chrome'da ishlamaydi,box-shadow: inset ...esa ishlaydi?
Javob
Fon rangi Chrome'ning o'z stilida !important bilan yozilgan. Kaskadda brauzerning !important i sizning !important ingizdan kuchli — fon baribir och ko'k qoladi. box-shadow ni esa brauzer band qilmagan. Ichki soya fon ustida chiziladi va uni yopib qo'yadi.
8. «Bahor»ning komponentlar.css iga
Bron formasi uchun asosiy qoidalar (segmentli tanlov va prefiks — namoyish, «Bahor»ga kirmaydi):
/* === Forma (Forma komponentlari darsi) === */
form :is(div, fieldset) {
display: grid;
gap: var(--masofa-2xs);
}
form label {
font-weight: 600;
}
span[id$="-yordam"] {
font-size: var(--step--1);
color: var(--rang-ikkinchi);
}
span[id$="-xato"] {
font-size: var(--step--1);
font-weight: 600;
color: var(--rang-xato);
}
span[id$="-xato"]::before {
content: "⚠ " / "";
}
:is(input:not([type="checkbox"], [type="radio"]), select, textarea) {
min-block-size: 2.75rem;
padding: 0.5em 0.75em; /* shrift bilan o'sadi — ataylab em */
border: 2px solid var(--rang-ikkinchi);
border-radius: var(--burchak-m);
background: var(--rang-yuza);
color: var(--rang-matn);
}
/* Halqa — asos.css dagi umumiy ikki rangli :focus-visible */
:is(input, select, textarea):focus-visible {
border-color: var(--rang-asosiy);
}
:is(input, select, textarea):is(:user-invalid,
[aria-invalid="true"]) {
border-color: var(--rang-xato);
}
form div:has(> :is(:user-invalid, [aria-invalid="true"])) label {
color: var(--rang-xato);
}
form div:has(> :user-invalid) span[id$="-yordam"]::before {
content: "⚠ " / "Xato: ";
}
:is(input, select, textarea):disabled {
border-style: dashed;
background: transparent;
cursor: not-allowed;
}
input:autofill {
border-color: var(--rang-asosiy);
box-shadow: inset 0 0 0 100px var(--rang-yuza);
}
/* Checkbox va radio */
input:is([type="checkbox"], [type="radio"]) {
appearance: none;
flex: none;
display: inline-grid;
place-content: center;
inline-size: 1.5rem;
block-size: 1.5rem;
margin: 0;
border: 2px solid var(--rang-ikkinchi);
border-radius: var(--burchak-s);
background: var(--rang-yuza);
}
input[type="radio"] {
border-radius: 50%;
}
input:is([type="checkbox"], [type="radio"])::before {
content: "";
inline-size: 0.875rem;
block-size: 0.875rem;
background: var(--rang-fon);
scale: 0;
}
input[type="checkbox"]::before {
clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0,
43% 62%);
}
input[type="radio"]::before {
inline-size: 0.625rem;
block-size: 0.625rem;
border-radius: 50%;
}
input:is([type="checkbox"], [type="radio"]):checked {
border-color: var(--rang-asosiy);
background: var(--rang-asosiy);
}
input:is([type="checkbox"], [type="radio"]):checked::before {
scale: 1;
}
fieldset div:has(> [type="radio"]),
form p:has(> [type="checkbox"]) {
display: flex;
align-items: center;
gap: var(--masofa-xs);
}
@media (forced-colors: active) {
input::before {
background: CanvasText;
}
}form :is(div, fieldset)— bron formasidagi o'ramlar. subgrid darsidagi ogohlantirish: Chrome 154 dafieldsetsubgrid bo'lmaydi — shuning uchunfieldseto'z to'rini oladi, ota to'rga ulanmaydi.- Qorong'i rejimda
--rang-yuzava--rang-ikkinchio'zi o'zgaradi.--rang-xatoning qorong'i qiymati «Bahor» tokenlarida hali yo'q — uni yakuniy loyihada (Yakuniy loyiha: landing) palitra bilan birga qo'shasiz. - O'chirgich «Bahor» sozlamalar sahifasida bo'ladi — «O'chirgich (switch)» bo'limidagi qoidalar
[role="switch"]selektori bilan shu faylga qo'shiladi.
9. Ko'p uchraydigan xatolar
9.1 Placeholder — yorliq o'rnida
<input placeholder="Ismingiz">, label yo'q. Yozishni boshlagan zahoti "Ismingiz" yo'qoladi, ekran o'quvchi uchun nom ishonchsiz. Tuzatish: har doim label; namuna matn — faqat misol uchun.
9.2 Hamma bo'sh maydon ochilishda qizil
:invalid ishlatilgan. Tuzatish: :user-invalid.
9.3 Xato faqat qizil ramka
Rang ko'r odam va ekran o'quvchi xatoni bilmaydi. Tuzatish: belgi + so'z + ramka; xato matni aria-describedby bilan ulangan.
9.4 Checkbox display: none
Klaviatura va ekran o'quvchi uchun element yo'qoladi. Tuzatish: appearance: none yoki ko'rinmas qilib yashirish (opacity: 0 + position: absolute).
9.5 Majburiy ranglar rejimida belgi yo'q
::before belgisi fon rangi bilan chizilgan, rejim uni o'chirdi. Tuzatish: @media (forced-colors: active) { input::before { background: CanvasText; } }.
9.6 Och kulrang ramka
border: 1px solid #ddd — 1.4:1, maydon ko'rinmaydi. Tuzatish: kamida 3:1 kontrastli ramka.
10. Mashqlar
Mashqlarni kurs/mashqlar/06/ papkasida bajaring.
1-mashq (oson): muvaffaqiyat belgisi
Telefon maydoni to'g'ri to'ldirilgach (:user-valid), ramka yashil bo'lsin va yorliq yonida "" chiqsin. Ekran o'quvchi belgini o'qimasin.
Ishora: div:has(> :user-valid) label::after. Muqobil matnni bo'sh qiling: content: " ✓" / "". Muvaffaqiyat rangi — --rang-muvaffaqiyat (Rang nazariyasi: oklch(52% 0.13 150)).
Yechim
input:user-valid {
border-color: var(--rang-muvaffaqiyat);
}
div:has(> input:user-valid) label::after {
content: " ✓" / "";
color: var(--rang-muvaffaqiyat);
}Muqobil matn bo'sh — ekran o'quvchi uchun bu shunchaki bezak: maydon to'g'riligini brauzer baribir biladi. Ehtiyot bo'ling: har maydonga "" qo'yish formani shovqinli qiladi. Uni faqat xatoga moyil maydonlarda (telefon, email) ishlatish yaxshi.
2-mashq (o'rta): checkbox'ning uchinchi holati
"Hamma taomlarni tanlash" checkbox'i ba'zi taomlar tanlanganda qisman holatda ko'rinsin: yashil fon va ichida gorizontal chiziq ("−"). Bu holatni HTML atributi bilan emas, JavaScript indeterminate xususiyati bilan qo'yadi; CSS'da — :indeterminate.
Ishora: ::before ning shaklini almashtiring — clip-path: none va balandlikni kichraytiring. Holatni qo'yadigan qism JavaScript'da — uni 09-qismda o'rganasiz; bu mashqda faqat CSS tomoni.
Yechim
«Checkbox va radio» bo'limidagi qoidalarga qo'shiladi:
input:indeterminate {
border-color: var(--rang-asosiy);
background: var(--rang-asosiy);
}
input:indeterminate::before {
block-size: 0.1875rem;
clip-path: none;
scale: 1;
}Natija: yashil kvadrat, ichida qaymoq gorizontal chiziq — "qisman tanlangan". Chrome'da skript bilan indeterminate ni yoqib tekshirdik: ::before 14 × 3 piksellik chiziqqa aylandi, accessibility daraxtida holat — mixed (ekran o'quvchi "qisman belgilangan" deydi). Qoida «Checkbox va radio» dagi :checked qoidasidan keyin yozilsin: og'irligi bir xil, keyingisi yutadi. :indeterminate radio tugmada ham mos keladi — guruhda hech biri tanlanmagan bo'lsa. Shuning uchun uni input[type="checkbox"]:indeterminate deb toraytirsangiz, ishonchliroq.
3-mashq (qiyin): o'chirgichda holat so'zi
Katta yoshdagi mehmonlar o'chirgichni tushunmay qolmasin: yo'lak ichida "Yoq" / "O'ch" so'zlari ko'rinsin — tugmacha qarama-qarshi tomonda, so'z bo'sh tomonda. Ekran o'quvchi bu so'zlarni ikki marta eshitmasin.
Ishora: o'chirgichga ::after qo'shing va content ni holatga qarab almashtiring. Yo'lak eni so'z sig'ishi uchun kattaroq (masalan, 3.5rem), siljish ham qayta hisoblanadi. Muqobil matn — bo'sh.
Yechim
<style>
body { font-family: system-ui, sans-serif; background: #fffaf0; }
p { display: flex; align-items: center; gap: 0.75rem; }
input[role="switch"] {
appearance: none;
position: relative;
inline-size: 3.5rem;
block-size: 1.75rem;
margin: 0;
border: 2px solid #5b6660;
border-radius: 999px;
background: white;
font: inherit;
}
input[role="switch"]::before {
content: "";
position: absolute;
inset-block-start: 2px;
inset-inline-start: 2px;
inline-size: calc(1.75rem - 8px);
aspect-ratio: 1;
border-radius: 50%;
background: #5b6660;
}
input[role="switch"]::after {
content: "O'ch" / "";
position: absolute;
inset-block: 0;
inset-inline-end: 0.375rem;
display: grid;
place-items: center;
font-size: 0.6875rem;
font-weight: 600;
color: #5b6660;
}
input[role="switch"]:checked {
border-color: #2f6b3a;
background: #2f6b3a;
}
input[role="switch"]:checked::before {
translate: 1.75rem 0;
background: #fffaf0;
}
input[role="switch"]:checked::after {
content: "Yoq" / "";
inset-inline: 0.5rem auto;
color: #fffaf0;
}
input[role="switch"]:focus-visible {
outline: 3px solid #1a5d1a;
outline-offset: 2px;
box-shadow: 0 0 0 2px #fffaf0;
}
</style>
<p>
<input id="eslatma" type="checkbox" role="switch" checked>
<label for="eslatma">Aksiyalar haqida xabar</label>
</p>
<p>
<input id="ovoz" type="checkbox" role="switch">
<label for="ovoz">Ovozli bildirishnoma</label>
</p>Birinchi o'chirgichda "Yoq" chapda, tugmacha o'ngda; ikkinchisida tugmacha chapda, "O'ch" o'ngda. Siljish: yo'lak ichi 56 − 4 = 52, tugmacha 20, bo'shliqlar 2 + 2 → 52 − 20 − 4 = 28 piksel = 1.75rem. Muqobil matn bo'sh — Malika "o'chirgich, yoqilgan" ni eshitadi, "Yoq" so'zini ikkinchi marta emas. 11 piksellik so'z kichik, lekin u faqat qo'shimcha signal: asosiy — tugmacha joyi va rang.
4-mashq: Portfolio qadami — aloqa formasi komponentlari
Portfolio'ning aloqa formasi (Yakuniy loyiha): ism va email (form > p ichida label, span[id$="-yordam"], input), "Qaysi mavzuda?" radio guruhi (fieldset), xabar (textarea). Xato holati UI/UX asoslari darsida qo'shilgan.
- Matn maydonlari: 2 piksellik
--rang-ikkinchiramka,--burchak-mburchak, fokusda brend ramka + halqa, nofaol — punktir. Brauzerning standart ramkasi qolmasin. - "Qaysi mavzuda?" radio'lari segmentli tanlovga aylansin. HTML'da
inputo'zlabelidan oldin turibdi. - Avtomatik to'ldirilgan maydon qaymoq/qorong'i fonda begona ko'rinmasin.
- Qorong'i rejimda va majburiy ranglar rejimida tekshiring.
Ishora: portfolio'da class qo'shilmaydi — fieldset:has(> p > [type="radio"]). Radio'lar hozir fieldset p ichida, har biri alohida p da (Yakuniy loyiha). Segmentli tanlovda chetki elementlar — p:first-of-type, p:last-of-type.
Yechim
komponentlar.css dagi forma qismida input:not([type="radio"]), textarea qoidasini kengaytiring va yangi qoidalar qo'shing:
/* Matn maydonlari (Forma komponentlari darsi) */
input:not([type="radio"]),
textarea {
padding: 0.5em; /* shrift bilan o'sadi — ataylab em */
border: 2px solid var(--rang-ikkinchi);
border-radius: var(--burchak-m);
background-color: var(--rang-fon);
color: var(--rang-matn);
caret-color: var(--rang-asosiy);
}
:is(input, textarea):focus-visible {
border-color: var(--rang-asosiy);
}
:is(input, textarea):disabled {
border-style: dashed;
}
input:autofill {
border-color: var(--rang-asosiy);
box-shadow: inset 0 0 0 100px var(--rang-fon);
}
/* "Qaysi mavzuda?" — segmentli tanlov */
fieldset:has(> p > [type="radio"]) {
display: flex;
flex-wrap: wrap;
}
fieldset:has(> p > [type="radio"]) legend {
inline-size: 100%;
}
fieldset:has(> p > [type="radio"]) p {
margin: 0;
}
fieldset [type="radio"] {
position: absolute;
opacity: 0;
inline-size: 1px;
block-size: 1px;
}
fieldset [type="radio"] + label {
display: grid;
place-items: center;
min-block-size: 2.75rem;
padding-inline: 1em;
border: 2px solid var(--rang-asosiy);
color: var(--rang-asosiy);
cursor: pointer;
}
fieldset p:not(:first-of-type) [type="radio"] + label {
margin-inline-start: -2px;
}
fieldset p:first-of-type [type="radio"] + label {
border-start-start-radius: var(--burchak-m);
border-end-start-radius: var(--burchak-m);
}
fieldset p:last-of-type [type="radio"] + label {
border-start-end-radius: var(--burchak-m);
border-end-end-radius: var(--burchak-m);
}
fieldset [type="radio"]:checked + label {
background-color: var(--rang-asosiy);
color: var(--rang-fon);
font-weight: bold;
}
fieldset [type="radio"]:focus-visible + label {
position: relative;
outline: 2px solid var(--rang-asosiy);
outline-offset: 2px;
}
@media (forced-colors: active) {
fieldset [type="radio"]:checked + label {
border-width: 4px;
}
}- Oldingi
fieldset p { display: flex; ... }vainput:checked + label { font-weight: bold; }qoidalari endi keraksiz — yangi qoidalar ularni almashtiradi (qalinlik tanlangan chip ichida qoldi). Forma elementlarini stillash darsidagiform { accent-color }ham radio uchun ishlamay qoladi — u endi ko'rinmaydi; qatorni olib tashlasangiz bo'ladi. fieldsetramkasi (Yakuniy loyiha dagi karta ramkasi) qoladi — chiplar uning ichida.- Majburiy ranglar rejimida fon rangi o'chadi: tanlangan chip ham, qolganlari ham bir xil ramka bo'lib qoladi. Shuning uchun u yerda tanlanganini qalinroq ramka bilan ajratdik — rangga tayanmaydigan signal.
- Xato holati o'zgarmadi:
label:has(~ :user-invalid)va yordam matnidagi "" (UI/UX asoslari) ishlayveradi. Radio guruhida xato bo'lsa,legendqizaradi. - Qorong'i rejimda
--rang-fon,--rang-ikkinchiva--rang-asosiyo'zgaradi — ramkalar, chiplar va avtomatik to'ldirish soyasi ham moslashadi.
Tekshiring: Tab bilan radio guruhiga kiring va strelkalar bilan yuring. DevTools → Rendering → forced-colors active — tanlangan mavzu qalin ramkali. So'ng npm run check.
11. Real ishda
- Har bir mahsulotda formalar bor: ro'yxatdan o'tish, to'lov, buyurtma. Click va Payme kabi to'lov sahifalarida maydon holatlari juda aniq: prefiks (+998), maskalangan karta raqami, darhol xato matni.
- Dizayn tizimlari forma komponentlarini tugmadan keyin ikkinchi bo'lib quradi. GOV.UK Design System — accessible formalar bo'yicha eng ko'p o'rganiladigan namuna: yorliq doim tepada, xato matni maydon ustida, xatolar ro'yxati sahifa boshida.
- Kutubxonalar (React Hook Form, Zod — kursda keyinroq) xato holatini boshqaradi, lekin CSS qismi —
aria-invalid, xato matni, holatlar — bugun yozganimizdek qoladi. - Intervyuda so'raladi: "
:invalidva:user-invalidfarqi?", "Maxsus checkbox'ni qanday accessible qilasiz?", "Switch va checkbox qachon?", "Autofill fonini nega o'zgartirib bo'lmaydi?".
Xulosa
- Maydon — yorliq, yordam matni (maydondan oldin), maydon va xato matni bitta o'ramda; holat o'ramga
:has()bilan tarqaladi. - Xato —
:is(:user-invalid, [aria-invalid="true"]); rang + belgi + so'z. Xato matnini CSS bilan yashirib qo'ymang —aria-describedbyuni baribir o'qiydi. - Maxsus checkbox va radio —
appearance: none+::before; belgilangan holat fon bilan ham ko'rinsin, majburiy ranglar rejimida —CanvasText. - O'chirgich —
role="switch"li checkbox; u darhol kuchga kiradigan sozlama uchun.:has()bilan JavaScript'siz ta'sir ham berishi mumkin. - Radio'ni yashirib,
labelni bezash — segmentli tanlov; yashirishopacity: 0bilan,display: nonebilan emas. :autofillfoni va matni brauzer qo'lida; chegara va ichki soya — sizning qo'lingizda.
Keyingi dars: Modal oyna va skroll bloklash — bron formasi oynada ochiladi: orqa sahifa surilmasin, oyna telefonda pastdan chiqsin, uzun forma oyna ichida surilsin.
Manbalar
- MDN: ":user-invalid", ":user-valid", ":has()", "appearance", ":indeterminate", ":placeholder-shown", ":focus-within", ":autofill", "forced-colors", "ARIA: switch role" — developer.mozilla.org
- WCAG 2.2: 1.4.1 "Use of Color", 1.4.11 "Non-text Contrast", 3.3.1 "Error Identification" — w3.org/TR/WCAG22
- GOV.UK Design System: "Text input", "Error message" — design-system.service.gov.uk
- web-features (Baseline ma'lumotlari): "user-pseudos", "has", "appearance", "accent-color", "autofill", "focus-within", "placeholder-shown", "forced-colors" — github.com/web-platform-dx/web-features
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!