Keyboard navigatsiya — tabindex, focus boshqarish
Muammodan boshlaylik
20-darsdagi tajribani eslang: sichqonchasiz saytda harakat. Odatda uchraydigan muammolar:
- Tab bosasiz — fokus qayerda ekanini ko'rmaysiz
- Asosiy kontentga yetish uchun menyudagi 30 ta havoladan har safar o'tasiz
- Modal oyna ochildi — Tab bosilsa fokus oyna orqasidagi sahifaga ketib qoladi
- Modal yopildi — fokus sahifaning eng boshiga "uchib" ketdi
- Ba'zi "tugmalar" ga umuman yetib bo'lmaydi
Klaviatura bilan ishlaydigan foydalanuvchilar: ekran o'quvchi foydalanuvchilari, harakat cheklovlari bor odamlar, va ko'plab dasturchilar — tezlik uchun. Bu darsda — ularning hammasi uchun saytni qulay qilish.
Asosiy klaviatura tugmalari
| Tugma | Amal |
|---|---|
Tab |
Keyingi interaktiv elementga |
Shift + Tab |
Oldingisiga |
Enter |
Havolani ochish, tugmani bosish, formani yuborish |
Space |
Tugmani bosish, checkbox ni belgilash, sahifani pastga |
↑ ↓ ← → |
Radio guruh, select, tablar, menyu ichida harakat |
Esc |
Modal, menyu, ochilgan ro'yxatni yopish |
Home / End |
Ro'yxat yoki sahifa boshi / oxiri |
Tabiiy fokus tartibi
Tab bilan avtomatik ravishda tanlanadigan elementlar:
<a href>(faqathrefbilan!)<button><input>,<select>,<textarea><summary>(<details>ichida)contenteditableelementlar
Tartib — HTML dagi tartib (DOM tartibi), ekranda qanday ko'rinishidan qat'i nazar.
[!WARNING] CSS bilan vizual tartibni o'zgartirsangiz (
flex-direction: row-reverse,order, Grid joylashuvi,position: absolute), Tab tartibi o'zgarmaydi — fokus ekranda u yoqdan bu yoqqa sakraydi. Mantiqiy tartibni HTML da to'g'ri yozing, CSS faqat ko'rinish uchun (CSS kursi, 15 va 19-darslar).
Fokus ko'rinsin
/* ❌ eng ko'p uchraydigan accessibility xatosi */
*:focus {
outline: none;
}
Bu bilan klaviatura foydalanuvchisi qayerda ekanini ko'rmaydi — xuddi sichqoncha kursorini yashirgandek.
/* ✅ faqat klaviatura bilan ishlaganda */
:focus-visible {
outline: 2px solid #2563eb;
outline-offset: 2px;
}
/* sichqoncha bilan bosilganda — chiziqsiz */
:focus:not(:focus-visible) {
outline: none;
}
:focus-visible — brauzer o'zi hal qiladi: klaviatura bilan kelinganda fokus ko'rsatiladi, sichqoncha bosilganda — yo'q. Dizaynerning "bosilganda ko'k ramka xunuk" degan e'tiroziga ham yechim.
Fokus belgisi yaxshi ko'rinsin: kontrast kamida 3 : 1, qalinligi kamida 2px, fon bilan qo'shilib ketmasin.
tabindex
<div tabindex="0">...</div> <!-- tabiiy tartibga qo'shiladi -->
<div tabindex="-1">...</div> <!-- Tab bilan emas, faqat JS bilan fokuslanadi -->
<div tabindex="3">...</div> <!-- ❌ hech qachon -->
| Qiymat | Ma'nosi | Qachon |
|---|---|---|
0 |
Tab tartibiga HTML joylashuvi bo'yicha qo'shish | Fokuslanadigan maxsus vidjet (ARIA bilan) |
-1 |
Tab bilan yo'q, lekin element.focus() ishlaydi |
Modal sarlavhasi, xato xabari, "skip link" maqsadi |
1+ |
Hammadan oldin, raqam tartibida | Hech qachon — butun sahifa tartibini buzadi |
[!WARNING]
tabindex="0"ni<div>ga qo'shish uni tugmaga aylantirmaydi — faqat fokuslanadigan qiladi. Enter va Space ishlamaydi, ekran o'quvchi "tugma" demaydi. Agar element bosiladigan bo'lsa —<button>ishlating (21-dars, ARIA ning birinchi qoidasi).
Fokusdan chiqarish — inert
<main inert>...</main>
<dialog open>...</dialog>
inert atributi — element va uning barcha ichidagilarini fokusdan, bosishdan va ekran o'quvchidan chiqaradi. Modal ochilganda orqadagi sahifa uchun, yopiq yon panel uchun ideal.
Skip link — "asosiy kontentga o'tish"
Sahifaning eng birinchi havolasi:
<body>
<a href="#asosiy" class="skip-link">Asosiy kontentga o'tish</a>
<header>
<nav>...30 ta havola...</nav>
</header>
<main id="asosiy" tabindex="-1">
...
</main>
</body>
.skip-link {
position: absolute;
left: 1rem;
top: -100px;
}
.skip-link:focus {
top: 1rem; /* Tab bosilganda ko'rinadi */
}
Birinchi Tab — "Asosiy kontentga o'tish" paydo bo'ladi, Enter — menyuni chetlab o'tadi. Darsning boshidagi 2-muammo hal. Ko'plab yirik saytlarda (GitHub, GOV.UK) bor — ularda Tab bosib ko'ring.
Fokusni boshqarish — JavaScript
Sahifa dinamik o'zgarganda fokusni o'zingiz boshqarishingiz kerak.
Modal oyna — dialog
<button id="ochish">Kirish</button>
<dialog id="modal" aria-labelledby="modal-sarlavha">
<h2 id="modal-sarlavha">Tizimga kirish</h2>
<form method="dialog">
<label for="m-email">Email</label>
<input id="m-email" type="email">
<button>Yopish</button>
</form>
</dialog>
ochish.addEventListener('click', () => modal.showModal());
showModal() bilan ochilgan <dialog> hammasini o'zi qiladi:
- Fokus ichkaridagi birinchi elementga o'tadi
- Orqadagi sahifa
inert— Tab oynadan chiqmaydi (3-muammo) - Esc bilan yopiladi
- Yopilganda fokus uni ochgan tugmaga qaytadi (4-muammo)
Ilgari bularning hammasi uchun o'nlab qator JavaScript kerak edi — bugun bitta teg.
SPA da sahifa almashganda
Sahifa yangilanmasdan kontent o'zgarsa (React, Vue, DevDocs kabi SPA), ekran o'quvchi buni sezmaydi va fokus eski joyda qoladi:
function sahifaAlmashdi() {
const sarlavha = document.querySelector('main h1');
sarlavha.setAttribute('tabindex', '-1');
sarlavha.focus(); // ekran o'quvchi yangi sarlavhani o'qiydi
}
Element o'chirilganda
Ro'yxatdan element o'chirilsa, fokus u bilan birga yo'qoladi va sahifaning boshiga ketadi. Fokusni keyingi elementga yoki ro'yxat sarlavhasiga o'tkazing:
function ochir(item) {
const keyingi = item.nextElementSibling ?? item.previousElementSibling;
item.remove();
keyingi?.querySelector('button')?.focus();
}
Maxsus vidjetlar — roving tabindex
Tablar, menyular, asboblar paneli kabi guruhlar ichida strelkalar bilan harakatlanish kutiladi, Tab esa guruhdan chiqishi kerak:
<div role="tablist" aria-label="Kurslar">
<button role="tab" aria-selected="true" tabindex="0">HTML</button>
<button role="tab" aria-selected="false" tabindex="-1">CSS</button>
<button role="tab" aria-selected="false" tabindex="-1">JavaScript</button>
</div>
tablist.addEventListener('keydown', (e) => {
const tabs = [...tablist.querySelectorAll('[role="tab"]')];
const i = tabs.indexOf(document.activeElement);
let keyingi;
if (e.key === 'ArrowRight') keyingi = tabs[(i + 1) % tabs.length];
if (e.key === 'ArrowLeft') keyingi = tabs[(i - 1 + tabs.length) % tabs.length];
if (!keyingi) return;
tabs[i].tabIndex = -1;
keyingi.tabIndex = 0;
keyingi.focus();
});
Faqat bitta element tabindex="0" — guruhga Tab bilan bir marta kiriladi, ichida — strelkalar. To'liq namunalar — ARIA Authoring Practices Guide da (21-dars).
Tekshiruv ro'yxati
Har bir sahifada sichqonchasiz:
- Barcha havolalar, tugmalar va maydonlarga Tab bilan yetib boriladi
- Fokus har doim aniq ko'rinadi
- Tab tartibi mantiqiy — ekrandagi tartibga mos
- Hamma narsa Enter/Space bilan ishlaydi
- Skip link bor va ishlaydi
- Modal: fokus ichida qoladi, Esc yopadi, fokus qaytadi
- Hech qayerda "tuzoq" yo'q — Tab bilan kirib, chiqib bo'lmaydigan joy
- Yashirin elementlar (yopiq menyu) Tab bilan tanlanmaydi
Nima uchun shunday?
Nima uchun klaviatura navigatsiyasi accessibility ning eng muhim qismlaridan biri hisoblanadi?
Chunki deyarli barcha yordamchi texnologiyalar klaviatura orqali ishlaydi. Ekran o'quvchilar klaviatura buyruqlari bilan boshqariladi. Bitta tugmali qurilmalar (switch), og'iz bilan boshqariladigan tayoqchalar, ko'z harakatini kuzatuvchi tizimlar, ovozli boshqaruv — ularning hammasi brauzerga klaviatura hodisalari sifatida yetib keladi. Ya'ni sayt klaviatura bilan ishlasa, u o'nlab turli vositalar bilan ishlaydi. Klaviatura bilan ishlamasa — ularning hech biri bilan. Va eng yaxshi xabar: tabiiy HTML elementlari (<button>, <a href>, <input>, <dialog>) buni allaqachon bepul beradi — muammolar faqat biz ularni div lar bilan almashtirganda boshlanadi.
Xulosa
Eslab qoling:
- Tab / Shift+Tab — harakat; Enter / Space — amal; strelkalar — guruh ichida; Esc — yopish
- Fokus tartibi — HTML tartibi; CSS bilan vizual tartibni buzmang
outline: none— hech qachon;:focus-visiblebilan chiroyli fokustabindex="0"— tartibga qo'shish;-1— faqat JS; musbat — hech qachoninert— butun blokni fokusdan chiqarish- Skip link — sahifaning birinchi havolasi
<dialog>+showModal()— fokus, Esc, inert va qaytarish bepul- SPA da sahifa almashganda va element o'chirilganda — fokusni o'zingiz boshqaring
Kurs yakunlandi
Tabriklaymiz — HTML kursini tugatdingiz! Endi siz sahifa tuzilishini, semantik teglarni, meta ma'lumotlarni, formalarni va accessibility asoslarini bilasiz.
Keyingi qadam — CSS kursi: sahifangizni chiroyli, moslashuvchan va jonli qilish.