🏫 The School›📌 UI›♿ धडा 06 — Accessibility: प्रत्येकजण फलक वाचू शकतो
🖼️ See the drawing + lab 🏠 Course home 🌿 Branch on GitHub ✏️ View source
🖼️ आकृती आणि labThe drawing + lab पूर्ण पानावर उघडा ↗Open full page ↗

♿ धडा 06 — Accessibility: प्रत्येकजण फलक वाचू शकतो

📍 तुम्ही इथे आहात: 12 पैकी धडा 06 · मागे: lesson-05-state-components · पुढे: lesson-07-frameworks


📦 या ब्रँचमध्ये काय आहे

धडे 01–05, आणि फलक प्रत्येकासाठी चालतो की नाही हे ठरवणारा धडा: keyboard, प्रत्येक control साठी नावे, contrast, focus, live regions, आणि ARIA चे प्रामाणिक नियम.

🧒 5 वर्षांच्या मुलाला समजावल्यासारखे

कल्पना करा की तुम्ही दिवे बंद असताना फलक वाचत आहात, आणि एक मदतनीस तो मोठ्याने वाचून दाखवत आहे (screen reader). किंवा तुमचे हात mouse वापरू शकत नाहीत, म्हणून तुम्ही Tab ने पुढे जाता आणि Enter ने दाबता. किंवा कडक उन्हात, जिथे पांढऱ्यावरचा फिकट राखाडी मजकूर नाहीसा होतो.

या सगळ्यांसाठी चालणारा फलक म्हणजे वेगळी खास आवृत्ती नाही — तो तोच फलक आहे, फक्त योग्य प्रकारे बांधलेला:

आणि ARIA चा पहिला नियम: वाईट ARIA पेक्षा ARIA नसणे चांगले. आधी योग्य element वापरा (lesson 02); HTML ला जे सांगता येत नाही तेच सांगण्यासाठी aria-* वापरा.

🗺️ आकृती

flowchart TB
    kb["⌨️ keyboard: Tab order = visual order · :focus-visible · skip link first"]
    nm["🏷️ names: label for= · alt · aria-label on icon buttons"]
    ct["🎨 contrast 4.5:1 · never colour alone · reduced motion honoured"]
    lv["📣 live regions: role=status / aria-live=polite announce changes"]
    ar["⚠️ ARIA last: the right element first; no ARIA > bad ARIA"]
    kb --> nm --> ct --> lv --> ar

❓ काय

🤔 का

कारण लोकांना वगळणारा फलक त्यांच्यासाठी थोडा नव्हे, तर पूर्णपणे मोडलेला असतो. कारण इथली प्रत्येक गोष्ट इतर सगळ्यांनाही मदत करते: keyboard support power users ना मदत करतो, contrast उन्हात मदत करतो, live regions मंद networks वर मदत करतात, आणि semantics तुमच्या tests मजबूत बनवतात. आणि कारण नंतर जोडण्यापेक्षा सुरुवातीपासून टिकवून ठेवणे खूपच स्वस्त आहे.

🔧 कसे (या repo मध्ये)

फलकासोबत येतात: एक .skip link (फक्त focus असतानाच दिसणारी), :focus-visible outlines, प्रत्येक control साठी labels, avatars वर alt (alt="" — नाव अगदी शेजारीच आहे), list status वर role="status" aria-live="polite", form संदेशावर role="alert", load होत असताना list वर aria-busy, आणि theme toggle वर aria-pressed.

🧪 करून पाहा

python3 ui/mock_api.py
# 1) keyboard only — no mouse at all: Tab (skip link) → Enter → filter a class → Tab to the form → enrol a student
# 2) screen reader: macOS ⌘F5 (VoiceOver) or Windows Narrator. Listen to the list, the labels, and the message after enrolling.
# 3) break a name: remove aria-label from the theme button and hear "button" with no name. Put it back.
# 4) contrast: DevTools → pick .status colour → the contrast ratio is shown. Try making --muted lighter and see it fail.
# 5) the robot pass:
python3 ui/smoke_test.py      # lang, one h1, labels, alt, skip link + live region

✅ तपासा — तुम्हाला काय दिसायला हवे

तुम्ही mouse ला हात न लावता नावनोंदणी पूर्ण केली, आणि प्रत्येक पायरीवर focus ring दिसत होती. Screen reader ने "Zoya is on the board" जाहीर केले, कारण तो संदेश live region मध्ये राहतो. Smoke test च्या पाच a11y तपासण्या pass होतात.

