Making your website accessible isn't just good practice—it's essential. Over one billion people worldwide have some form of disability, and many rely on assistive technologies like screen readers to navigate the web. ARIA (Accessible Rich Internet Applications) is a set of attributes that make complex web interfaces understandable and usable for everyone, especially those using screen readers.
This guide covers what ARIA is, when and how to use it, common accessibility issues, and how to test your website for accessibility compliance. Whether you're building a new site or improving an existing one, understanding ARIA is crucial for creating inclusive web experiences.
TL;DR
- ARIA - Accessible Rich Internet Applications attributes that make web content accessible to screen readers
- Use semantic HTML first - ARIA supplements HTML but doesn't replace proper semantic elements
- Common ARIA attributes - aria-label, aria-labelledby, aria-describedby, aria-expanded, aria-hidden, role
- Testing is critical - Use tools like WAVE, axe DevTools, and screen readers to test accessibility
- WCAG compliance - Follow WCAG 2.1 Level AA standards for legal compliance and best practices
What is ARIA?
ARIA (Accessible Rich Internet Applications) is a W3C specification that defines ways to make web content and web applications more accessible to people with disabilities. It's particularly important for dynamic content and advanced user interface controls developed with HTML, JavaScript, and related technologies.
ARIA works by providing additional information about elements to assistive technologies. When a screen reader encounters an element with ARIA attributes, it can communicate that information to the user, making the interface understandable even when the visual presentation doesn't convey all the necessary information.
When to Use ARIA
The first rule of ARIA is: don't use ARIA if you can use semantic HTML instead. Semantic HTML elements like <button>, <nav>, <main>, and <article> already provide accessibility information to assistive technologies.
Use ARIA when:
- Custom interactive elements - When creating custom buttons, menus, or widgets that don't use standard HTML elements
- Dynamic content - When content changes dynamically and you need to notify screen readers
- Complex widgets - For tabs, accordions, modals, and other complex UI patterns
- Filling gaps - When HTML semantics don't fully describe the element's purpose or state
Don't use ARIA when:
- Standard HTML elements work - Use
<button>instead of<div role="button"> - It conflicts with native semantics - Don't add ARIA to elements that already have the correct semantic meaning
- It's redundant - Don't repeat information that's already conveyed by the element's content
Essential ARIA Attributes
aria-label
Provides an accessible name for an element when the visible text doesn't fully describe its purpose. This is especially useful for icon buttons and links.
<button aria-label="Close dialog">
<svg><path d="..."/></svg>
</button>
<a href="#" aria-label="Shopping cart with 3 items">
<svg><path d="..."/></svg>
</a>
aria-labelledby
References another element that provides the accessible name. Use this when you want to associate a label with an element, especially when the label is visually positioned elsewhere.
<div id="search-label">Search Products</div>
<input type="search" aria-labelledby="search-label">
<h2 id="modal-title">Delete Account</h2>
<div role="dialog" aria-labelledby="modal-title">
...
</div>
aria-describedby
References elements that provide additional descriptive information. Useful for form field help text, error messages, and tooltips.
<input type="email" aria-describedby="email-help email-error">
<div id="email-help">We'll never share your email</div>
<div id="email-error" role="alert">Please enter a valid email address</div>
aria-expanded
Indicates whether a collapsible element is expanded or collapsed. Essential for accordions, dropdown menus, and other expandable content.
<button aria-expanded="false" aria-controls="menu">
Menu
</button>
<ul id="menu" aria-hidden="true">
...
</ul>
<!-- JavaScript updates aria-expanded when toggled -->
<script>
button.addEventListener('click', () => {
const isExpanded = button.getAttribute('aria-expanded') === 'true';
button.setAttribute('aria-expanded', !isExpanded);
menu.setAttribute('aria-hidden', isExpanded);
});
</script>
aria-hidden
Hides decorative elements from screen readers. Use this for purely visual elements like icons, decorative images, and separators that don't add meaning.
<button>
<span>Add to Cart</span>
<svg aria-hidden="true">
<path d="..."/>
</svg>
</button>
<div class="separator" aria-hidden="true">
<hr>
</div>
role
Defines what an element is or does. Use roles when creating custom widgets that don't have semantic HTML equivalents.
<div role="alert">Your session has expired</div>
<div role="dialog" aria-labelledby="dialog-title">
<h2 id="dialog-title">Confirm Action</h2>
...
</div>
<ul role="tablist">
<li role="tab" aria-selected="true">Overview</li>
<li role="tab" aria-selected="false">Details</li>
</ul>
aria-controls
Identifies elements controlled by the current element. Useful for connecting buttons to the content they control.
<button aria-expanded="false" aria-controls="mobile-menu">
Toggle Menu
</button>
<nav id="mobile-menu" aria-hidden="true">
...
</nav>
Common Accessibility Issues and Solutions
Missing Skip Links
Skip links allow keyboard users to jump directly to the main content, bypassing navigation. This is essential for users who navigate entirely with keyboards.
<body>
<a href="#main-content" class="skip-link">Skip to main content</a>
<header>...</header>
<main id="main-content">...</main>
</body>
CSS for skip link (hidden until focused):
.skip-link {
position: absolute;
top: -40px;
left: 0;
background: var(--primary-color);
color: white;
padding: 12px 24px;
text-decoration: none;
z-index: 10000;
}
.skip-link:focus {
top: 0;
}
Invisible Buttons
Buttons without visible labels are inaccessible. Always provide text labels, either visible or via aria-label.
<!-- Bad: No label -->
<button class="icon-btn">
<svg><path d="..."/></svg>
</button>
<!-- Good: aria-label -->
<button class="icon-btn" aria-label="Close dialog">
<svg aria-hidden="true"><path d="..."/></svg>
</button>
Skipped Heading Levels
Headings should follow a logical hierarchy (h1, h2, h3, etc.) without skipping levels. Screen reader users often navigate by headings.
<!-- Bad: Skipped from h1 to h3 -->
<h1>Page Title</h1>
<h3>Section Title</h3>
<!-- Good: Proper hierarchy -->
<h1>Page Title</h1>
<h2>Section Title</h2>
<h3>Subsection Title</h3>
Low Contrast Text
Text must have sufficient contrast against its background. WCAG requires at least 4.5:1 for normal text and 3:1 for large text.
<!-- Bad: Low contrast (gray on light gray) -->
<p style="color: #999999; background: #f5f5f5;">Text</p>
<!-- Good: High contrast (dark on light) -->
<p style="color: #000000; background: #ffffff;">Text</p>
Use tools like WebAIM's Contrast Checker to verify contrast ratios meet WCAG standards.
Redundant Links
When an image and text both link to the same destination, it creates redundant navigation for screen reader users. Wrap both in a single link or remove one link.
<!-- Bad: Redundant links -->
<a href="product.html">
<img src="product.jpg" alt="Product">
</a>
<a href="product.html">Product Name</a>
<!-- Good: Single link -->
<a href="product.html">
<img src="product.jpg" alt="">
Product Name
</a>
Missing Form Labels
Every form input needs an associated label. Use explicit labels or aria-labelledby for proper association.
<!-- Bad: No label -->
<input type="email" placeholder="Email address">
<!-- Good: Explicit label -->
<label for="email">Email address</label>
<input type="email" id="email" name="email">
<!-- Good: aria-label -->
<input type="email" aria-label="Email address">
Navigation and Menus
Navigation menus need proper ARIA attributes to communicate their state and structure to screen readers.
<nav aria-label="Main navigation">
<button
class="mobile-menu-toggle"
aria-label="Toggle mobile menu"
aria-expanded="false"
aria-controls="mobile-menu">
Menu
</button>
<ul id="mobile-menu" aria-label="Mobile menu" aria-hidden="true">
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
JavaScript to manage aria-expanded and aria-hidden:
const menuButton = document.querySelector('.mobile-menu-toggle');
const menu = document.getElementById('mobile-menu');
menuButton.addEventListener('click', () => {
const isExpanded = menuButton.getAttribute('aria-expanded') === 'true';
menuButton.setAttribute('aria-expanded', !isExpanded);
menu.setAttribute('aria-hidden', isExpanded);
});
Modals and Dialogs
Modal dialogs require proper ARIA attributes and keyboard management. Use the native <dialog> element when possible, or implement proper ARIA patterns.
<div
role="dialog"
aria-modal="true"
aria-labelledby="dialog-title"
aria-describedby="dialog-description">
<h2 id="dialog-title">Confirm Delete</h2>
<p id="dialog-description">Are you sure you want to delete this item?</p>
<button aria-label="Close dialog">Cancel</button>
<button>Delete</button>
</div>
Testing for Accessibility
Testing is essential to ensure your website is accessible. Use a combination of automated tools and manual testing.
Automated Testing Tools
- WAVE - Web Accessibility Evaluation Tool browser extension
- axe DevTools - Browser extension and testing library
- Lighthouse - Built into Chrome DevTools, includes accessibility audit
- Pa11y - Command-line accessibility testing
Manual Testing
- Keyboard navigation - Use only keyboard (Tab, Enter, Space, Arrow keys) to navigate your site
- Screen readers - Test with NVDA (Windows, free), JAWS (Windows, paid), or VoiceOver (macOS/iOS, free)
- Zoom testing - Ensure your site works at 200% zoom
- Color contrast - Use WebAIM Contrast Checker to verify contrast ratios
WCAG Compliance
The Web Content Accessibility Guidelines (WCAG) 2.1 define three levels of compliance:
- Level A - Minimum requirements, basic accessibility
- Level AA - Recommended standard, addresses major barriers (most legal requirements target this level)
- Level AAA - Highest level, enhanced accessibility
Most organizations should aim for WCAG 2.1 Level AA compliance, which is the standard referenced in many accessibility laws and regulations.
Best Practices
- Start with semantic HTML - Use proper HTML elements before adding ARIA
- Test regularly - Include accessibility testing in your development workflow
- Test with real users - Automated tools catch many issues, but user testing reveals real-world problems
- Keep it simple - Don't overuse ARIA; use it only when necessary
- Maintain dynamic states - Keep aria-expanded, aria-hidden, and other state attributes updated with JavaScript
- Provide text alternatives - All images need alt text (or aria-hidden="true" if decorative)
- Ensure keyboard access - All interactive elements must be keyboard accessible
- Test with screen readers - There's no substitute for testing with actual assistive technology
Common ARIA Patterns
Toggle Button
<button
aria-expanded="false"
aria-controls="content"
aria-label="Toggle section">
Show More
</button>
<div id="content" aria-hidden="true">
Hidden content
</div>
Breadcrumb Navigation
<nav aria-label="Breadcrumb">
<ol>
<li><a href="/">Home</a></li>
<li><a href="/products">Products</a></li>
<li aria-current="page">Current Page</li>
</ol>
</nav>
Alert Messages
<div role="alert" aria-live="assertive">
Error: Please check your input
</div>
<div role="status" aria-live="polite">
Form submitted successfully
</div>
Summary
ARIA is a powerful tool for making websites accessible, but it should supplement—not replace—semantic HTML. Start with proper HTML elements, add ARIA only when necessary, and always test with real assistive technologies.
Making your website accessible isn't just the right thing to do—it's also good for business. Accessible websites reach more users, rank better in search engines, and often provide better user experiences for everyone, not just users with disabilities.
Remember: accessibility is an ongoing process, not a one-time checklist. Regular testing, user feedback, and staying updated with accessibility best practices will help you maintain an accessible website as your site evolves.
Need Help Making Your Website Accessible?
We provide comprehensive website accessibility audits, ARIA implementation, and WCAG compliance services. Our team can help identify accessibility issues, implement proper ARIA attributes, and ensure your site meets WCAG 2.1 Level AA standards. Contact us for professional accessibility consulting and implementation.