Modern QA2026Common ARIA Mistakes — tiles
Log inJoin
32 / 74 · 10 Visual & Accessibility Testing · ARIA Labels and Color Contrast← prev⊞ allnext →☰ Read as one page

6.4Common ARIA Mistakes

Mistake Why It Is Wrong Correct Approach
<div role="button"> Missing keyboard handling Use <button>
aria-label on <div> without role aria-label has no effect on generic elements Add a role or use a semantic element
aria-hidden="true" on focusable element Removes from accessibility tree but still focusable Also add tabindex="-1"
Duplicate aria-labelledby targets Confusing screen reader output Each label target should be unique
role="presentation" on interactive element Removes semantics from clickable element Never suppress semantics on interactive elements
Using ARIA to fix a broken HTML structure ARIA compensates but does not truly fix issues Fix the HTML structure first

Testing for these mistakes can be automated:

test('no ARIA anti-patterns', async ({ page }) => {
    await page.goto('/');

    const antiPatterns = await page.evaluate(() => {
        const issues: string[] = [];

        // Check for divs with role="button" (should be <button>)
        document.querySelectorAll('[role="button"]:not(button)').forEach(el => {
            issues.push(`Non-button element with role="button": ${el.outerHTML.substring(0, 100)}`);
        });

        // Check for aria-hidden on focusable elements
        document.querySelectorAll('[aria-hidden="true"]').forEach(el => {
            const tabindex = el.getAttribute('tabindex');
            if (tabindex !== '-1' && (el as HTMLElement).tabIndex >= 0) {
                issues.push(`Focusable element with aria-hidden: ${el.outerHTML.substring(0, 100)}`);
            }
        });

        return issues;
    });

    expect(antiPatterns).toEqual([]);
});

ARIA and color contrast testing form the backbone of automated accessibility checks. They are fast to run, catch real issues, and require minimal setup. Every project should have these tests from day one.