| name | accessibility-wcag-patterns |
| description | WCAG 2.1 AA compliance, ARIA attributes, keyboard navigation, screen reader optimization for accessible political data platforms |
| license | Apache-2.0 |
Accessibility WCAG Patterns
Purpose
This skill provides guidance for implementing WCAG 2.1 Level AA accessibility standards in the CIA platform, ensuring political transparency data is accessible to all users including those with disabilities. Covers ARIA attributes, keyboard navigation, screen reader optimization, and automated accessibility testing.
When to Use
✅ Use this skill when:
- Designing new UI components
- Implementing forms and interactive elements
- Creating data visualizations and charts
- Building responsive layouts
- Reviewing UI for accessibility compliance
- Fixing accessibility violations
- Writing automated accessibility tests
- Conducting accessibility audits
❌ Don't use this skill for:
- General UI design patterns (use vaadin-component-design)
- Performance optimization (use code-quality-checks)
- Security (use input-validation, secure-code-review)
- Backend implementation (use spring-framework-patterns)
Patterns & Examples
WCAG 2.1 Compliance Checklist
Level A (Must Have):
Level AA (Target):
Vaadin Accessibility Patterns
@Route("politician/edit")
public class PoliticianEditView extends VerticalLayout {
public PoliticianEditView() {
getElement().setAttribute("role", "main");
getElement().setAttribute("aria-label", "Edit Politician Profile");
H1 title = new H1("Edit Politician Profile");
add(title);
TextField nameField = new TextField("Full Name");
nameField.setRequired(true);
nameField.setErrorMessage("Name is required");
nameField.setAriaLabel("Politician full name");
TextArea bioField = new TextArea("Biography");
bioField.setMaxLength(1000);
bioField.setHelperText("Maximum 1000 characters");
bioField.setAriaLabel("Politician biography");
Select<String> partySelect = new Select<>();
partySelect.setLabel("Political Party");
partySelect.setItems(, , );
partySelect.setRequiredIndicatorVisible();
();
saveButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
saveButton.setAriaLabel();
saveButton.setIcon( (VaadinIcon.CHECK));
();
cancelButton.setAriaLabel();
cancelButton.setIcon( (VaadinIcon.CLOSE));
(saveButton, cancelButton);
buttons.getElement().setAttribute(, );
buttons.getElement().setAttribute(, );
add(nameField, bioField, partySelect, buttons);
}
}
Accessible Data Table
Grid<Politician> grid = new Grid<>(Politician.class, false);
grid.setAriaLabel("Politicians List");
grid.addColumn(Politician::getName)
.setHeader("Name")
.setSortable(true)
.setAriaLabel("Politician name, sortable");
grid.addColumn(Politician::getParty)
.setHeader("Party")
.setSortable(true);
grid.addColumn(politician -> {
Span badge = new Span(String.format("%.0f", politician.getRiskScore()));
badge.getElement().getThemeList().add(
politician.getRiskScore() > 70 ? "badge error" : "badge success"
);
badge.getElement().setAttribute("aria-label",
String.format("Risk score %d out of 100",
Math.round(politician.getRiskScore())));
return badge;
})
.setHeader("Risk Score")
.setAriaLabel("Risk assessment score");
grid.setSelectionMode(Grid.SelectionMode.SINGLE);
grid.addFocusListener(e -> {
Notification.show("Use arrow keys to navigate, Enter to select");
});
Color Contrast Compliance
:root {
--text-primary: #212121;
--text-secondary: #616161;
--risk-high-bg: #c62828;
--risk-high-text: #ffffff;
--risk-medium-bg: #f57c00;
--risk-medium-text: #000000;
--risk-low-bg: #2e7d32;
--risk-low-text: #ffffff;
--focus-outline: 3px solid #1976d2;
--focus-outline-offset: 2px;
}
button:focus,
a:focus,
input:focus,
select:focus,
textarea:focus {
outline: var(--focus-outline);
outline-offset: var(--focus-outline-offset);
}
{
: absolute;
: -;
: ;
: ;
: ;
: ;
: none;
: ;
}
{
: ;
}
Screen Reader Optimization
<header role="banner">
<h1>Citizen Intelligence Agency</h1>
<nav role="navigation" aria-label="Main navigation">
</nav>
</header>
<main role="main" aria-labelledby="page-title">
<h1 id="page-title">Politician Risk Dashboard</h1>
<div aria-live="polite" aria-atomic="true" class="sr-only">
</div>
<form role="search" aria-label="Search politicians">
<label for="search-input">Search by name or party</label>
<input
=
=
=
/>
Enter at least 3 characters to search
Risk Score Distribution
Bar chart showing risk score distribution across 349 politicians.
Highest concentration in 40-60 range.
Keyboard Navigation Patterns
class AccessibleRiskSlider {
constructor(element) {
this.element = element;
this.value = 50;
this.min = 0;
this.max = 100;
element.setAttribute('role', 'slider');
element.setAttribute('aria-valuemin', this.min);
element.setAttribute('aria-valuemax', this.max);
element.setAttribute('aria-valuenow', this.value);
element.setAttribute('aria-label', 'Filter by risk score');
element.setAttribute('tabindex', '0');
element.addEventListener('keydown', this.handleKeyDown.bind(this));
}
handleKeyDown(event) {
let newValue = .;
(event.) {
:
:
newValue = .(. + , .);
event.();
;
:
:
newValue = .(. - , .);
event.();
;
:
newValue = .;
event.();
;
:
newValue = .;
event.();
;
:
newValue = .(. + , .);
event.();
;
:
newValue = .(. - , .);
event.();
;
}
(newValue !== .) {
.(newValue);
}
}
() {
. = value;
..(, value);
.();
..( (, { : value }));
}
}
ISMS Compliance Mapping
ISO 27001:2022 Annex A Controls
A.7.1 - Physical and environmental security
- Digital accessibility ensures equal access to information
A.5.1 - Policies for information security
- Accessibility policy as part of information security
GDPR Considerations
Article 9 - Processing of special categories
- Accessibility features must not discriminate
- Equal access to personal data for data subjects with disabilities
Legal Requirements
EU Web Accessibility Directive
- Public sector websites must meet WCAG 2.1 Level AA
- Accessibility statements required
- Compliance monitoring and reporting
Hack23 ISMS Policy References
References
Standards & Guidelines
Testing Tools
Remember
- Accessibility is not optional: WCAG 2.1 AA is the baseline
- Test with real users: Include users with disabilities in testing
- Keyboard-first design: All functionality via keyboard
- Semantic HTML: Use proper elements for structure
- Progressive enhancement: Core content accessible without JavaScript
- Automated testing: Integrate accessibility checks in CI/CD