7.2 KiB
name, description
| name | description |
|---|---|
| angular-accessibility | Enforce and improve accessibility (a11y) in Angular applications following WCAG 2.2 AA, ARIA best practices, semantic HTML, and Angular-specific patterns. |
Angular Accessibility Skill
Purpose
This skill helps build and review Angular applications that are accessible by default. It prioritizes semantic HTML, keyboard navigation, screen reader compatibility, color contrast, focus management, and Angular CDK accessibility utilities.
Target standard: WCAG 2.2 Level AA
When to Use
Activate this skill whenever the task involves:
- Creating Angular components
- Reviewing templates for accessibility
- Refactoring UI components
- Building forms
- Navigation menus
- Dialogs and modals
- Tables
- Custom controls
- Angular Material components
- Accessibility audits
- Fixing Lighthouse or axe-core accessibility issues
Accessibility Principles
Always follow this priority order:
- Semantic HTML
- Native browser behavior
- Angular accessibility utilities
- ARIA only when necessary
Rule: Never use ARIA to replace native HTML functionality.
Example:
Good:
<button type="button">Save</button>
Avoid:
<div role="button">Save</div>
Angular Template Rules
Buttons
Always:
- use
<button> - specify
type - provide accessible text
Good:
<button type="submit">Submit</button>
Icon button:
<button type="button" aria-label="Close dialog">
<mat-icon>close</mat-icon>
</button>
Links
Use <a> only for navigation.
Good:
<a routerLink="/dashboard">Dashboard</a>
Avoid:
<a (click)="save()">Save</a>
Use a button instead.
Images
Decorative:
<img src="divider.svg" alt="">
Informative:
<img src="profile.jpg" alt="Jane Doe smiling">
Avoid generic alt text like "image" or "photo."
Forms
Labels
Every input needs a label.
Good:
<label for="email">Email</label>
<input id="email" type="email">
Angular Material:
<mat-form-field>
<mat-label>Email</mat-label>
<input matInput type="email">
</mat-form-field>
Error Messages
Requirements:
- visible
- descriptive
- associated with the input
Example:
<input
id="email"
aria-describedby="email-error">
<div id="email-error">
Enter a valid email address.
</div>
Avoid relying on color alone.
Required Fields
Use both:
<input required aria-required="true">
Keyboard Accessibility
Every interactive element must be usable with:
- Tab
- Shift+Tab
- Enter
- Space
- Escape (when applicable)
- Arrow keys (where expected)
Never trap keyboard focus.
Focus Management
Use Angular CDK when possible.
Example:
constructor(private focusMonitor: FocusMonitor) {}
For dialogs:
- move focus into dialog
- trap focus
- restore focus on close
Angular Material already provides this behavior.
Angular CDK Accessibility
Prefer Angular CDK utilities.
Useful services:
- FocusMonitor
- LiveAnnouncer
- InteractivityChecker
- FocusTrapFactory
Example:
this.liveAnnouncer.announce('Settings saved');
Use for:
- success messages
- validation updates
- dynamic content
ARIA Usage
Use ARIA only when native HTML cannot express the behavior.
Common attributes:
| Attribute | Use |
|---|---|
| aria-label | Icon buttons |
| aria-labelledby | Existing visible label |
| aria-describedby | Helper/error text |
| aria-expanded | Expandable controls |
| aria-controls | Controlled region |
| aria-live | Dynamic announcements |
| aria-current | Current navigation item |
Avoid redundant ARIA.
Bad:
<button role="button">
Navigation
Provide a skip link.
Example:
<a href="#main" class="skip-link">
Skip to main content
</a>
Use landmarks:
<header>
<nav>
<main id="main">
<footer>
Tables
Use proper table structure.
Good:
<table>
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Role</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alice</td>
<td>Admin</td>
</tr>
</tbody>
</table>
Avoid tables for layout.
Dialogs
Requirements:
- focus trap
- Escape closes dialog
- initial focus
- restore focus afterward
Angular Material Dialog already supports most of these.
Add:
<h2 mat-dialog-title>
for proper dialog labeling.
Custom Components
When creating custom controls:
Implement:
- keyboard interaction
- focus visibility
- accessible name
- appropriate ARIA state
Example checklist:
- Tab reachable
- Enter works
- Space works
- Focus visible
- Screen reader announces purpose
Color and Contrast
Minimum ratios:
| Text | Ratio |
|---|---|
| Normal | 4.5:1 |
| Large | 3:1 |
Never communicate information using color alone.
Instead of:
- Red = error
Use:
- icon
- text
- color
Focus Indicators
Never remove focus outlines unless replacing them.
Good:
:focus-visible {
outline: 2px solid #005fcc;
outline-offset: 2px;
}
Avoid:
outline: none;
Motion
Respect reduced motion.
Example:
@media (prefers-reduced-motion: reduce) {
* {
animation: none;
transition: none;
}
}
Angular Material Guidance
Prefer built-in accessible components.
Good choices:
- MatButton
- MatDialog
- MatMenu
- MatCheckbox
- MatRadio
- MatSelect
- MatSnackBar
- MatTabs
Verify:
- labels
- keyboard support
- announcements
Testing Checklist
Before completing any accessibility task:
Keyboard
- Everything reachable with Tab
- No keyboard traps
- Enter works
- Space works
- Escape works where appropriate
Screen Reader
- Controls have accessible names
- Form fields have labels
- Errors are announced
- Dynamic updates are announced
Visual
- Contrast passes WCAG
- Focus visible
- No color-only communication
- Text scales properly
Automated Testing
Recommend these tools:
Angular ESLint
Enable accessibility rules.
axe-core
Use for automated audits.
Example:
- axe DevTools
- Cypress + axe
- Playwright + axe
Lighthouse
Run accessibility audits regularly.
Treat Lighthouse as a guide rather than the only authority.
Code Review Rules
Whenever reviewing Angular code:
- Replace non-semantic elements with semantic HTML.
- Add missing labels.
- Improve keyboard support.
- Remove unnecessary ARIA.
- Fix focus management.
- Ensure dynamic updates are announced.
- Verify Angular Material accessibility.
- Confirm WCAG 2.2 AA compliance.
Always explain:
- why the issue affects accessibility
- the WCAG principle involved
- the preferred Angular solution
- the corrected code