Web Accessibility: A Developer's Guide
Web accessibility ensures that websites and applications are usable by everyone, including people with disabilities. This comprehensive guide will help you understand and implement accessibility best practices in your projects.
Understanding Accessibility
What is Web Accessibility?
Web accessibility means that websites, tools, and technologies are designed and developed so that people with disabilities can use them. This includes:
- Visual impairments: Blindness, low vision, color blindness
- Motor impairments: Limited fine motor control, tremors
- Cognitive impairments: Learning disabilities, attention disorders
- Hearing impairments: Deafness, hard of hearing
The Business Case
Accessibility isn't just the right thing to do—it's good business:
- Legal compliance: Avoid lawsuits and meet regulations
- Broader audience: Reach more users and customers
- Better SEO: Accessible sites often rank better
- Improved UX: Better for all users, not just those with disabilities
Semantic HTML: The Foundation
Use Proper HTML Elements
Semantic HTML provides meaning and structure:
html
Article Title
Article content...
Heading Hierarchy
Create a logical heading structure:
html
Page Title
Section Title
Subsection Title
Another Subsection
Another Section
Subsection
ARIA: Enhancing Semantics
ARIA Labels and Descriptions
Provide additional context for screen readers:
html
type="password"
id="password"
aria-describedby="password-help"
required
>
Password must be at least 8 characters long
src="chart.png"
alt="Sales increased by 25% in Q3 2024"
>
ARIA States and Properties
Convey dynamic state information:
html
type="email"
aria-invalid="true"
aria-describedby="email-error"
>
Please enter a valid email address
Keyboard Navigation
Focus Management
Ensure all interactive elements are keyboard accessible:
css
/ Visible focus indicators /
:focus {
outline: 2px solid #0066cc;
outline-offset: 2px;
}
/ Custom focus styles /
.button:focus {
box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.3);
}
Tab Order
Maintain logical tab order:
html
Skip Links
Provide shortcuts for keyboard users:
html
Skip to main content
css
.skip-link {
position: absolute;
top: -40px;
left: 6px;
background: #000;
color: #fff;
padding: 8px;
text-decoration: none;
z-index: 1000;
}
.skip-link:focus {
top: 6px;
}
Color and Contrast
Color Contrast Ratios
Ensure sufficient contrast between text and background:
- Normal text: 4.5:1 contrast ratio
- Large text: 3:1 contrast ratio
- UI components: 3:1 contrast ratio
css
/ ✅ Good contrast /
.text-dark {
color: #000000; / Black text /
background: #ffffff; / White background /
/ Contrast ratio: 21:1 /
}
.text-medium {
color: #333333; / Dark gray /
background: #ffffff; / White background /
/ Contrast ratio: 12.6:1 /
}
/ ❌ Poor contrast /
.text-poor {
color: #999999; / Light gray /
background: #ffffff; / White background /
/ Contrast ratio: 2.8:1 - Too low! /
}
Don't Rely on Color Alone
Provide additional visual cues:
html
Forms and Inputs
Proper Form Labels
Associate labels with form controls:
html
Username
Form Validation
Provide clear error messages:
html
Required Fields
Clearly indicate required fields:
html
Images and Media
Alt Text
Provide meaningful alternative text:
html



Complex Images
Use long descriptions for complex content:
html
src="infographic.png"
alt="Infographic showing company growth"
longdesc="#infographic-description"
>
Company Growth Infographic
This infographic shows our company's growth over the past five years...
Video and Audio
Provide captions and transcripts:
html
Testing and Validation
Automated Testing Tools
Use tools to catch accessibility issues:
bash
Install axe-core for automated testing
npm install --save-dev @axe-core/react
Install Lighthouse CLI
npm install -g lighthouse
tsx
// React component with axe testing
import { useEffect } from 'react'
import axe from '@axe-core/react'
function App() {
useEffect(() => {
axe(React, ReactDOM, 1000)
}, [])
return (
{/ Your app content */}
)
}
Manual Testing
Test with real assistive technologies:
1. Screen readers: NVDA (Windows), JAWS (Windows), VoiceOver (Mac)
2. Keyboard only: Navigate without mouse
3. Voice control: Dragon NaturallySpeaking, Voice Control
4. Zoom: Test at 200% zoom level
Browser DevTools
Use built-in accessibility features:
- Chrome DevTools: Accessibility panel
- Firefox: Accessibility inspector
- Safari: Web Inspector accessibility features
Common Patterns
Modal Dialogs
Make modals accessible:
tsx
function Modal({ isOpen, onClose, children }) {
useEffect(() => {
if (isOpen) {
// Trap focus
const focusableElements = modalRef.current?.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
)
if (focusableElements?.length) {
focusableElements[0].focus()
}
}
}, [isOpen])
if (!isOpen) return null
return (
className="modal-overlay"
onClick={onClose}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
className="modal-content"
onClick={e => e.stopPropagation()}
ref={modalRef}
>
Modal Title
{children}
)
}
Data Tables
Make tables accessible:
html
Monthly Sales Report
Month
Sales
Growth
January
$10,000
+5%
February
$12,000
+20%
Conclusion
Web accessibility is not a one-time task but an ongoing commitment to inclusive design. By following these guidelines and continuously testing with real users, you can create web experiences that work for everyone.
Remember:
- Start with semantic HTML
- Test with real assistive technologies
- Include users with disabilities in your design process
- Make accessibility part of your development workflow
- Keep learning and improving
The web should be accessible to everyone, and as developers, we have the power to make that happen.
What is Web Accessibility?
Web accessibility means that websites, tools, and technologies are designed and developed so that people with disabilities can use them. This includes:
- Visual impairments: Blindness, low vision, color blindness
- Motor impairments: Limited fine motor control, tremors
- Cognitive impairments: Learning disabilities, attention disorders
- Hearing impairments: Deafness, hard of hearing
The Business Case
Accessibility isn't just the right thing to do—it's good business:
- Legal compliance: Avoid lawsuits and meet regulations
- Broader audience: Reach more users and customers
- Better SEO: Accessible sites often rank better
- Improved UX: Better for all users, not just those with disabilities
Semantic HTML: The Foundation
Use Proper HTML Elements
Semantic HTML provides meaning and structure:
html
Article Title
Article content...
Heading Hierarchy
Create a logical heading structure:
html
Page Title
Section Title
Subsection Title
Another Subsection
Another Section
Subsection
ARIA: Enhancing Semantics
ARIA Labels and Descriptions
Provide additional context for screen readers:
html
type="password"
id="password"
aria-describedby="password-help"
required
>
Password must be at least 8 characters long
src="chart.png"
alt="Sales increased by 25% in Q3 2024"
>
ARIA States and Properties
Convey dynamic state information:
html
type="email"
aria-invalid="true"
aria-describedby="email-error"
>
Please enter a valid email address
Keyboard Navigation
Focus Management
Ensure all interactive elements are keyboard accessible:
css
/ Visible focus indicators /
:focus {
outline: 2px solid #0066cc;
outline-offset: 2px;
}
/ Custom focus styles /
.button:focus {
box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.3);
}
Tab Order
Maintain logical tab order:
html
Skip Links
Provide shortcuts for keyboard users:
html
Skip to main content
css
.skip-link {
position: absolute;
top: -40px;
left: 6px;
background: #000;
color: #fff;
padding: 8px;
text-decoration: none;
z-index: 1000;
}
.skip-link:focus {
top: 6px;
}
Color and Contrast
Color Contrast Ratios
Ensure sufficient contrast between text and background:
- Normal text: 4.5:1 contrast ratio
- Large text: 3:1 contrast ratio
- UI components: 3:1 contrast ratio
css
/ ✅ Good contrast /
.text-dark {
color: #000000; / Black text /
background: #ffffff; / White background /
/ Contrast ratio: 21:1 /
}
.text-medium {
color: #333333; / Dark gray /
background: #ffffff; / White background /
/ Contrast ratio: 12.6:1 /
}
/ ❌ Poor contrast /
.text-poor {
color: #999999; / Light gray /
background: #ffffff; / White background /
/ Contrast ratio: 2.8:1 - Too low! /
}
Don't Rely on Color Alone
Provide additional visual cues:
html
Forms and Inputs
Proper Form Labels
Associate labels with form controls:
html
Username
Form Validation
Provide clear error messages:
html
Required Fields
Clearly indicate required fields:
html
Images and Media
Alt Text
Provide meaningful alternative text:
html



