ARIA — role, aria-label, aria-hidden, aria-expanded

~20 daq · HTML · Accessibility

Muammodan boshlaylik

Saytdagi uchta element:

<button><svg>...</svg></button>                 <!-- faqat ikonka -->
<button class="burger">☰</button>               <!-- mobil menyu -->
<span class="badge">3</span>                     <!-- o'qilmagan xabarlar -->

Ekran o'quvchi nima deydi?

  • Birinchisi: "tugma" — qaysi tugma? Qidiruvmi, yopishmi, sozlamalarmi?
  • Ikkinchisi: "uch chiziqli belgi, tugma" — menyu ochiqmi yoki yopiqmi — noma'lum
  • Uchinchisi: "3" — uchta nima?

Ko'rgan foydalanuvchi ikonka va kontekstdan tushunadi. Ekran o'quvchi foydalanuvchisi — yo'q. HTML da bu ma'lumotni ifodalash uchun teg yo'q. Bu bo'shliqni ARIA to'ldiradi.


ARIA nima

ARIA (Accessible Rich Internet Applications) — HTML elementlariga qo'shimcha ma'no beradigan atributlar to'plami. Ular:

  • Elementning roli — u nima (role="dialog")
  • Nomi — u qanday ataladi (aria-label="Qidirish")
  • Holati — u qanday holatda (aria-expanded="true")

ARIA faqat yordamchi texnologiyalar (ekran o'quvchilar) uchun. U ko'rinishni, xatti-harakatni yoki klaviatura bilan ishlashni o'zgartirmaydi.


ARIA ning birinchi qoidasi

[!WARNING] Agar mos keladigan HTML elementi bo'lsa — ARIA emas, o'shani ishlating. Bu rasmiy qoida. <div role="button"> — tugma deb e'lon qiladi, lekin Tab bilan tanlanmaydi, Enter bilan bosilmaydi, forma yubormaydi — bularning hammasini qo'lda yozish kerak. <button> esa hammasini bepul beradi. Statistika ham shuni ko'rsatadi: ARIA ishlatilgan sahifalarda o'rtacha ko'proq accessibility xatolari topiladi — chunki noto'g'ri ishlatilgan ARIA yo'q ARIA dan yomonroq.

<!-- ❌ -->
<div role="button" tabindex="0" onclick="..." onkeydown="...">Saqlash</div>
<span role="link" onclick="...">Kurslar</span>
<div role="navigation">...</div>

<!-- ✅ -->
<button>Saqlash</button>
<a href="/kurslar">Kurslar</a>
<nav>...</nav>

ARIA — HTML yetmaganda kerak: ikonkali tugmalarga nom berish, ochiladigan menyuning holati, modal oyna, tablar, dinamik xabarlar.


Nom berish

aria-label — ko'rinmas nom

<button aria-label="Qidirish">
  <svg aria-hidden="true">...</svg>
</button>

🔊 "Qidirish, tugma"

Ko'rinadigan matni yo'q elementlar uchun: ikonkali tugmalar, "✕" yopish tugmasi.

<button aria-label="Yopish">✕</button>

<nav aria-label="Asosiy menyu">...</nav>
<nav aria-label="Kurs mundarijasi">...</nav>   <!-- bir nechta nav ni farqlash (10-dars) -->

aria-labelledby — boshqa elementdan nom

<section aria-labelledby="kurslar-sarlavha">
  <h2 id="kurslar-sarlavha">Mashhur kurslar</h2>
  ...
</section>

Nom sahifada allaqachon ko'rinib turgan bo'lsa — uni takrorlash o'rniga id orqali bog'lang.

aria-describedby — qo'shimcha izoh

<label for="parol">Parol</label>
<input id="parol" type="password" aria-describedby="parol-izoh">
<p id="parol-izoh">Kamida 8 belgi, bitta raqam bilan</p>

🔊 "Parol, parol maydoni, Kamida 8 belgi, bitta raqam bilan"

Nom — qisqa ("Parol"); izoh — qo'shimcha ma'lumot (talablar, xato xabari).

[!INFO] aria-label ko'rinadigan matnni almashtiradi. <button aria-label="Yuborish">Saqlash</button> — ko'rgan foydalanuvchi "Saqlash" ni, ekran o'quvchi "Yuborish" ni eshitadi. Ovoz bilan boshqaruvchi foydalanuvchi "Saqlashni bos" deydi — va ishlamaydi. Ko'rinadigan matn bor bo'lsa — aria-label qo'shmang.


aria-hidden — yashirish

<button>
  <svg aria-hidden="true">...</svg>
  Saqlash
</button>

<span aria-hidden="true">★★★★☆</span>
<span class="sr-only">5 dan 4 baho</span>

aria-hidden="true" — elementni ekran o'quvchidan yashiradi (ekranda ko'rinadi). Qachon:

  • Bezak ikonkalar — yonida matn bor
  • Takrorlanuvchi ma'lumot
  • Ma'nosiz belgilar (★★★★☆ — "qora yulduz, qora yulduz..." deb o'qiladi)

sr-only — teskarisi

Ekranda ko'rinmaydi, lekin ekran o'quvchi o'qiydi:

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
<span class="badge">3 <span class="sr-only">o'qilmagan xabar</span></span>

🔊 "3 o'qilmagan xabar" — darsning boshidagi 3-muammo hal.

