Tips & Tricks (अपडेट: 2/6/2026)

Claude Code से Accessibility सुधारें: Semantic HTML, ARIA, axe और Manual Check

Claude Code accessibility workflow: HTML, keyboard, forms, focus, axe और screen reader check.

Claude Code से Accessibility सुधारें: Semantic HTML, ARIA, axe और Manual 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 में बदल सके।

AreaPractical targetCommon failure
Semantic HTMLbutton, a, form, label, main, nav सही meaning में use होंclickable div button बन जाता है
KeyboardTab, Shift+Tab, Enter, Space, Escape से main flow चलेModal mouse से ही close होता है
Focusनया UI खुलने पर focus अंदर जाए, बंद होने पर trigger पर लौटेFocus page background में भाग जाता है
ARIANative HTML से state express न हो तभी ARIAmissing label छिपाने के लिए aria-label
ColorText, controls, errors और focus visible रहेंError सिर्फ red color से बताया जाता है
FormsLabel, hint, invalid state और error input से connected होंError दिखता है पर announce नहीं होता
Testingaxe plus keyboard और screen reader manual checkzero 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 हुई।

#Claude Code #accessibility #WCAG #a11y #React
मुफ़्त

मुफ़्त PDF: Claude Code cheatsheet

Email डालें और commands, review habits तथा safe workflow वाली एक-page PDF पाएँ.

हम आपका data सुरक्षित रखते हैं और spam नहीं भेजते.

Masa

लेखक के बारे में

Masa

Claude Code workflow और team adoption पर काम करने वाला engineer.