Complex Images
Use long descriptions for complex content:
html
src="infographic.png"
alt="Infographic showing company growth"
longdesc="#infographic-description"
>
Company Growth Infographic
This infographic shows our company's growth over the past five years...
Video and Audio
Provide captions and transcripts:
html
Testing and Validation
Automated Testing Tools
Use tools to catch accessibility issues:
bash
Install axe-core for automated testing
npm install --save-dev @axe-core/react
Install Lighthouse CLI
npm install -g lighthouse
tsx
// React component with axe testing
import { useEffect } from 'react'
import axe from '@axe-core/react'
function App() {
useEffect(() => {
axe(React, ReactDOM, 1000)
}, [])
return (
{/ Your app content */}
)
}
Manual Testing
Test with real assistive technologies:
1. Screen readers: NVDA (Windows), JAWS (Windows), VoiceOver (Mac)
2. Keyboard only: Navigate without mouse
3. Voice control: Dragon NaturallySpeaking, Voice Control
4. Zoom: Test at 200% zoom level
Browser DevTools
Use built-in accessibility features:
- Chrome DevTools: Accessibility panel
- Firefox: Accessibility inspector
- Safari: Web Inspector accessibility features
Common Patterns
Modal Dialogs
Make modals accessible:
tsx
function Modal({ isOpen, onClose, children }) {
useEffect(() => {
if (isOpen) {
// Trap focus
const focusableElements = modalRef.current?.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
)
if (focusableElements?.length) {
focusableElements[0].focus()
}
}
}, [isOpen])
if (!isOpen) return null
return (
className="modal-overlay"
onClick={onClose}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
className="modal-content"
onClick={e => e.stopPropagation()}
ref={modalRef}
>
Modal Title
{children}
)
}
Data Tables
Make tables accessible:
html
Monthly Sales Report
Month
Sales
Growth
January
$10,000
+5%
February
$12,000
+20%
Conclusion
Web accessibility is not a one-time task but an ongoing commitment to inclusive design. By following these guidelines and continuously testing with real users, you can create web experiences that work for everyone.
Remember:
- Start with semantic HTML
- Test with real assistive technologies
- Include users with disabilities in your design process
- Make accessibility part of your development workflow
- Keep learning and improving
The web should be accessible to everyone, and as developers, we have the power to make that happen.
Accessibility isn't just the right thing to do—it's good business:
- Legal compliance: Avoid lawsuits and meet regulations
- Broader audience: Reach more users and customers
- Better SEO: Accessible sites often rank better
- Improved UX: Better for all users, not just those with disabilities
Semantic HTML: The Foundation
Use Proper HTML Elements
Semantic HTML provides meaning and structure:
html
Article Title
Article content...
Heading Hierarchy
Create a logical heading structure:
html
Page Title
Section Title
Subsection Title
Another Subsection
Another Section
Subsection
ARIA: Enhancing Semantics
ARIA Labels and Descriptions
Provide additional context for screen readers:
html
type="password"
id="password"
aria-describedby="password-help"
required
>
Password must be at least 8 characters long
src="chart.png"
alt="Sales increased by 25% in Q3 2024"
>
ARIA States and Properties
Convey dynamic state information:
html
type="email"
aria-invalid="true"
aria-describedby="email-error"
>
Please enter a valid email address
Keyboard Navigation
Focus Management
Ensure all interactive elements are keyboard accessible:
css
/ Visible focus indicators /
:focus {
outline: 2px solid #0066cc;
outline-offset: 2px;
}
/ Custom focus styles /
.button:focus {
box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.3);
}
Tab Order
Maintain logical tab order:
html
Skip Links
Provide shortcuts for keyboard users:
html
Skip to main content
css
.skip-link {
position: absolute;
top: -40px;
left: 6px;
background: #000;
color: #fff;
padding: 8px;
text-decoration: none;
z-index: 1000;
}
.skip-link:focus {
top: 6px;
}
Color and Contrast
Color Contrast Ratios
Ensure sufficient contrast between text and background:
- Normal text: 4.5:1 contrast ratio
- Large text: 3:1 contrast ratio
- UI components: 3:1 contrast ratio
css
/ ✅ Good contrast /
.text-dark {
color: #000000; / Black text /
background: #ffffff; / White background /
/ Contrast ratio: 21:1 /
}
.text-medium {
color: #333333; / Dark gray /
background: #ffffff; / White background /
/ Contrast ratio: 12.6:1 /
}
/ ❌ Poor contrast /
.text-poor {
color: #999999; / Light gray /
background: #ffffff; / White background /
/ Contrast ratio: 2.8:1 - Too low! /
}
Don't Rely on Color Alone
Provide additional visual cues:
html
Forms and Inputs
Proper Form Labels
Associate labels with form controls:
html
Username
Form Validation
Provide clear error messages:
html
Required Fields
Clearly indicate required fields:
html
Images and Media
Alt Text
Provide meaningful alternative text:
html