[!WARNING] Fokuslanadigan elementga (tugma, havola, input) yoki ularni o'z ichiga olgan blokka hech qachon aria-hidden="true" qo'ymang. Klaviatura foydalanuvchisi Tab bilan unga yetib boradi, lekin ekran o'quvchi hech narsa demaydi — "ko'rinmas" tugma. Elementni hammadan yashirish kerak bo'lsa — hidden atributi yoki display: none.


Holatlar

aria-expanded — ochiq yoki yopiq

<button aria-expanded="false" aria-controls="mobil-menyu">
  <span aria-hidden="true">☰</span>
  <span class="sr-only">Menyu</span>
</button>

<ul id="mobil-menyu" hidden>
  <li><a href="/kurslar">Kurslar</a></li>
  ...
</ul>
const btn = document.querySelector('[aria-controls="mobil-menyu"]');
const menyu = document.getElementById('mobil-menyu');

btn.addEventListener('click', () => {
  const ochiq = btn.getAttribute('aria-expanded') === 'true';
  btn.setAttribute('aria-expanded', String(!ochiq));
  menyu.hidden = ochiq;
});

🔊 "Menyu, tugma, yopiq" → bosilgandan keyin → "Menyu, tugma, ochiq"

Darsning boshidagi 2-muammo hal. Ochiladigan menyular, akkordeonlar, "batafsil" bloklari uchun.

Bonus — holatni CSS bilan ham ishlatish mumkin (14-dars):

[aria-expanded="true"] .ikonka { rotate: 180deg; }

Boshqa ko'p ishlatiladigan holatlar

Atribut Ma'nosi Misol
aria-current="page" Joriy sahifa Menyudagi faol havola
aria-pressed="true" Bosilgan holatdagi tugma "Yoqtirish", "Qalin" tugmasi
aria-selected="true" Tanlangan Faol tab
aria-invalid="true" Xato qiymat Validatsiyadan o'tmagan maydon
aria-disabled="true" O'chirilgan (lekin fokuslanadi) Sababini tushuntirish mumkin bo'lgan tugma
aria-busy="true" Yuklanmoqda Yangilanayotgan ro'yxat

role — rol

<div role="alert">Xatolik: to'lov amalga oshmadi</div>

<div role="tablist">
  <button role="tab" aria-selected="true">HTML</button>
  <button role="tab" aria-selected="false">CSS</button>
</div>

HTML da mos teg bo'lmagan murakkab vidjetlar uchun: tablist/tab/tabpanel, dialog, alert, status, menu, tooltip, progressbar.

[!TIP] Murakkab vidjetlarni (tablar, menyular, combobox) noldan yozishdan oldin ARIA Authoring Practices Guide (APG) ni oching — W3C ning rasmiy qo'llanmasi. Unda har bir vidjet uchun kerakli rollar, holatlar va klaviatura xatti-harakati namunalari bor. Modal oynalar uchun esa tayyor <dialog> elementi mavjud — u fokusni boshqarish va Esc bilan yopishni o'zi qiladi.


Jonli hududlar — dinamik xabarlar

Sahifa yangilanmasdan paydo bo'lgan xabarni ekran o'quvchi sezmaydi: "Savatga qo'shildi", "Saqlandi", "3 ta natija topildi".

<div aria-live="polite" class="sr-only" id="xabar"></div>
document.getElementById('xabar').textContent = "Mahsulot savatga qo'shildi";

🔊 "Mahsulot savatga qo'shildi" — joriy o'qishni tugatgandan keyin

  • aria-live="polite" — foydalanuvchini to'xtatmasdan, navbat bilan (ko'p hollarda)
  • aria-live="assertive" yoki role="alert" — darhol, to'xtatib (faqat jiddiy xatolar)
  • Element sahifada oldindan bo'lishi kerak — matn keyin qo'shiladi

Nima uchun shunday?

Nima uchun ARIA faqat "e'lon qiladi", lekin xatti-harakat bermaydi — role="button" yozilsa, brauzer Enter bilan bosishni ham qo'shib bera olmasmidi?

Chunki ARIA mavjud veb-ilovalarni tuzatish uchun yaratilgan. 2000-yillarda JavaScript bilan murakkab interfeyslar paydo bo'ldi — va ular allaqachon div lardan yasalgan, o'z xatti-harakati bilan. Agar ARIA xatti-harakatni ham o'zgartirganida, bu saytlar buzilib ketardi. Shuning uchun ARIA atayin "faqat ma'no qatlami" qilib yaratildi: u yordamchi texnologiyalarga nima ekanini aytadi, qanday ishlashi esa dasturchining zimmasida qoladi. Natija — ARIA kuchli, lekin xavfli vosita: noto'g'ri e'lon yolg'on va'da beradi. Shuning uchun birinchi qoida: avval tabiiy HTML.


Xulosa

Eslab qoling:

  • ARIA — ekran o'quvchilar uchun rol, nom va holat; xatti-harakatni bermaydi
  • 1-qoida: mos HTML elementi bo'lsa — ARIA emas, o'sha
  • aria-label — ko'rinadigan matni yo'q elementlar uchun; aria-labelledby, aria-describedby
  • aria-hidden="true" — bezaklarni yashirish; fokuslanadigan elementlarga — hech qachon
  • .sr-only — ko'rinmas, lekin o'qiladigan matn
  • aria-expanded, aria-current, aria-pressed, aria-invalid — holatlar; JS bilan yangilang
  • aria-live="polite" — dinamik xabarlar
  • Murakkab vidjetlar — APG qo'llanmasi; modal — <dialog>

Keyingi dars

22-dars: Keyboard navigatsiya — tabindex, focus boshqarish