Skip to main content
Accessibility issues affect users who rely on assistive technologies — screen readers, keyboard navigation, voice control, and screen magnifiers. In many jurisdictions, web accessibility compliance is legally required.

missing-form-labels

Medium WCAG 1.3.1, 2.4.6

What it is

Form input elements have no associated label, making their purpose unclear to screen readers and assistive technologies.

Why it matters

Screen reader users navigate forms by cycling through labeled inputs. An unlabeled field is announced as “edit text” or “text field” with no indication of what it’s for. This makes the form effectively unusable without sight.

How QAOS detects it

The agent scans the DOM for <input>, <textarea>, and <select> elements that lack an associated <label> (via for/id pairing), aria-label, or aria-labelledby attribute.

Examples

<!-- Missing label -->
<input type="email" name="email" placeholder="Enter email">

<!-- Correct: explicit label -->
<label for="email">Email address</label>
<input type="email" id="email" name="email">

<!-- Correct: aria-label -->
<input type="search" aria-label="Search products">

How to fix

Associate every form field with a visible label using <label for="...">, or provide an accessible name via aria-label or aria-labelledby. Placeholder text is not a substitute for a label.

button-no-text

Medium WCAG 4.1.2

What it is

Buttons have no visible text, making their purpose ambiguous to all users — especially those who cannot see icons or who use screen readers.

How QAOS detects it

The agent captures a screenshot and identifies buttons that contain no visible text content — including icon-only buttons where the icon has no accessible label.

Examples

<!-- Empty button — no indication of purpose -->
<button type="submit"></button>

<!-- Icon button with no accessible name -->
<button><svg>...</svg></button>

<!-- Correct: icon button with accessible label -->
<button aria-label="Delete item"><svg>...</svg></button>

How to fix

For icon-only buttons, add aria-label with a descriptive action. For buttons with hidden text, use sr-only CSS or aria-label instead of display:none:
<button aria-label="Save document">
  <svg>...</svg>
</button>

missing-alt-text

Medium WCAG 1.1.1

What it is

<img> elements have no alt attribute at all. This is distinct from an empty alt="" — a missing alt attribute causes screen readers to announce the image filename instead.

How QAOS detects it

The agent scans the DOM for <img> elements where the alt attribute is absent entirely.

Examples

<!-- Missing alt — screen reader announces filename -->
<img src="company-logo.png">

<!-- Correct: descriptive alt -->
<img src="company-logo.png" alt="Acme Corporation">

<!-- Correct: decorative image (empty alt) -->
<img src="divider.png" alt="">

How to fix

Add an alt attribute to every <img> element. For images that convey information, write a concise description. For purely decorative images, use alt="" (empty string) to tell screen readers to skip it.

empty-alt-informative-image

Low WCAG 1.1.1

What it is

Images with an empty alt="" attribute that actually convey meaningful information — such as charts, infographics, or product photos that a user needs to understand the content.

How QAOS detects it

The agent identifies <img alt=""> elements and uses LLM-based analysis to determine whether the image appears to convey information (based on filename, surrounding context, and image content).

Examples

<!-- Informative image incorrectly marked as decorative -->
<img src="revenue-chart-2024.png" alt="">
<img src="product-photo.jpg" alt="">

How to fix

Provide a descriptive alt text for informative images. Reserve alt="" for genuinely decorative images:
<img src="revenue-chart-2024.png" alt="Revenue chart showing 40% growth in Q3 2024">

insufficient-color-contrast

Medium WCAG 1.4.3

What it is

Text elements have a foreground-to-background color contrast ratio below the WCAG minimum of 4.5:1 for normal text (3:1 for large text). This makes text hard or impossible to read for users with low vision or color blindness.

How QAOS detects it

The agent computes the actual contrast ratio between text and background colors from computed CSS styles and flags any text below the threshold.

Examples

/* Failing: light gray on white — ratio ~2.8:1 */
color: #999999;
background: #ffffff;

/* Passing: dark gray on white — ratio ~7:1 */
color: #595959;
background: #ffffff;

How to fix

Use a contrast checker tool (WebAIM Contrast Checker) to verify all text/background combinations. Aim for at least 4.5:1 for body text and 3:1 for large text (18pt+ or 14pt+ bold).

text-too-small

Medium WCAG 1.4.4

What it is

Text has a font size below 14 pixels, making it difficult to read — especially for older users, users with low vision, or users on high-density displays.

How QAOS detects it

The agent computes the rendered font size of all text nodes from computed CSS and flags any below 14px.

How to fix

Set a minimum font size of 14px for all body text. Use relative units (em, rem) rather than pixels so users can scale text with browser settings:
body { font-size: 1rem; }       /* 16px default */
.caption { font-size: 0.875rem; } /* 14px */

not-keyboard-reachable

High WCAG 2.1.1

What it is

Interactive elements — elements that respond to click events — cannot be reached by tabbing with the keyboard. This affects <div> or <span> elements used as buttons, custom dropdowns, and any non-native interactive component that lacks a tabindex attribute.

Why it matters

Users who cannot use a mouse (motor disabilities, power users, keyboard navigators) rely entirely on the Tab key to reach interactive elements. An unreachable element is completely inaccessible to them.

How QAOS detects it

The agent identifies elements with click handlers or interactive roles that are not natively focusable (not a <button>, <a>, <input>, etc.) and checks whether they have tabindex or appropriate ARIA role.

Examples

<!-- Unreachable: div with click handler, no tabindex -->
<div onclick="openModal()">Open Settings</div>

<!-- Correct: button element (natively focusable) -->
<button onclick="openModal()">Open Settings</button>

<!-- Correct: div with tabindex and role -->
<div role="button" tabindex="0" onclick="openModal()">Open Settings</div>

How to fix

Use native HTML elements (<button>, <a>, <input>) wherever possible — they are focusable by default. For custom interactive elements, add tabindex="0" and the appropriate ARIA role.

not-keyboard-activatable

High WCAG 2.1.1

What it is

Elements that can be focused via keyboard (either natively or via tabindex) but cannot be activated using keyboard input. Typically custom button-like elements that only respond to mouse clicks, not Enter or Space.

How QAOS detects it

The agent tabs to focusable elements and presses Enter and Space, checking whether the element responds in the same way as a mouse click.

Examples

<!-- Focusable but not keyboard-activatable -->
<div tabindex="0" onclick="handleAction()">Click Me</div>

How to fix

Add keyboard event handlers to custom interactive elements:
element.addEventListener('keydown', (e) => {
  if (e.key === 'Enter' || e.key === ' ') {
    e.preventDefault()
    handleAction()
  }
})
Or better, replace the custom element with a native <button> which handles this automatically.

missing-focus-indicator

Medium WCAG 2.4.7

What it is

Interactive elements have their default focus ring removed via CSS (outline: none or outline: 0) with no alternative focus indicator provided.

Why it matters

Keyboard users need to know which element is currently focused. Without a visible focus indicator, keyboard navigation becomes blind navigation.

How QAOS detects it

The agent tabs to interactive elements and captures a screenshot, using LLM-based analysis to determine whether a visible focus indicator is present.

How to fix

Never use outline: none without providing an alternative focus style:
/* Don't do this */
:focus { outline: none; }

/* Do this instead */
:focus-visible {
  outline: 2px solid #8265fd;
  outline-offset: 2px;
}

color-only-distinction

High WCAG 1.4.1

What it is

Critical information is conveyed using color as the only visual differentiator — no text label, symbol, icon, pattern, or shape difference accompanies the color cue.

Why it matters

Approximately 8% of men and 0.5% of women have some form of color vision deficiency. When color is the sole indicator of meaning (e.g., a red border meaning “required”), those users receive no information at all. This affects all colorblind users, as well as users on monochrome displays.

How QAOS detects it

The agent captures a screenshot and analyzes elements where color appears to be the sole distinguishing factor — for example, required fields marked only with a red border and no asterisk, text, or icon.

Examples

<!-- Only color distinguishes required — inaccessible -->
<input type="text" style="border-color: red;">

<!-- Correct: color + text marker -->
<label>Name <span aria-hidden="true" style="color: red;">*</span></label>
<input type="text" aria-required="true">

How to fix

Always combine color with at least one other visual cue — text, icon, pattern, or shape:
  • Required fields: add an asterisk or “required” label text
  • Status indicators: add text labels (“Error”, “Success”, “Warning”)
  • Charts: use patterns or direct labels in addition to color coding

image-as-text

Medium WCAG 1.4.5

What it is

Meaningful text is rendered as a rasterized image (PNG, JPG, GIF) rather than actual HTML text. This makes the text unzoomable, unsearchable, unable to be restyled, and often missing from screen reader output.

Why it matters

Users who need to zoom text, adjust font size, change contrast, or copy text cannot do so when the “text” is actually a pixel image. Search engines also cannot index image text, reducing discoverability.

How QAOS detects it

The agent captures a screenshot and uses visual analysis to identify images that appear to contain meaningful text — such as headings, promotional messages, or navigation labels — without an equivalent readable text alternative.

Examples

<!-- Text rendered as image — unzoomable, unsearchable -->
<img src="sale-banner.png" alt="">

<!-- Correct: real HTML text with CSS styling -->
<h2 class="sale-banner">Summer Sale — 30% Off Everything</h2>

How to fix

Replace image-based text with styled HTML text. Use CSS for custom fonts, colors, and visual effects. If a logo or brand mark must be an image, provide a descriptive alt attribute.

iframe-missing-title

Medium WCAG 4.1.2

What it is

An <iframe> element has no title attribute, making it impossible for screen reader users to understand the purpose of the embedded content before deciding to enter it.

Why it matters

Screen readers announce iframes by their title before allowing the user to enter them. Without a title, the iframe is announced as “frame” with no indication of what it contains — forcing users to enter and explore just to understand the context.

How QAOS detects it

The agent scans the DOM for <iframe> elements with no title attribute.

Examples

<!-- No title — screen reader announces "frame" -->
<iframe src="payment.html" width="600" height="400"></iframe>

<!-- Correct: descriptive title -->
<iframe src="payment.html" title="Secure payment form" width="600" height="400"></iframe>

How to fix

Add a concise, descriptive title attribute to every <iframe>:
<iframe src="map-embed.html" title="Map showing our office location"></iframe>
<iframe src="video-player.html" title="Product demo video"></iframe>