Complex Images
Use long descriptions for complex content:
html
src="infographic.png"
alt="Infographic showing company growth"
longdesc="#infographic-description"
>
Company Growth Infographic
This infographic shows our company's growth over the past five years...
Video and Audio
Provide captions and transcripts:
html
Testing and Validation
Automated Testing Tools
Use tools to catch accessibility issues:
bash
Install axe-core for automated testing
npm install --save-dev @axe-core/react
Install Lighthouse CLI
npm install -g lighthouse
tsx
// React component with axe testing
import { useEffect } from 'react'
import axe from '@axe-core/react'
function App() {
useEffect(() => {
axe(React, ReactDOM, 1000)
}, [])
return (
{/ Your app content */}
)
}
Manual Testing
Test with real assistive technologies:
1. Screen readers: NVDA (Windows), JAWS (Windows), VoiceOver (Mac)
2. Keyboard only: Navigate without mouse
3. Voice control: Dragon NaturallySpeaking, Voice Control
4. Zoom: Test at 200% zoom level
Browser DevTools
Use built-in accessibility features:
- Chrome DevTools: Accessibility panel
- Firefox: Accessibility inspector
- Safari: Web Inspector accessibility features
Common Patterns
Modal Dialogs
Make modals accessible:
tsx
function Modal({ isOpen, onClose, children }) {
useEffect(() => {
if (isOpen) {
// Trap focus
const focusableElements = modalRef.current?.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
)
if (focusableElements?.length) {
focusableElements[0].focus()
}
}
}, [isOpen])
if (!isOpen) return null
return (
className="modal-overlay"
onClick={onClose}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
className="modal-content"
onClick={e => e.stopPropagation()}
ref={modalRef}
>
Modal Title
{children}
)
}
Data Tables
Make tables accessible:
html
Monthly Sales Report
Month
Sales
Growth
January
$10,000
+5%
February
$12,000
+20%
Conclusion
Web accessibility is not a one-time task but an ongoing commitment to inclusive design. By following these guidelines and continuously testing with real users, you can create web experiences that work for everyone.
Remember:
- Start with semantic HTML
- Test with real assistive technologies
- Include users with disabilities in your design process
- Make accessibility part of your development workflow
- Keep learning and improving
The web should be accessible to everyone, and as developers, we have the power to make that happen.
Semantic HTML provides meaning and structure:
html
Article Title
Article content...
Heading Hierarchy
Create a logical heading structure:
html
Page Title
Section Title
Subsection Title
Another Subsection
Another Section
Subsection
ARIA: Enhancing Semantics
ARIA Labels and Descriptions
Provide additional context for screen readers:
html
type="password"
id="password"
aria-describedby="password-help"
required
>
Password must be at least 8 characters long
src="chart.png"
alt="Sales increased by 25% in Q3 2024"
>
ARIA States and Properties
Convey dynamic state information:
html
type="email"
aria-invalid="true"
aria-describedby="email-error"
>
Please enter a valid email address
Keyboard Navigation
Focus Management
Ensure all interactive elements are keyboard accessible:
css
/ Visible focus indicators /
:focus {
outline: 2px solid #0066cc;
outline-offset: 2px;
}
/ Custom focus styles /
.button:focus {
box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.3);
}
Tab Order
Maintain logical tab order:
html
Skip Links
Provide shortcuts for keyboard users:
html
Skip to main content
css
.skip-link {
position: absolute;
top: -40px;
left: 6px;
background: #000;
color: #fff;
padding: 8px;
text-decoration: none;
z-index: 1000;
}
.skip-link:focus {
top: 6px;
}
Color and Contrast
Color Contrast Ratios
Ensure sufficient contrast between text and background:
- Normal text: 4.5:1 contrast ratio
- Large text: 3:1 contrast ratio
- UI components: 3:1 contrast ratio
css
/ ✅ Good contrast /
.text-dark {
color: #000000; / Black text /
background: #ffffff; / White background /
/ Contrast ratio: 21:1 /
}
.text-medium {
color: #333333; / Dark gray /
background: #ffffff; / White background /
/ Contrast ratio: 12.6:1 /
}
/ ❌ Poor contrast /
.text-poor {
color: #999999; / Light gray /
background: #ffffff; / White background /
/ Contrast ratio: 2.8:1 - Too low! /
}
Don't Rely on Color Alone
Provide additional visual cues:
html
Forms and Inputs
Proper Form Labels
Associate labels with form controls:
html
Username
Form Validation
Provide clear error messages:
html
Required Fields
Clearly indicate required fields:
html
Images and Media
Alt Text
Provide meaningful alternative text:
html



Complex Images
Use long descriptions for complex content:
html
src="infographic.png"
alt="Infographic showing company growth"
longdesc="#infographic-description"
>
Company Growth Infographic
This infographic shows our company's growth over the past five years...
Video and Audio
Provide captions and transcripts:
html
Testing and Validation
Automated Testing Tools
Use tools to catch accessibility issues:
bash
Install axe-core for automated testing
npm install --save-dev @axe-core/react
Install Lighthouse CLI
npm install -g lighthouse
tsx
// React component with axe testing
import { useEffect } from 'react'
import axe from '@axe-core/react'
function App() {
useEffect(() => {
axe(React, ReactDOM, 1000)
}, [])
return (
{/ Your app content */}
)
}
Manual Testing
Test with real assistive technologies:
1. Screen readers: NVDA (Windows), JAWS (Windows), VoiceOver (Mac)
2. Keyboard only: Navigate without mouse
3. Voice control: Dragon NaturallySpeaking, Voice Control
4. Zoom: Test at 200% zoom level
Browser DevTools
Use built-in accessibility features:
- Chrome DevTools: Accessibility panel
- Firefox: Accessibility inspector
- Safari: Web Inspector accessibility features
Common Patterns
Modal Dialogs
Make modals accessible:
tsx
function Modal({ isOpen, onClose, children }) {
useEffect(() => {
if (isOpen) {
// Trap focus
const focusableElements = modalRef.current?.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
)
if (focusableElements?.length) {
focusableElements[0].focus()
}
}
}, [isOpen])
if (!isOpen) return null
return (
className="modal-overlay"
onClick={onClose}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
className="modal-content"
onClick={e => e.stopPropagation()}
ref={modalRef}
>
Modal Title
{children}
)
}
Data Tables
Make tables accessible:
html
Monthly Sales Report
Month
Sales
Growth
January
$10,000
+5%
February
$12,000
+20%
Conclusion
Web accessibility is not a one-time task but an ongoing commitment to inclusive design. By following these guidelines and continuously testing with real users, you can create web experiences that work for everyone.
Remember:
- Start with semantic HTML
- Test with real assistive technologies
- Include users with disabilities in your design process
- Make accessibility part of your development workflow
- Keep learning and improving
The web should be accessible to everyone, and as developers, we have the power to make that happen.
html
Page Title
Section Title
Subsection Title
Another Subsection
Another Section
Subsection
ARIA Labels and Descriptions
Provide additional context for screen readers:
html
type="password"
id="password"
aria-describedby="password-help"
required
>
Password must be at least 8 characters long
src="chart.png"
alt="Sales increased by 25% in Q3 2024"
>
ARIA States and Properties
Convey dynamic state information:
html
type="email"
aria-invalid="true"
aria-describedby="email-error"
>
Please enter a valid email address
Keyboard Navigation
Focus Management
Ensure all interactive elements are keyboard accessible:
css
/ Visible focus indicators /
:focus {
outline: 2px solid #0066cc;
outline-offset: 2px;
}
/ Custom focus styles /
.button:focus {
box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.3);
}
Tab Order
Maintain logical tab order:
html
Skip Links
Provide shortcuts for keyboard users:
html
Skip to main content
css
.skip-link {
position: absolute;
top: -40px;
left: 6px;
background: #000;
color: #fff;
padding: 8px;
text-decoration: none;
z-index: 1000;
}
.skip-link:focus {
top: 6px;
}
Color and Contrast
Color Contrast Ratios
Ensure sufficient contrast between text and background:
- Normal text: 4.5:1 contrast ratio
- Large text: 3:1 contrast ratio
- UI components: 3:1 contrast ratio
css
/ ✅ Good contrast /
.text-dark {
color: #000000; / Black text /
background: #ffffff; / White background /
/ Contrast ratio: 21:1 /
}
.text-medium {
color: #333333; / Dark gray /
background: #ffffff; / White background /
/ Contrast ratio: 12.6:1 /
}
/ ❌ Poor contrast /
.text-poor {
color: #999999; / Light gray /
background: #ffffff; / White background /
/ Contrast ratio: 2.8:1 - Too low! /
}
Don't Rely on Color Alone
Provide additional visual cues:
html
Forms and Inputs
Proper Form Labels
Associate labels with form controls:
html
Username
Form Validation
Provide clear error messages:
html
Required Fields
Clearly indicate required fields:
html
Images and Media
Alt Text
Provide meaningful alternative text:
html



Complex Images
Use long descriptions for complex content:
html
src="infographic.png"
alt="Infographic showing company growth"
longdesc="#infographic-description"
>
Company Growth Infographic
This infographic shows our company's growth over the past five years...
Video and Audio
Provide captions and transcripts:
html
Testing and Validation
Automated Testing Tools
Use tools to catch accessibility issues:
bash
Install axe-core for automated testing
npm install --save-dev @axe-core/react
Install Lighthouse CLI
npm install -g lighthouse
tsx
// React component with axe testing
import { useEffect } from 'react'
import axe from '@axe-core/react'
function App() {
useEffect(() => {
axe(React, ReactDOM, 1000)
}, [])
return (
{/ Your app content */}
)
}
Manual Testing
Test with real assistive technologies:
1. Screen readers: NVDA (Windows), JAWS (Windows), VoiceOver (Mac)
2. Keyboard only: Navigate without mouse
3. Voice control: Dragon NaturallySpeaking, Voice Control
4. Zoom: Test at 200% zoom level
Browser DevTools
Use built-in accessibility features:
- Chrome DevTools: Accessibility panel
- Firefox: Accessibility inspector
- Safari: Web Inspector accessibility features
Common Patterns
Modal Dialogs
Make modals accessible:
tsx
function Modal({ isOpen, onClose, children }) {
useEffect(() => {
if (isOpen) {
// Trap focus
const focusableElements = modalRef.current?.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
)
if (focusableElements?.length) {
focusableElements[0].focus()
}
}
}, [isOpen])
if (!isOpen) return null
return (
className="modal-overlay"
onClick={onClose}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
className="modal-content"
onClick={e => e.stopPropagation()}
ref={modalRef}
>
Modal Title
{children}
)
}
Data Tables
Make tables accessible:
html
Monthly Sales Report
Month
Sales
Growth
January
$10,000
+5%
February
$12,000
+20%
Conclusion
Web accessibility is not a one-time task but an ongoing commitment to inclusive design. By following these guidelines and continuously testing with real users, you can create web experiences that work for everyone.
Remember:
- Start with semantic HTML
- Test with real assistive technologies
- Include users with disabilities in your design process
- Make accessibility part of your development workflow
- Keep learning and improving
The web should be accessible to everyone, and as developers, we have the power to make that happen.
html
type="password"
id="password"
aria-describedby="password-help"
required
>
Password must be at least 8 characters long
src="chart.png"
alt="Sales increased by 25% in Q3 2024"
>
Convey dynamic state information:
html
type="email"
aria-invalid="true"
aria-describedby="email-error"
>
Please enter a valid email address
Keyboard Navigation
Focus Management
Ensure all interactive elements are keyboard accessible:
css
/ Visible focus indicators /
:focus {
outline: 2px solid #0066cc;
outline-offset: 2px;
}
/ Custom focus styles /
.button:focus {
box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.3);
}
Tab Order
Maintain logical tab order:
html
Skip Links
Provide shortcuts for keyboard users:
html
Skip to main content
css
.skip-link {
position: absolute;
top: -40px;
left: 6px;
background: #000;
color: #fff;
padding: 8px;
text-decoration: none;
z-index: 1000;
}
.skip-link:focus {
top: 6px;
}
Color and Contrast
Color Contrast Ratios
Ensure sufficient contrast between text and background:
- Normal text: 4.5:1 contrast ratio
- Large text: 3:1 contrast ratio
- UI components: 3:1 contrast ratio
css
/ ✅ Good contrast /
.text-dark {
color: #000000; / Black text /
background: #ffffff; / White background /
/ Contrast ratio: 21:1 /
}
.text-medium {
color: #333333; / Dark gray /
background: #ffffff; / White background /
/ Contrast ratio: 12.6:1 /
}
/ ❌ Poor contrast /
.text-poor {
color: #999999; / Light gray /
background: #ffffff; / White background /
/ Contrast ratio: 2.8:1 - Too low! /
}
Don't Rely on Color Alone
Provide additional visual cues:
html
Forms and Inputs
Proper Form Labels
Associate labels with form controls:
html
Username
Form Validation
Provide clear error messages:
html
Required Fields
Clearly indicate required fields:
html
Images and Media
Alt Text
Provide meaningful alternative text:
html



Complex Images
Use long descriptions for complex content:
html
src="infographic.png"
alt="Infographic showing company growth"
longdesc="#infographic-description"
>
Company Growth Infographic
This infographic shows our company's growth over the past five years...
Video and Audio
Provide captions and transcripts:
html
Testing and Validation
Automated Testing Tools
Use tools to catch accessibility issues:
bash
Install axe-core for automated testing
npm install --save-dev @axe-core/react
Install Lighthouse CLI
npm install -g lighthouse
tsx
// React component with axe testing
import { useEffect } from 'react'
import axe from '@axe-core/react'
function App() {
useEffect(() => {
axe(React, ReactDOM, 1000)
}, [])
return (
{/ Your app content */}
)
}
Manual Testing
Test with real assistive technologies:
1. Screen readers: NVDA (Windows), JAWS (Windows), VoiceOver (Mac)
2. Keyboard only: Navigate without mouse
3. Voice control: Dragon NaturallySpeaking, Voice Control
4. Zoom: Test at 200% zoom level
Browser DevTools
Use built-in accessibility features:
- Chrome DevTools: Accessibility panel
- Firefox: Accessibility inspector
- Safari: Web Inspector accessibility features
Common Patterns
Modal Dialogs
Make modals accessible:
tsx
function Modal({ isOpen, onClose, children }) {
useEffect(() => {
if (isOpen) {
// Trap focus
const focusableElements = modalRef.current?.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
)
if (focusableElements?.length) {
focusableElements[0].focus()
}
}
}, [isOpen])
if (!isOpen) return null
return (
className="modal-overlay"
onClick={onClose}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
className="modal-content"
onClick={e => e.stopPropagation()}
ref={modalRef}
>
Modal Title
{children}
)
}
Data Tables
Make tables accessible:
html
Monthly Sales Report
Month
Sales
Growth
January
$10,000
+5%
February
$12,000
+20%
Conclusion
Web accessibility is not a one-time task but an ongoing commitment to inclusive design. By following these guidelines and continuously testing with real users, you can create web experiences that work for everyone.
Remember:
- Start with semantic HTML
- Test with real assistive technologies
- Include users with disabilities in your design process
- Make accessibility part of your development workflow
- Keep learning and improving
The web should be accessible to everyone, and as developers, we have the power to make that happen.
Ensure all interactive elements are keyboard accessible:
css
/ Visible focus indicators /
:focus {
outline: 2px solid #0066cc;
outline-offset: 2px;
}
/ Custom focus styles /
.button:focus {
box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.3);
}
Tab Order
Maintain logical tab order:
html
Skip Links
Provide shortcuts for keyboard users:
html
Skip to main content
css
.skip-link {
position: absolute;
top: -40px;
left: 6px;
background: #000;
color: #fff;
padding: 8px;
text-decoration: none;
z-index: 1000;
}
.skip-link:focus {
top: 6px;
}
Color and Contrast
Color Contrast Ratios
Ensure sufficient contrast between text and background:
- Normal text: 4.5:1 contrast ratio
- Large text: 3:1 contrast ratio
- UI components: 3:1 contrast ratio
css
/ ✅ Good contrast /
.text-dark {
color: #000000; / Black text /
background: #ffffff; / White background /
/ Contrast ratio: 21:1 /
}
.text-medium {
color: #333333; / Dark gray /
background: #ffffff; / White background /
/ Contrast ratio: 12.6:1 /
}
/ ❌ Poor contrast /
.text-poor {
color: #999999; / Light gray /
background: #ffffff; / White background /
/ Contrast ratio: 2.8:1 - Too low! /
}
Don't Rely on Color Alone
Provide additional visual cues:
html
Forms and Inputs
Proper Form Labels
Associate labels with form controls:
html
Username
Form Validation
Provide clear error messages:
html
Required Fields
Clearly indicate required fields:
html
Images and Media
Alt Text
Provide meaningful alternative text:
html



Complex Images
Use long descriptions for complex content:
html
src="infographic.png"
alt="Infographic showing company growth"
longdesc="#infographic-description"
>
Company Growth Infographic
This infographic shows our company's growth over the past five years...
Video and Audio
Provide captions and transcripts:
html
Testing and Validation
Automated Testing Tools
Use tools to catch accessibility issues:
bash
Install axe-core for automated testing
npm install --save-dev @axe-core/react
Install Lighthouse CLI
npm install -g lighthouse
tsx
// React component with axe testing
import { useEffect } from 'react'
import axe from '@axe-core/react'
function App() {
useEffect(() => {
axe(React, ReactDOM, 1000)
}, [])
return (
{/ Your app content */}
)
}
Manual Testing
Test with real assistive technologies:
1. Screen readers: NVDA (Windows), JAWS (Windows), VoiceOver (Mac)
2. Keyboard only: Navigate without mouse
3. Voice control: Dragon NaturallySpeaking, Voice Control
4. Zoom: Test at 200% zoom level
Browser DevTools
Use built-in accessibility features:
- Chrome DevTools: Accessibility panel
- Firefox: Accessibility inspector
- Safari: Web Inspector accessibility features
Common Patterns
Modal Dialogs
Make modals accessible:
tsx
function Modal({ isOpen, onClose, children }) {
useEffect(() => {
if (isOpen) {
// Trap focus
const focusableElements = modalRef.current?.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
)
if (focusableElements?.length) {
focusableElements[0].focus()
}
}
}, [isOpen])
if (!isOpen) return null
return (
className="modal-overlay"
onClick={onClose}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
className="modal-content"
onClick={e => e.stopPropagation()}
ref={modalRef}
>
Modal Title
{children}
)
}
Data Tables
Make tables accessible:
html
Monthly Sales Report
Month
Sales
Growth
January
$10,000
+5%
February
$12,000
+20%
Conclusion
Web accessibility is not a one-time task but an ongoing commitment to inclusive design. By following these guidelines and continuously testing with real users, you can create web experiences that work for everyone.
Remember:
- Start with semantic HTML
- Test with real assistive technologies
- Include users with disabilities in your design process
- Make accessibility part of your development workflow
- Keep learning and improving
The web should be accessible to everyone, and as developers, we have the power to make that happen.
html
Provide shortcuts for keyboard users:
html
Skip to main content
css
.skip-link {
position: absolute;
top: -40px;
left: 6px;
background: #000;
color: #fff;
padding: 8px;
text-decoration: none;
z-index: 1000;
}
.skip-link:focus {
top: 6px;
}
Color and Contrast
Color Contrast Ratios
Ensure sufficient contrast between text and background:
- Normal text: 4.5:1 contrast ratio
- Large text: 3:1 contrast ratio
- UI components: 3:1 contrast ratio
css
/ ✅ Good contrast /
.text-dark {
color: #000000; / Black text /
background: #ffffff; / White background /
/ Contrast ratio: 21:1 /
}
.text-medium {
color: #333333; / Dark gray /
background: #ffffff; / White background /
/ Contrast ratio: 12.6:1 /
}
/ ❌ Poor contrast /
.text-poor {
color: #999999; / Light gray /
background: #ffffff; / White background /
/ Contrast ratio: 2.8:1 - Too low! /
}
Don't Rely on Color Alone
Provide additional visual cues:
html
Forms and Inputs
Proper Form Labels
Associate labels with form controls:
html
Username
Form Validation
Provide clear error messages:
html
Required Fields
Clearly indicate required fields:
html
Images and Media
Alt Text
Provide meaningful alternative text:
html



Complex Images
Use long descriptions for complex content:
html
src="infographic.png"
alt="Infographic showing company growth"
longdesc="#infographic-description"
>
Company Growth Infographic
This infographic shows our company's growth over the past five years...
Video and Audio
Provide captions and transcripts:
html
Testing and Validation
Automated Testing Tools
Use tools to catch accessibility issues:
bash
Install axe-core for automated testing
npm install --save-dev @axe-core/react
Install Lighthouse CLI
npm install -g lighthouse
tsx
// React component with axe testing
import { useEffect } from 'react'
import axe from '@axe-core/react'
function App() {
useEffect(() => {
axe(React, ReactDOM, 1000)
}, [])
return (
{/ Your app content */}
)
}
Manual Testing
Test with real assistive technologies:
1. Screen readers: NVDA (Windows), JAWS (Windows), VoiceOver (Mac)
2. Keyboard only: Navigate without mouse
3. Voice control: Dragon NaturallySpeaking, Voice Control
4. Zoom: Test at 200% zoom level
Browser DevTools
Use built-in accessibility features:
- Chrome DevTools: Accessibility panel
- Firefox: Accessibility inspector
- Safari: Web Inspector accessibility features
Common Patterns
Modal Dialogs
Make modals accessible:
tsx
function Modal({ isOpen, onClose, children }) {
useEffect(() => {
if (isOpen) {
// Trap focus
const focusableElements = modalRef.current?.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
)
if (focusableElements?.length) {
focusableElements[0].focus()
}
}
}, [isOpen])
if (!isOpen) return null
return (
className="modal-overlay"
onClick={onClose}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
className="modal-content"
onClick={e => e.stopPropagation()}
ref={modalRef}
>
Modal Title
{children}
)
}
Data Tables
Make tables accessible:
html
Monthly Sales Report
Month
Sales
Growth
January
$10,000
+5%
February
$12,000
+20%
Conclusion
Web accessibility is not a one-time task but an ongoing commitment to inclusive design. By following these guidelines and continuously testing with real users, you can create web experiences that work for everyone.
Remember:
- Start with semantic HTML
- Test with real assistive technologies
- Include users with disabilities in your design process
- Make accessibility part of your development workflow
- Keep learning and improving
The web should be accessible to everyone, and as developers, we have the power to make that happen.
Ensure sufficient contrast between text and background:
- Normal text: 4.5:1 contrast ratio
- Large text: 3:1 contrast ratio
- UI components: 3:1 contrast ratio
css
/ ✅ Good contrast /
.text-dark {
color: #000000; / Black text /
background: #ffffff; / White background /
/ Contrast ratio: 21:1 /
}
.text-medium {
color: #333333; / Dark gray /
background: #ffffff; / White background /
/ Contrast ratio: 12.6:1 /
}
/ ❌ Poor contrast /
.text-poor {
color: #999999; / Light gray /
background: #ffffff; / White background /
/ Contrast ratio: 2.8:1 - Too low! /
}
Don't Rely on Color Alone
Provide additional visual cues:
html
Forms and Inputs
Proper Form Labels
Associate labels with form controls:
html
Username
Form Validation
Provide clear error messages:
html
Required Fields
Clearly indicate required fields:
html
Images and Media
Alt Text
Provide meaningful alternative text:
html



Complex Images
Use long descriptions for complex content:
html
src="infographic.png"
alt="Infographic showing company growth"
longdesc="#infographic-description"
>
Company Growth Infographic
This infographic shows our company's growth over the past five years...
Video and Audio
Provide captions and transcripts:
html
Testing and Validation
Automated Testing Tools
Use tools to catch accessibility issues:
bash
Install axe-core for automated testing
npm install --save-dev @axe-core/react
Install Lighthouse CLI
npm install -g lighthouse
tsx
// React component with axe testing
import { useEffect } from 'react'
import axe from '@axe-core/react'
function App() {
useEffect(() => {
axe(React, ReactDOM, 1000)
}, [])
return (
{/ Your app content */}
)
}
Manual Testing
Test with real assistive technologies:
1. Screen readers: NVDA (Windows), JAWS (Windows), VoiceOver (Mac)
2. Keyboard only: Navigate without mouse
3. Voice control: Dragon NaturallySpeaking, Voice Control
4. Zoom: Test at 200% zoom level
Browser DevTools
Use built-in accessibility features:
- Chrome DevTools: Accessibility panel
- Firefox: Accessibility inspector
- Safari: Web Inspector accessibility features
Common Patterns
Modal Dialogs
Make modals accessible:
tsx
function Modal({ isOpen, onClose, children }) {
useEffect(() => {
if (isOpen) {
// Trap focus
const focusableElements = modalRef.current?.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
)
if (focusableElements?.length) {
focusableElements[0].focus()
}
}
}, [isOpen])
if (!isOpen) return null
return (
className="modal-overlay"
onClick={onClose}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
className="modal-content"
onClick={e => e.stopPropagation()}
ref={modalRef}
>
Modal Title
{children}
)
}
Data Tables
Make tables accessible:
html
Monthly Sales Report
Month
Sales
Growth
January
$10,000
+5%
February
$12,000
+20%
Conclusion
Web accessibility is not a one-time task but an ongoing commitment to inclusive design. By following these guidelines and continuously testing with real users, you can create web experiences that work for everyone.
Remember:
- Start with semantic HTML
- Test with real assistive technologies
- Include users with disabilities in your design process
- Make accessibility part of your development workflow
- Keep learning and improving
The web should be accessible to everyone, and as developers, we have the power to make that happen.
html
Proper Form Labels
Associate labels with form controls:
html
Username
Form Validation
Provide clear error messages:
html
Required Fields
Clearly indicate required fields:
html
Images and Media
Alt Text
Provide meaningful alternative text:
html



Complex Images
Use long descriptions for complex content:
html
src="infographic.png"
alt="Infographic showing company growth"
longdesc="#infographic-description"
>
Company Growth Infographic
This infographic shows our company's growth over the past five years...
Video and Audio
Provide captions and transcripts:
html
Testing and Validation
Automated Testing Tools
Use tools to catch accessibility issues:
bash
Install axe-core for automated testing
npm install --save-dev @axe-core/react
Install Lighthouse CLI
npm install -g lighthouse
tsx
// React component with axe testing
import { useEffect } from 'react'
import axe from '@axe-core/react'
function App() {
useEffect(() => {
axe(React, ReactDOM, 1000)
}, [])
return (
{/ Your app content */}
)
}
Manual Testing
Test with real assistive technologies:
1. Screen readers: NVDA (Windows), JAWS (Windows), VoiceOver (Mac)
2. Keyboard only: Navigate without mouse
3. Voice control: Dragon NaturallySpeaking, Voice Control
4. Zoom: Test at 200% zoom level
Browser DevTools
Use built-in accessibility features:
- Chrome DevTools: Accessibility panel
- Firefox: Accessibility inspector
- Safari: Web Inspector accessibility features
Common Patterns
Modal Dialogs
Make modals accessible:
tsx
function Modal({ isOpen, onClose, children }) {
useEffect(() => {
if (isOpen) {
// Trap focus
const focusableElements = modalRef.current?.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
)
if (focusableElements?.length) {
focusableElements[0].focus()
}
}
}, [isOpen])
if (!isOpen) return null
return (
className="modal-overlay"
onClick={onClose}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
className="modal-content"
onClick={e => e.stopPropagation()}
ref={modalRef}
>
Modal Title
{children}
)
}
Data Tables
Make tables accessible:
html
Monthly Sales Report
Month
Sales
Growth
January
$10,000
+5%
February
$12,000
+20%
Conclusion
Web accessibility is not a one-time task but an ongoing commitment to inclusive design. By following these guidelines and continuously testing with real users, you can create web experiences that work for everyone.
Remember:
- Start with semantic HTML
- Test with real assistive technologies
- Include users with disabilities in your design process
- Make accessibility part of your development workflow
- Keep learning and improving
The web should be accessible to everyone, and as developers, we have the power to make that happen.
html
Username
Provide clear error messages:
html
Required Fields
Clearly indicate required fields:
html
Images and Media
Alt Text
Provide meaningful alternative text:
html



Complex Images
Use long descriptions for complex content:
html
src="infographic.png"
alt="Infographic showing company growth"
longdesc="#infographic-description"
>
Company Growth Infographic
This infographic shows our company's growth over the past five years...
Video and Audio
Provide captions and transcripts:
html
Testing and Validation
Automated Testing Tools
Use tools to catch accessibility issues:
bash
Install axe-core for automated testing
npm install --save-dev @axe-core/react
Install Lighthouse CLI
npm install -g lighthouse
tsx
// React component with axe testing
import { useEffect } from 'react'
import axe from '@axe-core/react'
function App() {
useEffect(() => {
axe(React, ReactDOM, 1000)
}, [])
return (
{/ Your app content */}
)
}
Manual Testing
Test with real assistive technologies:
1. Screen readers: NVDA (Windows), JAWS (Windows), VoiceOver (Mac)
2. Keyboard only: Navigate without mouse
3. Voice control: Dragon NaturallySpeaking, Voice Control
4. Zoom: Test at 200% zoom level
Browser DevTools
Use built-in accessibility features:
- Chrome DevTools: Accessibility panel
- Firefox: Accessibility inspector
- Safari: Web Inspector accessibility features
Common Patterns
Modal Dialogs
Make modals accessible:
tsx
function Modal({ isOpen, onClose, children }) {
useEffect(() => {
if (isOpen) {
// Trap focus
const focusableElements = modalRef.current?.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
)
if (focusableElements?.length) {
focusableElements[0].focus()
}
}
}, [isOpen])
if (!isOpen) return null
return (
className="modal-overlay"
onClick={onClose}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
className="modal-content"
onClick={e => e.stopPropagation()}
ref={modalRef}
>
Modal Title
{children}
)
}
Data Tables
Make tables accessible:
html
Monthly Sales Report
Month
Sales
Growth
January
$10,000
+5%
February
$12,000
+20%
Conclusion
Web accessibility is not a one-time task but an ongoing commitment to inclusive design. By following these guidelines and continuously testing with real users, you can create web experiences that work for everyone.
Remember:
- Start with semantic HTML
- Test with real assistive technologies
- Include users with disabilities in your design process
- Make accessibility part of your development workflow
- Keep learning and improving
The web should be accessible to everyone, and as developers, we have the power to make that happen.
html
Alt Text
Provide meaningful alternative text:
html



Complex Images
Use long descriptions for complex content:
html
src="infographic.png"
alt="Infographic showing company growth"
longdesc="#infographic-description"
>
Company Growth Infographic
This infographic shows our company's growth over the past five years...
Video and Audio
Provide captions and transcripts:
html
Testing and Validation
Automated Testing Tools
Use tools to catch accessibility issues:
bash
Install axe-core for automated testing
npm install --save-dev @axe-core/react
Install Lighthouse CLI
npm install -g lighthouse
tsx
// React component with axe testing
import { useEffect } from 'react'
import axe from '@axe-core/react'
function App() {
useEffect(() => {
axe(React, ReactDOM, 1000)
}, [])
return (
{/ Your app content */}
)
}
Manual Testing
Test with real assistive technologies:
1. Screen readers: NVDA (Windows), JAWS (Windows), VoiceOver (Mac)
2. Keyboard only: Navigate without mouse
3. Voice control: Dragon NaturallySpeaking, Voice Control
4. Zoom: Test at 200% zoom level
Browser DevTools
Use built-in accessibility features:
- Chrome DevTools: Accessibility panel
- Firefox: Accessibility inspector
- Safari: Web Inspector accessibility features
Common Patterns
Modal Dialogs
Make modals accessible:
tsx
function Modal({ isOpen, onClose, children }) {
useEffect(() => {
if (isOpen) {
// Trap focus
const focusableElements = modalRef.current?.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
)
if (focusableElements?.length) {
focusableElements[0].focus()
}
}
}, [isOpen])
if (!isOpen) return null
return (
className="modal-overlay"
onClick={onClose}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
className="modal-content"
onClick={e => e.stopPropagation()}
ref={modalRef}
>
Modal Title
{children}
)
}
Data Tables
Make tables accessible:
html
Monthly Sales Report
Month
Sales
Growth
January
$10,000
+5%
February
$12,000
+20%
Conclusion
Web accessibility is not a one-time task but an ongoing commitment to inclusive design. By following these guidelines and continuously testing with real users, you can create web experiences that work for everyone.
Remember:
- Start with semantic HTML
- Test with real assistive technologies
- Include users with disabilities in your design process
- Make accessibility part of your development workflow
- Keep learning and improving
The web should be accessible to everyone, and as developers, we have the power to make that happen.
html



