Skip to main content

accessibility

Build WCAG 2.1 AA compliant websites with semantic HTML, proper ARIA, focus management, and screen reader support. Includes color contrast (4.5:1 text), keyboard navigation, form labels, and live regions. Use when implementing accessible interfaces, fixing screen reader issues, keyboard navigation, or troubleshooting "focus outline missing", "aria-label required", "insufficient contrast".

Informações da origem

Repositório
modbender/skill-library-mcp
Última atividade na origem
6 de março de 2026 às 18:33
Idioma detectado do SKILL.md
inglês
Estrelas
12
Forks
3

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
accessibility
description
Build WCAG 2.1 AA compliant websites with semantic HTML, proper ARIA, focus management, and screen reader support. Includes color contrast (4.5:1 text), keyboard navigation, form labels, and live regions. Use when implementing accessible interfaces, fixing screen reader issues, keyboard navigation, or troubleshooting "focus outline missing", "aria-label required", "insufficient contrast".
# Web Accessibility (WCAG 2.1 AA) **Status**: Production Ready ✅ **Last Updated**: 2026-01-14 **Dependencies**: None (framework-agnostic) **Standards**: WCAG 2.1 Level AA --- ## Quick Start (5 Minutes) ### 1. Semantic HTML Foundation Choose the right element - don't use `div` for everything: ```html <!-- ❌ WRONG - divs with onClick --> <div onclick="submit()">Submit</div> <div onclick="navigate()">Next page</div> <!-- ✅ CORRECT - semantic elements --> <button type="submit">Submit</button> <a href="/next">Next page</a> ``` **Why this matters:** - Semantic elements have built-in keyboard support - Screen readers announce role automatically - Browser provides default accessible behaviors ### 2. Focus Management Make interactive elements keyboard-accessible: ```css /* ❌ WRONG - removes focus outline */ button:focus { outline: none; } /* ✅ CORRECT - custom accessible outline */ button:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; } ``` **CRITICAL:** - Never remove focus outlines without replacement - Use `:focus-visible` to show only on keyboard focus - Ensure 3:1 contrast ratio for focus indicators ### 3. Text Alternatives Every non-text element needs a text alternative: ```html <!-- ❌ WRONG - no alt text --> <img src="logo.png"> <button><svg>...</svg></button> <!-- ✅ CORRECT - proper alternatives --> <img src="logo.png" alt="Company Name"> <button aria-label="Close dialog"><svg>...</svg></button> ``` --- ## The 5-Step Accessibility Process ### Step 1: Choose Semantic HTML **Decision tree for element selection:** ``` Need clickable element? ├─ Navigates to another page? → <a href="..."> ├─ Submits form? → <button type="submit"> ├─ Opens dialog? → <button aria-haspopup="dialog"> └─ Other action? → <button type="button"> Grouping content? ├─ Self-contained article? → <article> ├─ Thematic section? → <section> ├─ Navigation links? → <nav> └─ Supplementary info? → <aside> Form element? ├─ Text input? → <input type="text"> ├─ Multiple choice? → <select> or <input type="radio"> ├─ Toggle? → <input type="checkbox"> or <button aria-pressed> └─ Long text? → <textarea> ``` **See `references/semantic-html.md` for complete guide.** ### Step 2: Add ARIA When Needed **Golden rule: Use ARIA only when HTML can't express the pattern.** ```html <!-- ❌ WRONG - unnecessary ARIA --> <button role="button">Click me</button> <!-- Button already has role --> <!-- ✅ CORRECT - ARIA fills semantic gap --> <div role="dialog" aria-labelledby="title" aria-modal="true"> <h2 id="title">Confirm action</h2> <!-- No HTML dialog yet, so role needed --> </div> <!-- ✅ BETTER - Use native HTML when available --> <dialog aria-labelledby="title"> <h2 id="title">Confirm action</h2> </dialog> ``` **Common ARIA patterns:** - `aria-label` - When visible label doesn't exist - `aria-labelledby` - Reference existing text as label - `aria-describedby` - Additional description - `aria-live` - Announce dynamic updates - `aria-expanded` - Collapsible/expandable state **See `references/aria-patterns.md` for complete patterns.** ### Step 3: Implement Keyboard Navigation **All interactive elements must be keyboard-accessible:** ```typescript // Tab order management function Dialog({ onClose }) { const dialogRef = useRef<HTMLDivElement>(null); const previousFocus = useRef<HTMLElement | null>(null); useEffect(() => { // Save previous focus previousFocus.current = document.activeElement as HTMLElement; // Focus first element in dialog const firstFocusable = dialogRef.current?.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'); (firstFocusable as HTMLElement)?.focus(); // Trap focus within dialog const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); if (e.key === 'Tab') { // Focus trap logic here } }; document.addEventListener('keydown', handleKeyDown); return () => { document.removeEventListener('keydown', handleKeyDown); // Restore focus on close previousFocus.current?.focus(); }; }, [onClose]); return <div ref={dialogRef} role="dialog">...</div>; } ``` **Essential keyboard patterns:** - Tab/Shift+Tab: Navigate between focusable elements - Enter/Space: Activate buttons/links - Arrow keys: Navigate within components (tabs, menus) - Escape: Close dialogs/menus - Home/End: Jump to first/last item **See `references/focus-management.md` for complete patterns.** ### Step 4: Ensure Color Contrast **WCAG AA requirements:** - Normal text (under 18pt): 4.5:1 contrast ratio - Large text (18pt+ or 14pt+ bold): 3:1 contrast ratio - UI components (buttons, borders): 3:1 contrast ratio ```css /* ❌ WRONG - insufficient contrast */ :root { --background: #ffffff; --text: #999999; /* 2.8:1 - fails WCAG AA */ } /* ✅ CORRECT - sufficient contrast */ :root { --background: #ffffff; --text: #595959; /* 4.6:1 - passes WCAG AA */ } ``` **Testing tools:** - Browser DevTools (Chrome/Firefox have built-in checkers) - Contrast checker extensions - axe DevTools extension **See `references/color-contrast.md` for complete guide.** ### Step 5: Make Forms Accessible **Every form input needs a visible label:** ```html <!-- ❌ WRONG - placeholder is not a label --> <input type="email" placeholder="Email address"> <!-- ✅ CORRECT - proper label --> <label for="email">Email address</label> <input type="email" id="email" name="email" required aria-required="true"> ``` **Error handling:** ```html <label for="email">Email address</label> <input type="email" id="email" name="email" aria-invalid="true" aria-describedby="email-error" > <span id="email-error" role="alert"> Please enter a valid email address </span> ``` **Live regions for dynamic errors:** ```html <div role="alert" aria-live="assertive" aria-atomic="true"> Form submission failed. Please fix the errors above. </div> ``` **See `references/forms-validation.md` for complete patterns.** --- ## Critical Rules ### Always Do ✅ Use semantic HTML elements first (button, a, nav, article, etc.) ✅ Provide text alternatives for all non-text content ✅ Ensure 4.5:1 contrast for normal text, 3:1 for large text/UI ✅ Make all functionality keyboard accessible ✅ Test with keyboard only (unplug mouse) ✅ Test with screen reader (NVDA on Windows, VoiceOver on Mac) ✅ Use proper heading hierarchy (h1 → h2 → h3, no skipping) ✅ Label all form inputs with visible labels ✅ Provide focus indicators (never just `outline: none`) ✅ Use `aria-live` for dynamic content updates ### Never Do ❌ Use `div` with `onClick` instead of `button` ❌ Remove focus outlines without replacement ❌ Use color alone to convey information ❌ Use placeholders as labels ❌ Skip heading levels (h1 → h3) ❌ Use `tabindex` > 0 (messes with natural order) ❌ Add ARIA when semantic HTML exists ❌ Forget to restore focus after closing dialogs ❌ Use `role="presentation"` on focusable elements ❌ Create keyboard traps (no way to escape) --- ## Known Issues Prevention This skill prevents **12** documented accessibility issues: ### Issue #1: Missing Focus Indicators **Error**: Interactive elements have no visible focus indicator **Source**: WCAG 2.4.7 (Focus Visible) **Why It Happens**: CSS reset removes default outline **Prevention**: Always provide custom focus-visible styles ### Issue #2: Insufficient Color Contrast **Error**: Text has less than 4.5:1 contrast ratio **Source**: WCAG 1.4.3 (Contrast Minimum) **Why It Happens**: Using light gray text on white background **Prevention**: Test all text colors with contrast checker ### Issue #3: Missing Alt Text **Error**: Images missing alt attributes **Source**: WCAG 1.1.1 (Non-text Content) **Why It Happens**: Forgot to add or thought it was optional **Prevention**: Add alt="" for decorative, descriptive alt for meaningful images ### Issue #4: Keyboard Navigation Broken **Error**: Interactive elements not reachable by keyboard **Source**: WCAG 2.1.1 (Keyboard) **Why It Happens**: Using div onClick instead of button **Prevention**: Use semantic interactive elements (button, a) ### Issue #5: Form Inputs Without Labels **Error**: Input fields missing associated labels **Source**: WCAG 3.3.2 (Labels or Instructions) **Why It Happens**: Using placeholder as label **Prevention**: Always use `<label>` element with for/id association ### Issue #6: Skipped Heading Levels **Error**: Heading hierarchy jumps from h1 to h3 **Source**: WCAG 1.3.1 (Info and Relationships) **Why It Happens**: Using headings for visual styling instead of semantics **Prevention**: Use headings in order, style with CSS ### Issue #7: No Focus Trap in Dialogs **Error**: Tab key exits dialog to background content **Source**: WCAG 2.4.3 (Focus Order) **Why It Happens**: No focus trap implementation **Prevention**: Implement focus trap for modal dialogs ### Issue #8: Missing aria-live for Dynamic Content **Error**: Screen reader doesn't announce updates **Source**: WCAG 4.1.3 (Status Messages) **Why It Happens**: Dynamic content added without announcement **Prevention**: Use aria-live="polite" or "assertive" ### Issue #9: Color-Only Information **Error**: Using only color to convey status **Source**: WCAG 1.4.1 (Use of Color) **Why It Happens**: Red text for errors without icon/text **Prevention**: Add icon + text label, not just color ### Issue #10: Non-descriptive Link Text **Error**: Links with "click here" or "read more" **Source**: WCAG 2.4.4 (Link Purpose) **Why It Happens**: Generic link text without context **Prevention**: Use descriptive link text or aria-label ### Issue #11: Auto-playing Media **Error**: Video/audio auto-plays without user control **Source**: WCAG 1.4.2 (Audio Control) **Why It Happens**: Autoplay attribute without controls **Prevention**: Require user interaction to start media ### Issue #12: Inaccessible Custom Controls **Error**: Custom select/checkbox without keyboard support **Source**: WCAG 4.1.2 (Name, Role, Value) **Why It Happens**: Building from divs without ARIA **Prevention**: Use native elements or implement full ARIA pattern --- ## WCAG 2.1 AA Quick Checklist ### Perceivable - [ ] All images have alt text (or alt="" if decorative) - [ ] Text contrast ≥ 4.5:1 (normal), ≥ 3:1 (large) - [ ] Color not used alone to convey information - [ ] Text can be resized to 200% without loss of content - [ ] No auto-playing audio >3 seconds ### Operable - [ ] All functionality keyboard accessible - [ ] No keyboard traps - [ ] Visible focus indicators - [ ] Users can pause/stop/hide moving content - [ ] Page titles describe purpose - [ ] Focus order is logical - [ ] Link purpose clear from text or context - [ ] Multiple ways to find pages (menu, search, sitemap) - [ ] Headings and labels describe purpose ### Understandable - [ ] Page language specified (`<html lang="en">`) - [ ] Language changes marked (`<span lang="es">`) - [ ] No unexpected context changes on focus/input - [ ] Consistent navigation across site - [ ] Form labels/instructions provided - [ ] Input errors identified and described - [ ] Error prevention for legal/financial/data changes ### Robust - [ ] Valid HTML (no parsing errors) - [ ] Name, role, value available for all UI components - [ ] Status messages identified (aria-live) --- ## Testing Workflow ### 1. Keyboard-Only Testing (5 minutes) ``` 1. Unplug mouse or hide cursor 2. Tab through entire page - Can you reach all interactive elements? - Can you activate all buttons/links? - Is focus order logical? 3. Use Enter/Space to activate 4. Use Escape to close dialogs 5. Use arrow keys in menus/tabs ```
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub