Accessibility & Agent Interaction
12 checks · Weight: 7% of overall score
Checks in this category
Skip navigation link
Headless browser agents (Claude computer use, GPTBot with browser) parse the accessibility tree to navigate pages efficiently. A skip navigation link lets these agents jump directly to primary content without processing every nav element, reducing latency and improving content extraction accuracy.
Why This Matters
Headless browser agents (Claude computer use, GPTBot) parse the accessibility tree to navigate pages. A skip navigation link lets agents jump directly to primary content without processing every nav element, reducing latency and improving content extraction accuracy.
How to Fix
Add a "Skip to main content" link as the first focusable element in <body>, pointing to an anchor on your <main> element.
Example
<a href="#main-content" class="skip-link">Skip to main content</a>
<!-- ... navigation ... -->
<main id="main-content">...</main>ARIA landmarks complete
Claude computer use and browser agents rely on ARIA landmarks to identify page regions (navigation, main content, footer). Missing landmarks force agents to guess page structure from raw HTML, leading to misclicked elements and incorrect content extraction.
Why This Matters
Claude computer use and browser agents rely on ARIA landmarks to identify page regions (navigation, main content, footer). Missing landmarks force agents to guess page structure from raw HTML, leading to misclicked elements and incorrect content extraction.
How to Fix
Ensure your page has all four required landmarks: <header> (banner), <main>, <nav> (navigation), and <footer> (contentinfo). Use semantic HTML elements or ARIA roles.
Example
<header role="banner">...</header>
<nav role="navigation">...</nav>
<main role="main">...</main>
<footer role="contentinfo">...</footer><nav> has aria-label
AI browser agents use aria-label on <nav> elements to understand navigation purpose before interacting with it. Unlabeled navs force agents to inspect child links to guess whether it is main navigation, breadcrumbs, or a footer menu, slowing down agentic workflows.
Why This Matters
AI browser agents use aria-label on <nav> elements to understand navigation purpose before interacting with it. Unlabeled navs force agents to inspect child links to guess the navigation type, slowing down agentic workflows.
How to Fix
Add an aria-label attribute to every <nav> element describing its purpose (e.g., "Main navigation", "Breadcrumb", "Footer navigation").
Example
<nav aria-label="Main navigation">...</nav>Multiple nav distinguished
AI browser agents traverse the accessibility tree and use aria-labels to select the correct navigation region. Without unique labels on each <nav>, agents cannot distinguish primary navigation from footer or breadcrumb navigation, causing navigation failures in agentic workflows.
Why This Matters
AI browser agents traverse the accessibility tree and use aria-labels to select the correct navigation region. Without unique labels on each <nav>, agents cannot distinguish primary navigation from footer or breadcrumb navigation, causing navigation failures.
How to Fix
Give each <nav> element a unique aria-label that describes its purpose. Ensure no two <nav> elements share the same label.
Example
<nav aria-label="Primary navigation">...</nav>
<nav aria-label="Footer navigation">...</nav>
<nav aria-label="Breadcrumb">...</nav>Form inputs have associated labels
AI agents filling forms identify fields by their accessible name (label, aria-label, or aria-labelledby). Unlabeled inputs are invisible to form-filling agents, meaning automated workflows like "sign me up for the newsletter" or "submit a contact request" will fail on your site.
Why This Matters
AI agents filling forms identify fields by their accessible name (label, aria-label, or aria-labelledby). Unlabeled inputs are invisible to form-filling agents, meaning automated workflows like "sign me up" or "submit a contact request" will fail on your site.
How to Fix
Associate every form input with a <label for="id"> element, or add aria-label or aria-labelledby attributes. Hidden and submit inputs are exempt.
Example
<label for="email">Email</label>
<input id="email" type="email" name="email">Form error messages linked
AI agents filling forms use aria-describedby to detect and understand validation errors programmatically. Without linked error messages, agents cannot self-correct form submissions, causing them to repeatedly submit invalid data or abandon the form entirely.
Why This Matters
AI agents filling forms use aria-describedby to detect and understand validation errors programmatically. Without linked error messages, agents cannot self-correct form submissions, causing them to repeatedly submit invalid data or abandon the form entirely.
How to Fix
Add aria-describedby attributes to form inputs that link to error message elements. Use role="alert" on error message containers for dynamic error display.
Example
<input id="email" aria-describedby="email-error">
<span id="email-error" role="alert">Please enter a valid email.</span>Buttons and links have accessible names
AI browser agents identify clickable elements by their accessible name in the accessibility tree. Buttons and links without text, aria-label, or aria-labelledby are completely invisible to agents, meaning they cannot navigate your site or trigger actions on behalf of users.
Why This Matters
AI browser agents identify clickable elements by their accessible name in the accessibility tree. Buttons and links without text, aria-label, or aria-labelledby are completely invisible to agents, meaning they cannot navigate your site or trigger actions.
How to Fix
Add text content, aria-label, or aria-labelledby to every <button> and <a> element. For icon-only elements, use aria-label to describe the action.
Example
<a href="/page" aria-label="Go to pricing page">...</a>
<button aria-label="Close menu">X</button>Icon-only elements have labels
AI agents cannot interpret SVG or icon font visuals and rely entirely on aria-label to understand icon-only buttons. Without labels, these interactive elements are unnamed in the accessibility tree, making them impossible for agents to identify or click during automated workflows.
Why This Matters
AI agents cannot interpret SVG or icon font visuals and rely entirely on aria-label to understand icon-only buttons. Without labels, these interactive elements are unnamed in the accessibility tree, making them impossible for agents to identify or click.
How to Fix
Add aria-label attributes to all icon-only buttons and links describing the action they perform. Alternatively, add visually-hidden text inside the element.
Example
<button aria-label="Search"><svg>...</svg></button>
<a href="/cart" aria-label="Shopping cart"><i class="icon-cart"></i></a>Modal dialogs use role="dialog"
AI browser agents detect modals via role="dialog" in the accessibility tree and need aria-label to understand the dialog's purpose. Unlabeled dialogs trap agents in unknown UI states, preventing them from completing tasks that involve confirmations, forms, or cookie consent.
Why This Matters
AI browser agents detect modals via role="dialog" in the accessibility tree and need aria-label to understand the dialog's purpose. Unlabeled dialogs trap agents in unknown UI states, preventing them from completing tasks involving confirmations, forms, or cookie consent.
How to Fix
Add role="dialog" and aria-labelledby (pointing to the dialog title) or aria-label to all modal/dialog elements. Use the native <dialog> element where possible.
Example
<div role="dialog" aria-labelledby="dialog-title">
<h2 id="dialog-title">Confirm Action</h2>
<p>Are you sure you want to proceed?</p>
<button>Confirm</button>
</div>Focus styles declared in CSS
AI browser agents navigating via keyboard need visible focus indicators to track the active element. Without :focus-visible styles, agents using screenshots (like Claude computer use) cannot determine which element is focused, breaking keyboard-driven agentic workflows.
Why This Matters
AI browser agents navigating via keyboard need visible focus indicators to track the active element. Without :focus-visible styles, agents using screenshots cannot determine which element is focused, breaking keyboard-driven agentic workflows.
How to Fix
Add :focus-visible CSS rules for interactive elements with a visible outline. Use outline with an offset for clear visibility against all backgrounds.
Example
:focus-visible {
outline: 2px solid #005fcc;
outline-offset: 2px;
}Color contrast declarations
AI agents that process visual screenshots (like Claude computer use) depend on sufficient contrast to read text via OCR. Low-contrast text also triggers WCAG compliance failures that AI trust-scoring systems use to downrank content quality. Adjust colors to achieve at least 4.5:1 contrast.
Why This Matters
AI agents that process visual screenshots (like Claude computer use) depend on sufficient contrast to read text via OCR. Low-contrast text also triggers WCAG compliance failures that AI trust-scoring systems use to downrank content quality.
How to Fix
Adjust foreground and background colors to achieve at least a 4.5:1 contrast ratio for normal text (3:1 for large text). Declare both color and background-color in the same CSS rule for verifiability.
Example
.text-block {
color: #1a1a1a; /* dark text */
background-color: #ffffff; /* light background */
/* Contrast ratio: 16.75:1 - passes WCAG AAA */
}prefers-reduced-motion respected
AI browser agents that use visual screenshots are confused by CSS animations that change page layout between captures. Respecting prefers-reduced-motion ensures agents see a stable visual state, improving the reliability of screenshot-based page understanding and interaction.
Why This Matters
AI browser agents that use visual screenshots are confused by CSS animations that change page layout between captures. Respecting prefers-reduced-motion ensures agents see a stable visual state, improving the reliability of screenshot-based page understanding.
How to Fix
Add a @media (prefers-reduced-motion: reduce) query to your CSS that disables or minimizes all animations and transitions.
Example
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}