So optimieren Sie Barrierefreiheit mit Claude Code
Erfahren Sie, wie Sie Barrierefreiheit mit Claude Code optimieren. Mit praktischen Codebeispielen und Schritt-für-Schritt-Anleitung.
Vorteile von Claude Code für die Barrierefreiheit
Web-Barrierefreiheit ist wichtig, aber das Verständnis der WCAG-Richtlinien und die korrekte Verwendung von ARIA-Attributen sind komplex. Claude Code ermöglicht die effiziente Generierung von Code nach Best Practices der Barrierefreiheit sowie das Audit bestehenden Codes.
Barrierefreiheits-Audit bestehenden Codes
> Überprüfe alle Komponenten unter src/components/ auf Barrierefreiheit.
> Prüfe nach WCAG 2.1 AA-Kriterien und erstelle eine Liste der Probleme und Lösungsvorschläge.
Claude Code erkennt folgende Probleme:
- Fehlende alt-Attribute bei Bildern
- Formularelemente ohne zugehörige label-Elemente
- Unzureichende Farbkontrastverhältnisse
- Interaktive Elemente, die nicht per Tastatur bedienbar sind
- Unsachgemäß verwendete ARIA-Attribute
Generierung barrierefreier Komponenten
Modaler Dialog
> Erstelle einen barrierefreien modalen Dialog.
> Implementiere Fokusfalle, Schließen mit ESC-Taste und Scroll-Sperre des Hintergrunds.
import { useEffect, useRef, useCallback } from 'react';
interface ModalProps {
isOpen: boolean;
onClose: () => void;
title: string;
children: React.ReactNode;
}
function Modal({ isOpen, onClose, title, children }: ModalProps) {
const modalRef = useRef<HTMLDivElement>(null);
const previousFocus = useRef<HTMLElement | null>(null);
// Fokusfalle
const trapFocus = useCallback((e: KeyboardEvent) => {
if (!modalRef.current) return;
const focusable = modalRef.current.querySelectorAll<HTMLElement>(
'a[href], button:not([disabled]), input:not([disabled]), select, textarea, [tabindex]:not([tabindex="-1"])'
);
const first = focusable[0];
const last = focusable[focusable.length - 1];
if (e.key === 'Tab') {
if (e.shiftKey && document.activeElement === first) {
e.preventDefault();
last.focus();
} else if (!e.shiftKey && document.activeElement === last) {
e.preventDefault();
first.focus();
}
}
if (e.key === 'Escape') onClose();
}, [onClose]);
useEffect(() => {
if (isOpen) {
previousFocus.current = document.activeElement as HTMLElement;
document.body.style.overflow = 'hidden';
document.addEventListener('keydown', trapFocus);
// Fokus auf das erste fokussierbare Element im Modal setzen
setTimeout(() => {
modalRef.current?.querySelector<HTMLElement>('[autofocus], button')?.focus();
}, 0);
}
return () => {
document.body.style.overflow = '';
document.removeEventListener('keydown', trapFocus);
previousFocus.current?.focus();
};
}, [isOpen, trapFocus]);
if (!isOpen) return null;
return (
<div
className="fixed inset-0 z-50 flex items-center justify-center"
role="presentation"
>
<div
className="fixed inset-0 bg-black/50"
aria-hidden="true"
onClick={onClose}
/>
<div
ref={modalRef}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
className="relative z-10 mx-4 w-full max-w-lg rounded-lg bg-white p-6 shadow-xl dark:bg-gray-800"
>
<h2 id="modal-title" className="text-xl font-bold mb-4">
{title}
</h2>
{children}
<button
onClick={onClose}
aria-label="Schließen"
className="absolute right-4 top-4 rounded-full p-1 hover:bg-gray-100 dark:hover:bg-gray-700"
>
<svg aria-hidden="true" className="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" />
</svg>
</button>
</div>
</div>
);
}
Barrierefreies Dropdown-Menü
function DropdownMenu({ label, items }: { label: string; items: MenuItem[] }) {
const [isOpen, setIsOpen] = useState(false);
const [activeIndex, setActiveIndex] = useState(-1);
const menuRef = useRef<HTMLUListElement>(null);
const handleKeyDown = (e: React.KeyboardEvent) => {
switch (e.key) {
case 'ArrowDown':
e.preventDefault();
setActiveIndex(prev => Math.min(prev + 1, items.length - 1));
break;
case 'ArrowUp':
e.preventDefault();
setActiveIndex(prev => Math.max(prev - 1, 0));
break;
case 'Enter':
case ' ':
e.preventDefault();
if (activeIndex >= 0) items[activeIndex].onClick();
setIsOpen(false);
break;
case 'Escape':
setIsOpen(false);
break;
}
};
return (
<div className="relative" onKeyDown={handleKeyDown}>
<button
aria-haspopup="true"
aria-expanded={isOpen}
onClick={() => setIsOpen(!isOpen)}
>
{label}
</button>
{isOpen && (
<ul ref={menuRef} role="menu" className="absolute mt-1 rounded-md border bg-white shadow-lg dark:bg-gray-800">
{items.map((item, i) => (
<li
key={i}
role="menuitem"
tabIndex={-1}
className={`cursor-pointer px-4 py-2 ${i === activeIndex ? 'bg-blue-100 dark:bg-blue-900' : ''}`}
onClick={item.onClick}
>
{item.label}
</li>
))}
</ul>
)}
</div>
);
}
Barrierefreiheit von Formularen
> Gestalte das Kontaktformular barrierefrei.
> Validierungsfehler sollen auch für Screenreader erkennbar sein.
function ContactForm() {
const [errors, setErrors] = useState<Record<string, string>>({});
return (
<form aria-label="Kontaktformular" noValidate>
<div className="mb-4">
<label htmlFor="name" className="block font-medium mb-1">
Name <span aria-label="Pflichtfeld">*</span>
</label>
<input
id="name"
type="text"
required
aria-required="true"
aria-invalid={!!errors.name}
aria-describedby={errors.name ? 'name-error' : undefined}
className="w-full rounded border p-2"
/>
{errors.name && (
<p id="name-error" role="alert" className="mt-1 text-sm text-red-600">
{errors.name}
</p>
)}
</div>
<div className="mb-4">
<label htmlFor="email" className="block font-medium mb-1">
E-Mail-Adresse <span aria-label="Pflichtfeld">*</span>
</label>
<input
id="email"
type="email"
required
aria-required="true"
aria-invalid={!!errors.email}
aria-describedby="email-hint email-error"
className="w-full rounded border p-2"
/>
<p id="email-hint" className="mt-1 text-xs text-gray-500">
z.B. [email protected]
</p>
{errors.email && (
<p id="email-error" role="alert" className="mt-1 text-sm text-red-600">
{errors.email}
</p>
)}
</div>
<button type="submit" className="rounded bg-blue-600 px-4 py-2 text-white">
Absenden
</button>
</form>
);
}
Einführung automatisierter Tests
> Füge Barrierefreiheitstests mit jest-axe hinzu.
import { render } from '@testing-library/react';
import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);
describe('Modal accessibility', () => {
it('should have no accessibility violations', async () => {
const { container } = render(
<Modal isOpen={true} onClose={() => {}} title="Test Modal">
<p>Content</p>
</Modal>
);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
});
Zusammenfassung
Mit Claude Code können Sie effizient barrierefreie Komponenten gemäß WCAG-Richtlinien generieren und bestehenden Code auditieren. Es ist auch sinnvoll, Barrierefreiheitstests über die Hook-Funktion automatisch auszuführen. Weitere Details finden Sie im Hook-Funktionsleitfaden. Tipps zur Integration in den täglichen Entwicklungsworkflow finden Sie unter Tipps zur 3-fachen Produktivität.
Weitere Informationen zu Claude Code finden Sie in der offiziellen Anthropic-Dokumentation. Details zu den WCAG-Richtlinien finden Sie unter W3C WCAG 2.1.
Related Posts
10 Tipps, um Ihre Produktivität mit Claude Code zu verdreifachen
Entdecken Sie 10 praktische Tipps, um mehr aus Claude Code herauszuholen. Von Prompt-Strategien bis zu Workflow-Abkürzungen — diese Techniken steigern Ihre Effizienz ab sofort.
Canvas/WebGL-Optimierung mit Claude Code
Erfahren Sie, wie Sie Canvas/WebGL mit Claude Code optimieren. Mit praktischen Tipps und Codebeispielen.
Markdown Implementation with Claude Code
Learn about markdown implementation using Claude Code. Practical tips and code examples included.