🏁 तुम्ही आत्ताच काय सिद्ध केले

तोच फलक mouse, keyboard आणि screen-reader वापरणाऱ्या सगळ्यांची सेवा करतो — कारण HTML जे म्हणते तोच त्याचा अर्थ असतो आणि बदल जाहीर केले जातात.

⚠️ नेहमीच्या चुका

🏭 प्रत्यक्ष वापरात हे का महत्त्वाचे: accessibility audits, खरेदीच्या अटी आणि खटले खरे आहेत, पण रोजचे कारण सोपे आहे: तुमच्या users पैकी लक्षणीय भागाला याची गरज असते, आणि जो फलक ते चालवू शकत नाहीत तो ते सरळ सोडून जातील.

⏭️ पुढे

भाग 2 सुरू होतो: फलक पाठवणे. आधी, frameworks — React, Vue आणि Svelte काय automate करतात, आणि vanilla कधी पुरेसे असते.

git checkout lesson-07-frameworks

♿ Lesson 06 — Accessibility: everyone can read the board

📍 You are here: Lesson 06 of 12 · Previous: lesson-05-state-components · Next: lesson-07-frameworks


📦 What's in this branch

Lessons 01–05, plus the lesson that decides whether the board works for everyone: the keyboard, names for every control, contrast, focus, live regions, and the honest rules for ARIA.

🧒 Explain like I'm 5

Imagine reading the board with the lights off, using a helper who reads it aloud (a screen reader). Or with hands that cannot use a mouse, so you move with Tab and press with Enter. Or in bright sun, where pale grey text on white disappears.

A board that works for all of them is not a special version — it is the same board, built right:

And the first rule of ARIA: no ARIA is better than bad ARIA. Use the right element first (lesson 02); reach for aria-* only to say something HTML cannot.

🗺️ Diagram

flowchart TB
    kb["⌨️ keyboard: Tab order = visual order · :focus-visible · skip link first"]
    nm["🏷️ names: label for= · alt · aria-label on icon buttons"]
    ct["🎨 contrast 4.5:1 · never colour alone · reduced motion honoured"]
    lv["📣 live regions: role=status / aria-live=polite announce changes"]
    ar["⚠️ ARIA last: the right element first; no ARIA > bad ARIA"]
    kb --> nm --> ct --> lv --> ar

❓ What

🤔 Why

Because a board that excludes people is broken for them completely, not slightly. Because everything here also helps everyone else: keyboard support helps power users, contrast helps sunlight, live regions help slow networks, and semantics make your tests robust. And because it is far cheaper to keep than to retrofit.

🔧 How (in this repo)

The board ships with a .skip link (visible only on focus), :focus-visible outlines, labels for every control, alt on avatars (alt="" — the name is right next to them), role="status" aria-live="polite" on the list status, role="alert" on the form message, aria-busy on the list while loading, and aria-pressed on the theme toggle.

🧪 Try it

python3 ui/mock_api.py
# 1) keyboard only — no mouse at all: Tab (skip link) → Enter → filter a class → Tab to the form → enrol a student
# 2) screen reader: macOS ⌘F5 (VoiceOver) or Windows Narrator. Listen to the list, the labels, and the message after enrolling.
# 3) break a name: remove aria-label from the theme button and hear "button" with no name. Put it back.
# 4) contrast: DevTools → pick .status colour → the contrast ratio is shown. Try making --muted lighter and see it fail.
# 5) the robot pass:
python3 ui/smoke_test.py      # lang, one h1, labels, alt, skip link + live region

✅ Verify — what you should see

You completed an enrolment without touching the mouse, and the focus ring was visible at every step. The screen reader announced "Zoya is on the board" because the message lives in a live region. The smoke test's five a11y checks pass.

🏁 What you just proved

The same board serves mouse, keyboard and screen-reader users — because the HTML means what it says and changes are announced.

⚠️ Common mistakes

🏭 Why this matters in production: accessibility audits, procurement requirements and lawsuits are real, but the everyday reason is simpler: a meaningful fraction of your users need this, and they will simply leave a board they cannot operate.

⏭️ Next

Part 2 begins: shipping the board. First, frameworks — what React, Vue and Svelte automate, and when vanilla is enough.

git checkout lesson-07-frameworks
← Previousstate componentsNext →frameworks

This page is the lesson's README from the lesson-06-accessibility branch, shown here so the whole School stays on one site. Code files open on GitHub at the same branch.