Claude Code से Accessibility सुधारें: Semantic HTML, ARIA, axe और Manual Check
Claude Code accessibility workflow: HTML, keyboard, forms, focus, axe और screen reader check.
Accessibility सिर्फ release से पहले कोई tool चलाने का काम नहीं है। यह semantic HTML से शुरू होती है, keyboard navigation, focus management, form errors, color contrast, automated checks और screen reader manual verification तक जाती है।
Claude Code इस workflow को तेज कर सकता है, लेकिन prompt साफ होना चाहिए। अगर आप सिर्फ “इसे accessible बना दो” लिखते हैं, तो वह div पर ARIA जोड़ सकता है लेकिन Enter और Space behavior छोड़ सकता है। Modal दिखेगा, पर focus background में चला जाएगा। Form error screen पर दिखेगा, पर screen reader उसे नहीं पढ़ेगा।
इस article में official sources को आधार बनाया गया है: practical target के लिए W3C WCAG 2.2, component patterns के लिए WAI-ARIA Authoring Practices Guide, ARIA को समझने के लिए MDN ARIA guide, automated audit के लिए Deque axe-core docs और Claude Code basics के लिए official Claude Code docs।
पहले Acceptance Criteria लिखें
“Accessibility improve करो” बहुत vague है। Claude Code को ऐसी checklist दें जिसे वह review और patch में बदल सके।
| Area | Practical target | Common failure |
|---|---|---|
| Semantic HTML | button, a, form, label, main, nav सही meaning में use हों | clickable div button बन जाता है |
| Keyboard | Tab, Shift+Tab, Enter, Space, Escape से main flow चले | Modal mouse से ही close होता है |
| Focus | नया UI खुलने पर focus अंदर जाए, बंद होने पर trigger पर लौटे | Focus page background में भाग जाता है |
| ARIA | Native HTML से state express न हो तभी ARIA | missing label छिपाने के लिए aria-label |
| Color | Text, controls, errors और focus visible रहें | Error सिर्फ red color से बताया जाता है |
| Forms | Label, hint, invalid state और error input से connected हों | Error दिखता है पर announce नहीं होता |
| Testing | axe plus keyboard और screen reader manual check | zero automated violations को final proof मान लेना |
MDN की practical advice है: जब native HTML element meaning और behavior दे सकता है, तो पहले वही use करें। ARIA support है, foundation नहीं।
Claude Code के लिए safe prompt
Accessibility prompt में scope, protected areas, target standard और verification evidence शामिल करें।
claude <<'PROMPT'
Scope:
- Review only src/components/CheckoutForm.tsx and its tests.
- Do not change pricing copy, analytics events, or unrelated styles.
Accessibility target:
- Use WCAG 2.2 AA as the practical target.
- Prefer semantic HTML before ARIA.
- Add ARIA only when native HTML cannot express the state.
Check these items:
- Labels, descriptions, required state, and validation errors.
- Keyboard operation with Tab, Shift+Tab, Enter, Space, and Escape.
- Focus order, visible focus, and focus return after closing UI.
- Color contrast and non-color error indicators.
- Automated axe check plus manual screen-reader notes.
Output:
- Findings first, with file and line references.
- Minimal patch.
- Commands to verify.
- Any remaining risk.
PROMPT
Findings first बहुत उपयोगी है। Claude Code पहले bug बताए, फिर minimal patch दे। CTA, Gumroad link, pricing copy और analytics वाले pages में यह जरूरी है। Scope छोटा रखने का तरीका Claude Code productivity tips में भी काम आता है।
Use case 1: Product CTA और article CTA
CTA revenue path है। अगर action navigation है, तो real link use करें। पूरा card clickable div बनाने से keyboard और screen reader experience खराब होता है।
<div class="hero-card" onclick="location.href='/en/products'">
<div class="title">Claude Code Templates</div>
<div class="button">Buy now</div>
</div>
Better structure में heading, explanation और link अलग रहते हैं।
<section aria-labelledby="templates-heading" class="product-cta">
<h2 id="templates-heading">Claude Code templates से review time घटाएं</h2>
<p>
Implementation, review, debugging और documentation के लिए
reusable prompts copy करें।
</p>
<a class="primary-link" href="/en/products">
Product resources देखें
</a>
</section>
Claude Code को साफ कहें कि CTA destination, tracking attributes और monetization copy preserve रहे। Accessibility patch अगर conversion path तोड़ दे, तो वह production-ready नहीं है।
Use case 2: Consultation form और errors
Forms में accessibility issue सीधे conversion loss बनता है। User field नहीं समझता, error नहीं सुनता, या correction नहीं जानता तो submit नहीं करेगा।
import { FormEvent, useState } from "react";
type Errors = {
name?: string;
email?: string;
};
export function ConsultationForm() {
const [errors, setErrors] = useState<Errors>({});
function handleSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
const data = new FormData(event.currentTarget);
const nextErrors: Errors = {};
if (!String(data.get("name") || "").trim()) {
nextErrors.name = "अपना नाम दर्ज करें।";
}
if (!String(data.get("email") || "").includes("@")) {
nextErrors.email = "मान्य email address दर्ज करें।";
}
setErrors(nextErrors);
}
return (
<form aria-labelledby="consultation-title" onSubmit={handleSubmit} noValidate>
<h2 id="consultation-title">Consultation request</h2>
<div className="field">
<label htmlFor="name">नाम</label>
<input
id="name"
name="name"
autoComplete="name"
aria-invalid={errors.name ? "true" : "false"}
aria-describedby={errors.name ? "name-error" : undefined}
/>
{errors.name && (
<p id="name-error" role="alert">
{errors.name}
</p>
)}
</div>
<div className="field">
<label htmlFor="email">Email</label>
<p id="email-help">ऐसा address लिखें जहाँ reply मिल सके।</p>
<input
id="email"
name="email"
type="email"
autoComplete="email"
aria-invalid={errors.email ? "true" : "false"}
aria-describedby={
errors.email ? "email-help email-error" : "email-help"
}
/>
{errors.email && (
<p id="email-error" role="alert">
{errors.email}
</p>
)}
</div>
<button type="submit">Request भेजें</button>
</form>
);
}
Common failure है error text दिखाना पर input से connect न करना। दूसरा failure है हमेशा ऐसे error ID को refer करना जो render ही नहीं हुआ। Help text हमेशा connected रहे; error तभी जब मौजूद हो।
Use case 3: Modal, command palette और menu
Modal का hard part animation नहीं, focus है। WAI-ARIA Dialog Modal Pattern के अनुसार focus dialog में जाना चाहिए, Tab अंदर cycle करना चाहिए, Escape close करना चाहिए और close के बाद focus trigger button पर लौटना चाहिए।
import { ReactNode, useEffect, useRef } from "react";
type ModalProps = {
open: boolean;
title: string;
onClose: () => void;
children: ReactNode;
};
const focusableSelector = [
"a[href]",
"button:not([disabled])",
"input:not([disabled])",
"select:not([disabled])",
"textarea:not([disabled])",
'[tabindex]:not([tabindex="-1"])',
].join(",");
export function AccessibleModal(props: ModalProps) {
const { open, title, onClose, children } = props;
const dialogRef = useRef<HTMLDivElement>(null);
const previousFocusRef = useRef<HTMLElement | null>(null);
useEffect(() => {
if (!open) return;
previousFocusRef.current = document.activeElement as HTMLElement;
const focusable = dialogRef.current?.querySelectorAll<HTMLElement>(
focusableSelector
);
focusable?.[0]?.focus();
function onKeyDown(event: KeyboardEvent) {
if (event.key === "Escape") onClose();
if (event.key !== "Tab" || !dialogRef.current) return;
const items = [...dialogRef.current.querySelectorAll<HTMLElement>(
focusableSelector
)];
const first = items[0];
const last = items[items.length - 1];
if (event.shiftKey && document.activeElement === first) {
event.preventDefault();
last?.focus();
} else if (!event.shiftKey && document.activeElement === last) {
event.preventDefault();
first?.focus();
}
}
document.addEventListener("keydown", onKeyDown);
return () => {
document.removeEventListener("keydown", onKeyDown);
previousFocusRef.current?.focus();
};
}, [open, onClose]);
if (!open) return null;
return (
<div className="modal-backdrop">
<div
ref={dialogRef}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
className="modal-panel"
>
<h2 id="modal-title" tabIndex={-1}>
{title}
</h2>
{children}
<button type="button" onClick={onClose}>
Close
</button>
</div>
</div>
);
}
Dropdown में भी ARIA menu हमेशा सही नहीं होता। Menu Button Pattern command menu के लिए अच्छा है; normal site navigation में nav और links अक्सर बेहतर होते हैं।
Color, focus और mobile
Design polish में focus outline हट जाना common regression है। Error सिर्फ red color से न दिखाएं; border, text और icon जैसे extra signals दें।
.primary-link {
background: #0f766e;
border-radius: 6px;
color: #ffffff;
display: inline-flex;
font-weight: 700;
min-height: 44px;
padding: 0.75rem 1rem;
}
.primary-link:focus-visible,
button:focus-visible,
input:focus-visible {
outline: 3px solid #f59e0b;
outline-offset: 3px;
}
.field [role="alert"] {
border-left: 4px solid #b91c1c;
color: #7f1d1d;
margin-top: 0.5rem;
padding-left: 0.75rem;
}
Mobile viewport भी देखें। छोटा close button, sticky header के नीचे छिपा focus और narrow CTA desktop review में छूट जाते हैं।
axe और manual screen reader check
axe structural issues पकड़ता है, लेकिन यह नहीं बता सकता कि label business context में clear है या reading order सच में usable है।
npm install -D @axe-core/playwright @playwright/test
npx playwright install --with-deps chromium
import AxeBuilder from "@axe-core/playwright";
import { expect, test } from "@playwright/test";
test("consultation form has no serious accessibility issues", async ({ page }) => {
await page.goto("/contact");
const results = await new AxeBuilder({ page })
.include("main")
.withTags(["wcag2a", "wcag2aa", "wcag22aa"])
.analyze();
expect(results.violations).toEqual([]);
});
Manual check में product CTA, consultation form, checkout, modal, navigation और error recovery पहले देखें। Windows पर NVDA और macOS पर VoiceOver practical starting point हैं।
Failure examples जिन्हें जरूर पूछें
role="button"है, पर Enter और Space support नहीं।- Icon-only button का accessible name नहीं।
- Image में
alt="image"जैसा बेकार text। aria-hidden="true"modal या live region को hide कर रहा है।- Error visible है पर
aria-describedbyसे connected नहीं। - Focus outline हट गया और replacement नहीं।
- Modal close होने पर focus trigger button पर नहीं लौटता।
- Automated test सिर्फ marketing page देखता है, real form नहीं।
इस list को Claude Code को दें और file plus line references मांगें।
CTA और actual verification
Workflow को repeatable बनाना है तो Claude Code product resources से शुरू करें। Reusable review और debugging prompts चाहिए तो 50 Claude Code prompt templates देखें। Team rollout में permissions, hooks और verification receipt चाहिए तो consultation बेहतर next step है।
इस refresh में तीन real failures पर verification किया: clickable div CTA, visible पर unread form error, और modal close होने के बाद lost focus। सबसे stable Claude Code flow था: पहले findings, फिर minimal patch, फिर keyboard और VoiceOver check। axe ने structure पकड़ा, लेकिन final clarity human सुनकर ही confirm हुई।
मुफ़्त PDF: Claude Code cheatsheet
Email डालें और commands, review habits तथा safe workflow वाली एक-page PDF पाएँ.
हम आपका data सुरक्षित रखते हैं और spam नहीं भेजते.
लेखक के बारे में
Masa
Claude Code workflow और team adoption पर काम करने वाला engineer.
संबंधित लेख
Claude Code permission safety ladder: access धीरे-धीरे बढ़ाएं
read-only से limited edits, proof commands और deploy checks तक permission बढ़ाने की सुरक्षित ladder.
Claude Code Small PR Proof Pack: छोटे PR को review-ready बनाना
Claude Code PR के लिए diff, checks, public URL, CTA path और rollback वाला practical proof pack.
Claude Code Review Gate Before Commit: diff, test, public URL और CTA जांच
Claude Code से commit से पहले review gate बनाएं: diff, build, public URL, Gumroad, consultation, tests और unrelated files।