Skip to main content

accessibility

Web accessibility (a11y). WCAG 2.1, ARIA, keyboard navigation, screen readers, testing tools.

Quellinformationen

Repository
skeletorflet/opencode-kit
Letzte Quellaktivität
3. April 2026 um 15:32
Erkannte Sprache von SKILL.md
Englisch
Sterne
10
Forks
1

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
accessibility
description
Web accessibility (a11y). WCAG 2.1, ARIA, keyboard navigation, screen readers, testing tools.
# Accessibility (a11y) > Accessible apps are better apps for everyone. --- ## 1. WCAG 2.1 Core Principles (POUR) | Principle | Meaning | |-----------|---------| | **Perceivable** | Info must be presentable to all senses | | **Operable** | UI must be keyboard + assistive tech operable | | **Understandable** | Content and operation must be comprehensible | | **Robust** | Must work with current + future assistive tech | **Target: AA conformance** (minimum for most products) --- ## 2. Color & Contrast | Element | Minimum Ratio | AA+ Ratio | |---------|-------------|-----------| | Normal text (< 18px) | 4.5:1 | 7:1 | | Large text (≥ 18px) | 3:1 | 4.5:1 | | UI components (borders, icons) | 3:1 | — | | Disabled state | No requirement | — | ``` Tools: ├── WebAIM Contrast Checker ├── Chrome DevTools → Accessibility panel └── axe DevTools browser extension ``` --- ## 3. Semantic HTML First ```html \x3C!-- ❌ Bad --> <div class="button" onclick="submit()">Submit</div> <div class="heading">Section Title</div> <div class="nav">...</div> \x3C!-- ✅ Good --> <button type="submit">Submit</button> <h2>Section Title</h2> <nav aria-label="Main navigation">...</nav> ``` --- ## 4. ARIA Patterns ```html \x3C!-- When to use ARIA: Rule 1: Don\'t use ARIA if native HTML works Rule 2: Don\'t change native semantics unnecessarily Rule 3: All interactive ARIA controls must be keyboard-focusable --> \x3C!-- Modal Dialog --> <div role="dialog" aria-modal="true" aria-labelledby="modal-title" aria-describedby="modal-desc"> <h2 id="modal-title">Confirm Delete</h2> <p id="modal-desc">This action cannot be undone.</p> <button>Cancel</button> <button>Delete</button> </div> \x3C!-- Live Region (dynamic content) --> <div aria-live="polite" aria-atomic="true"> \x3C!-- Updates announced to screen readers --> {statusMessage} </div> \x3C!-- Icon button --> <button aria-label="Close dialog"> <svg aria-hidden="true">...</svg> </button> \x3C!-- Loading --> <div role="status" aria-label="Loading users..."> <Spinner /> </div> ``` --- ## 5. Keyboard Navigation | Key | Expected Behavior | |-----|------------------| | `Tab` | Move to next focusable element | | `Shift+Tab` | Move to previous | | `Enter` / `Space` | Activate button/link | | `Escape` | Close modal/dropdown | | Arrow keys | Navigate within widget (menu, tabs, listbox) | ```tsx // Focus trap (modals) import { useFocusTrap } from "@mantine/hooks"; // or write custom function Modal({ isOpen, onClose, children }) { const focusTrapRef = useFocusTrap(isOpen); return isOpen ? ( <div ref={focusTrapRef} role="dialog" aria-modal="true"> {children} </div> ) : null; } // Skip link (keyboard shortcut to main content) <a href="#main-content" className="sr-only focus:not-sr-only"> Skip to main content </a> ``` --- ## 6. Images & Media ```html \x3C!-- Informative image --> <img src="chart.png" alt="Bar chart showing 40% increase in Q4 revenue" /> \x3C!-- Decorative image --> <img src="divider.png" alt="" role="presentation" /> \x3C!-- Icon (standalone meaning) --> <svg aria-label="Settings" role="img">...</svg> \x3C!-- Video --> <video> <track kind="captions" src="captions.vtt" srclang="en" label="English" /> </video> ``` --- ## 7. Form Accessibility ```html \x3C!-- Always associate label with input --> <label for="email">Email address</label> <input id="email" type="email" required aria-describedby="email-hint email-error" aria-invalid="true" /> <span id="email-hint">We\'ll never share your email.</span> <span id="email-error" role="alert">Please enter a valid email.</span> \x3C!-- Fieldset for groups --> <fieldset> <legend>Notification preferences</legend> <label><input type="checkbox" name="email"> Email</label> <label><input type="checkbox" name="sms"> SMS</label> </fieldset> ``` --- ## 8. Testing Tools | Tool | Type | Use For | |------|------|---------| | **axe DevTools** | Browser ext | Automated scan | | **Lighthouse** | Chrome DevTools | Audit score | | **NVDA** | Screen reader (Windows) | Manual testing | | **VoiceOver** | Screen reader (Mac/iOS) | Manual testing | | **jest-axe** | Unit test | CI/CD integration | | **Playwright** | E2E | Keyboard/focus testing | ```ts // jest-axe import { axe, toHaveNoViolations } from "jest-axe"; expect.extend(toHaveNoViolations); it("has no accessibility violations", async () => { const { container } = render(<MyForm />); const results = await axe(container); expect(results).toHaveNoViolations(); }); ``` --- ## 9. Quick Checklist - [ ] Color contrast meets AA (4.5:1 normal text) - [ ] Keyboard navigable (Tab, Enter, Escape, arrows) - [ ] All images have meaningful alt text - [ ] Forms have visible labels (not just placeholders) - [ ] Focus indicators visible (don\'t `outline: none`) - [ ] Skip navigation link on every page - [ ] Error messages associated with fields - [ ] Page has one `<h1>`, logical heading hierarchy - [ ] Interactive elements have 44×44px touch target minimum
Auf GitHub ansehen