ARIA — Semantics, Name, State, Patterns
ARIA qachon kerak va qachon zarar ekanini o'rganing, accessible name va state'ni to'g'ri boshqarishni va ARIA'ning 3 ta oltin qoidasini tushunish. ARIA interaktivlik bermaydi—faqat screen reader'ga ma'lumot beradi.
9-dars
ARIA — Semantics, Name, State, Patterns
🎯 Maqsad: ARIA'ni "yopishtirish" emas, qachon kerak / qachon zarar ekanini bilish, va accessible name + state ni to'g'ri boshqarish.
0️⃣ ARIA'ning 3 ta oltin qoidasi
Qoida 1: Avval HTML (Native element bo'lsa ARIA ishlatma)
<!-- ✅ To'g'ri -->
<button>Save</button>
<!-- ❌ Noto'g'ri -->
<div role="button">Save</div>
Native HTML elementlar o'zida accessibility, keyboard qo'llab-quvvatlash va semantics'ga ega. ARIA faqat native elementlar mavjud bo'lmaganda ishlatilishi kerak.
Qoida 2: ARIA interaktivlik bermaydi
ARIA faqat screen reader'ga ma'lumot beradi. U quyidagilarni qilmaydi:
- Tab fokus qo'shmaydi
- Enter/Space behavior bermaydi
- Click funksiyasini bermaydi
- UI'ni "accessible" qilib qo'ymaydi
Keyboard behavior va interaktivlikni JavaScript bilan implement qilish kerak.
Qoida 3: ARIA state'lar JS bilan sync bo'lishi shart
Agar aria-expanded="true" qo'ysangiz, lekin UI panel yopiq ko'rsatsa, yolg'on UI yaratdingiz. Screen reader foydalanuvchilari chalkashadi.
// ✅ To'g'ri: State UI bilan sync
button.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
// ❌ Noto'g'ri: State UI bilan mos kelmaydi
button.setAttribute('aria-expanded', 'true'); // Lekin panel yopiq!
1️⃣ ARIA nima qiladi, nima qilmaydi
ARIA qiladi:
- Element "kim" ekanini aytadi (role)
- Holatini aytadi (state)
- Bog'lanishlarini aytadi (property)
- Screen reader o'qiydigan nom/izohni boshqaradi
ARIA qilmaydi:
- ❌ Tab fokus qo'shmaydi
- ❌ Enter/Space behavior bermaydi
- ❌ Click ishlatib bermaydi
- ❌ UI'ni "accessible" qilib qo'ymaydi (faqat xabar beradi)
2️⃣ ARIA'ning tuzilishi: Role / State / Property
A) role — "bu nima?"
role screen reader'ga element nima ekanligini aytadi.
Keng tarqalgan role'lar:
role="navigation"role="dialog"role="tablist"role="tab"role="tabpanel"role="menu"role="menuitem"role="listbox"role="option"role="switch"
Qoidasi: role faqat native HTML yo'q bo'lsa ishlatiladi.
<!-- ✅ To'g'ri: Custom tabs -->
<div role="tablist">
<button role="tab">Tab 1</button>
<button role="tab">Tab 2</button>
</div>
<div role="tabpanel">Content</div>
<!-- ❌ Noto'g'ri: Native button mavjud -->
<div role="button">Click me</div>
<!-- <button>Click me</button> bo'lishi kerak -->
B) state — "hozir holati qanday?"
State elementning hozirgi holatini tasvirlaydi.
Keng tarqalgan state'lar:
aria-expanded="true|false"(ochiq/yopiq)aria-checked="true|false"(checkbox/switch)aria-selected="true|false"(tabs/options)aria-pressed="true|false"(toggle button)aria-disabled="true"(o'chirilgan)aria-hidden="true"(screen reader'dan yashirish)
Qoidasi: State har doim real UI bilan bir xil bo'lishi kerak (JS bilan sync).
<!-- ✅ To'g'ri: State UI bilan mos -->
<button aria-expanded="true" aria-controls="panel">
Open Panel
</button>
<div id="panel">Content</div>
<script>
button.addEventListener('click', () => {
const isOpen = panel.classList.toggle('open');
button.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
});
</script>
C) property — "nimalar bilan bog'langan?"
Property bog'lanishlar va qo'shimcha ma'lumotlarni tasvirlaydi.
Keng tarqalgan property'lar:
aria-controls="id"(qaysi panelni boshqaradi)aria-labelledby="id"(nomini qayerdan oladi)aria-describedby="id"(izoh qayerdan)aria-live="polite|assertive"(dynamic xabarlar)aria-modal="true"(modal context)aria-current="page"(nav'da current page)
3️⃣ Accessible Name (Eng muhim mavzu)
Screen reader elementni o'qiganda 1-chi savol: "nomi nima?"
Name berish tartibi (amaliy qoida)
- Visible text (masalan, button ichidagi "Save")
aria-labelledby="id"(tashqaridagi matndan nom olish)aria-label="..."(so'nggi chora)
Qoidasi:
- Ko'rinadigan label bor bo'lsa →
aria-labelledby - Visible label yo'q bo'lsa (faqat icon) →
aria-label
<!-- ✅ To'g'ri: Ko'rinadigan label -->
<button aria-labelledby="save-label">
<span id="save-label">Save</span>
</button>
<!-- ✅ To'g'ri: Faqat icon -->
<button aria-label="Save">
<svg>...</svg>
</button>
<!-- ❌ Noto'g'ri: Accessible name yo'q -->
<button>
<svg>...</svg>
</button>
aria-labelledby vs aria-describedby
- aria-labelledby → nom ("bu nima?")
- aria-describedby → izoh ("qo'shimcha info")
<button aria-labelledby="btn-name" aria-describedby="btn-desc">
<span id="btn-name">Submit</span>
</button>
<span id="btn-desc">Bu form ma'lumotlaringizni yuboradi</span>
Screen reader: "Submit, button. Bu form ma'lumotlaringizni yuboradi"
4️⃣ Eng ko'p ishlatiladigan ARIA'lar (cheat-sheet)
Toggle / Dropdown / Filter panel
<button
aria-expanded="false"
aria-controls="panel"
id="toggle-btn"
>
Toggle Panel
</button>
<div id="panel" aria-labelledby="toggle-btn">
Content
</div>
Toggle button (like/subscribe)
<button aria-pressed="false">
Like
</button>
Tabs
<div role="tablist">
<button
role="tab"
aria-selected="true"
aria-controls="panel-1"
tabindex="0"
>
Tab 1
</button>
<button
role="tab"
aria-selected="false"
aria-controls="panel-2"
tabindex="-1"
>
Tab 2
</button>
</div>
<div role="tabpanel" id="panel-1" aria-labelledby="tab-1">
Content 1
</div>
<div role="tabpanel" id="panel-2" aria-labelledby="tab-2">
Content 2
</div>
(ko'pincha) tabindex="0|-1" bilan roving tabindex pattern ishlatiladi.
Listbox / Combobox (custom select)
<div role="combobox" aria-expanded="false" aria-controls="listbox">
<input aria-autocomplete="list" aria-controls="listbox">
<ul role="listbox" id="listbox">
<li role="option" aria-selected="false">Option 1</li>
<li role="option" aria-selected="true">Option 2</li>
</ul>
</div>
Modal/dialog (custom bo'lsa)
<div role="dialog" aria-modal="true" aria-labelledby="dialog-title" aria-describedby="dialog-desc">
<h2 id="dialog-title">Tasdiqlash</h2>
<p id="dialog-desc">Ishonchingiz komilmi?</p>
<button>OK</button>
</div>
Live feedback (toast, "Saved!")
<!-- Polite: qulay bo'lganda o'qiydi -->
<div role="status" aria-live="polite">
Saqlandi!
</div>
<!-- Assertive: darhol o'qiydi -->
<div role="alert" aria-live="assertive">
Xato: Noto'g'ri kirish
</div>
Navigation current
<nav>
<a href="/home" aria-current="page">Home</a>
<a href="/about">About</a>
</nav>
5️⃣ Live Regions — dynamic kontentni "gapirtirish"
Agar UI'da matn o'zi o'zgarib qolsa (AJAX, toast, validation), screen reader buni ko'rmay qolishi mumkin.
aria-live="polite"→ tinch, keyinroq o'qiydi (status, "Saved")aria-live="assertive"→ darhol (critical error)
Qoida: keragidan ortiq assertive ishlatma — foydalanuvchini "bosib ketadi".
<!-- ✅ To'g'ri: Non-critical yangilanishlar uchun polite -->
<div role="status" aria-live="polite" id="status">
<!-- JS orqali yangilanadi -->
</div>
<!-- ✅ To'g'ri: Critical xatolar uchun assertive -->
<div role="alert" aria-live="assertive" id="error">
<!-- Critical xato -->
</div>
6️⃣ aria-hidden va "yashirish" (katta xatolar shu yerda)
aria-hidden="true"→ faqat screen reader'dan yashiriladihidden/display:none→ ham ko'rinmaydi, ham SR ko'rmaydi
Xato pattern: Modal ochilganda orqa fonni faqat vizual yashirib qo'yib, SR uchun ochiq qoldirish.
<!-- ❌ Noto'g'ri: Background hali ham SR uchun accessible -->
<div class="modal-backdrop" style="opacity: 0;">
<!-- Screen reader hali ham bu yerga navigatsiya qila oladi -->
</div>
<!-- ✅ To'g'ri: Modal ochilganda SR'dan yashirish -->
<div class="modal-backdrop" aria-hidden="true">
<!-- Screen reader'dan yashirilgan -->
</div>
7️⃣ Eng xavfli 10 ta xato (checklist)
- ❌ Native element bor joyda
roleishlatish - ❌
aria-expandedbor, lekin JS update qilmaydi - ❌
aria-controlsid noto'g'ri (mavjud emas) - ❌ Icon button'da label yo'q (
aria-label/aria-labelledbyyo'q) - ❌
aria-hidden="true"bosiladigan narsaga qo'yilgan - ❌
role="button"qo'yib, keyboard behavior yozilmagan - ❌
aria-disabled="true"qo'yib, real disabled emas (action baribir ishlaydi) - ❌
aria-describedbybilan error text ulanganmadi - ❌
aria-livehamma joyga qo'yilgan (shovqin) - ❌ ARIA bilan "semanticsni" tuzataman deb, asl HTML'ni buzish
8️⃣ Minimal "qachon ARIA kerak?" qaror daraxti
Native HTML bormi?
├─ Ha → ARIA yo'q
└─ Yo'q → Davom et
Icon-only buttonmi?
├─ Ha → aria-label yoki aria-labelledby
└─ Yo'q → Davom et
Biror narsa ochilib-yopiladimi?
├─ Ha → aria-expanded + aria-controls (JS sync)
└─ Yo'q → Davom et
Custom widgetmi (tabs/combobox)?
├─ Ha → role + state + keyboard spec
└─ Yo'q → Ehtimol ARIA kerak emas
Umumiy xulosa
ARIA — bu accessibility uchun "plastir" emas, bu screen reader'lar uchun muloqot vositasi. 3 ta oltin qoida: avval HTML, ARIA interaktivlik bermaydi, va ARIA state'lar JS bilan sync bo'lishi kerak.