Use long descriptions for complex content:
html
src="infographic.png"
alt="Infographic showing company growth"
longdesc="#infographic-description"
>
Company Growth Infographic
This infographic shows our company's growth over the past five years...
Video and Audio
Provide captions and transcripts:
html
Testing and Validation
Automated Testing Tools
Use tools to catch accessibility issues:
bash
Install axe-core for automated testing
npm install --save-dev @axe-core/react
Install Lighthouse CLI
npm install -g lighthouse
tsx
// React component with axe testing
import { useEffect } from 'react'
import axe from '@axe-core/react'
function App() {
useEffect(() => {
axe(React, ReactDOM, 1000)
}, [])
return (
{/ Your app content */}
)
}
Manual Testing
Test with real assistive technologies:
1. Screen readers: NVDA (Windows), JAWS (Windows), VoiceOver (Mac)
2. Keyboard only: Navigate without mouse
3. Voice control: Dragon NaturallySpeaking, Voice Control
4. Zoom: Test at 200% zoom level
Browser DevTools
Use built-in accessibility features:
- Chrome DevTools: Accessibility panel
- Firefox: Accessibility inspector
- Safari: Web Inspector accessibility features
Common Patterns
Modal Dialogs
Make modals accessible:
tsx
function Modal({ isOpen, onClose, children }) {
useEffect(() => {
if (isOpen) {
// Trap focus
const focusableElements = modalRef.current?.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
)
if (focusableElements?.length) {
focusableElements[0].focus()
}
}
}, [isOpen])
if (!isOpen) return null
return (
className="modal-overlay"
onClick={onClose}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
className="modal-content"
onClick={e => e.stopPropagation()}
ref={modalRef}
>
Modal Title
{children}
)
}
Data Tables
Make tables accessible:
html
Monthly Sales Report
Month
Sales
Growth
January
$10,000
+5%
February
$12,000
+20%
Conclusion
Web accessibility is not a one-time task but an ongoing commitment to inclusive design. By following these guidelines and continuously testing with real users, you can create web experiences that work for everyone.
Remember:
- Start with semantic HTML
- Test with real assistive technologies
- Include users with disabilities in your design process
- Make accessibility part of your development workflow
- Keep learning and improving
The web should be accessible to everyone, and as developers, we have the power to make that happen.
html
Automated Testing Tools
Use tools to catch accessibility issues:
bash
Install axe-core for automated testing
npm install --save-dev @axe-core/react
Install Lighthouse CLI
npm install -g lighthouse
tsx
// React component with axe testing
import { useEffect } from 'react'
import axe from '@axe-core/react'
function App() {
useEffect(() => {
axe(React, ReactDOM, 1000)
}, [])
return (
{/ Your app content */}
)
}
Manual Testing
Test with real assistive technologies:
1. Screen readers: NVDA (Windows), JAWS (Windows), VoiceOver (Mac)
2. Keyboard only: Navigate without mouse
3. Voice control: Dragon NaturallySpeaking, Voice Control
4. Zoom: Test at 200% zoom level
Browser DevTools
Use built-in accessibility features:
- Chrome DevTools: Accessibility panel
- Firefox: Accessibility inspector
- Safari: Web Inspector accessibility features
Common Patterns
Modal Dialogs
Make modals accessible:
tsx
function Modal({ isOpen, onClose, children }) {
useEffect(() => {
if (isOpen) {
// Trap focus
const focusableElements = modalRef.current?.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
)
if (focusableElements?.length) {
focusableElements[0].focus()
}
}
}, [isOpen])
if (!isOpen) return null
return (
className="modal-overlay"
onClick={onClose}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
className="modal-content"
onClick={e => e.stopPropagation()}
ref={modalRef}
>
Modal Title
{children}
)
}
Data Tables
Make tables accessible:
html
Monthly Sales Report
Month
Sales
Growth
January
$10,000
+5%
February
$12,000
+20%
Conclusion
Web accessibility is not a one-time task but an ongoing commitment to inclusive design. By following these guidelines and continuously testing with real users, you can create web experiences that work for everyone.
Remember:
- Start with semantic HTML
- Test with real assistive technologies
- Include users with disabilities in your design process
- Make accessibility part of your development workflow
- Keep learning and improving
The web should be accessible to everyone, and as developers, we have the power to make that happen.
bash
Install axe-core for automated testing
npm install --save-dev @axe-core/react
Install Lighthouse CLI
npm install -g lighthouse
tsx
// React component with axe testing
import { useEffect } from 'react'
import axe from '@axe-core/react'
function App() {
useEffect(() => {
axe(React, ReactDOM, 1000)
}, [])
return (
{/ Your app content */}
)
}
Test with real assistive technologies:
1. Screen readers: NVDA (Windows), JAWS (Windows), VoiceOver (Mac)
2. Keyboard only: Navigate without mouse
3. Voice control: Dragon NaturallySpeaking, Voice Control
4. Zoom: Test at 200% zoom level
Browser DevTools
Use built-in accessibility features:
- Chrome DevTools: Accessibility panel
- Firefox: Accessibility inspector
- Safari: Web Inspector accessibility features
Common Patterns
Modal Dialogs
Make modals accessible:
tsx
function Modal({ isOpen, onClose, children }) {
useEffect(() => {
if (isOpen) {
// Trap focus
const focusableElements = modalRef.current?.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
)
if (focusableElements?.length) {
focusableElements[0].focus()
}
}
}, [isOpen])
if (!isOpen) return null
return (
className="modal-overlay"
onClick={onClose}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
className="modal-content"
onClick={e => e.stopPropagation()}
ref={modalRef}
>
Modal Title
{children}
)
}
Data Tables
Make tables accessible:
html
Monthly Sales Report
Month
Sales
Growth
January
$10,000
+5%
February
$12,000
+20%
Conclusion
Web accessibility is not a one-time task but an ongoing commitment to inclusive design. By following these guidelines and continuously testing with real users, you can create web experiences that work for everyone.
Remember:
- Start with semantic HTML
- Test with real assistive technologies
- Include users with disabilities in your design process
- Make accessibility part of your development workflow
- Keep learning and improving
The web should be accessible to everyone, and as developers, we have the power to make that happen.
Modal Dialogs
Make modals accessible:
tsx
function Modal({ isOpen, onClose, children }) {
useEffect(() => {
if (isOpen) {
// Trap focus
const focusableElements = modalRef.current?.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
)
if (focusableElements?.length) {
focusableElements[0].focus()
}
}
}, [isOpen])
if (!isOpen) return null
return (
className="modal-overlay"
onClick={onClose}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
className="modal-content"
onClick={e => e.stopPropagation()}
ref={modalRef}
>
Modal Title
{children}
)
}
Data Tables
Make tables accessible:
html
Monthly Sales Report
Month
Sales
Growth
January
$10,000
+5%
February
$12,000
+20%
Conclusion
Web accessibility is not a one-time task but an ongoing commitment to inclusive design. By following these guidelines and continuously testing with real users, you can create web experiences that work for everyone.
Remember:
- Start with semantic HTML
- Test with real assistive technologies
- Include users with disabilities in your design process
- Make accessibility part of your development workflow
- Keep learning and improving
The web should be accessible to everyone, and as developers, we have the power to make that happen.
tsx
function Modal({ isOpen, onClose, children }) {
useEffect(() => {
if (isOpen) {
// Trap focus
const focusableElements = modalRef.current?.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
)
if (focusableElements?.length) {
focusableElements[0].focus()
}
}
}, [isOpen])
if (!isOpen) return null
return (
className="modal-overlay"
onClick={onClose}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
className="modal-content"
onClick={e => e.stopPropagation()}
ref={modalRef}
>
Modal Title
{children}
)
}
Make tables accessible:
html
Monthly Sales Report
Month
Sales
Growth
January
$10,000
+5%
February
$12,000
+20%