Test Page Notice
This page contains intentionally problematic accessibility patterns for testing and demonstration purposes only.
Do not use these examples in production websites. They violate accessibility guidelines and best practices.
This page is designed to work with the Accessibility Visualizer browser extension to help developers identify and understand accessibility issues.
Test Examples
This page serves as a testing ground for the Accessibility Visualizer browser extension. It contains various examples of web elements with accessibility issues to demonstrate how the extension highlights problems and provides information about accessible alternatives.
Categories
Images
Images are a fundamental part of web content that must be accessible to users of assistive technologies. The following examples demonstrate various approaches to image accessibility, including both correct implementations and common mistakes.
<img> element
The img
element requires proper alternative text to be accessible.
Image with alt text
Properly accessible image with descriptive alternative text. This is the correct way to make images accessible.

Image with alt and title
Image with both alt text and title attribute. The title attribute shows as a tooltip but doesn't improve accessibility significantly.

Image without alt attribute
❌ Missing alt attribute - this is problematic! Screen readers will announce the filename or 'image' instead of meaningful content.

Image with title but no alt
❌ Having only a title attribute is insufficient for accessibility. Screen readers primarily use the alt attribute, not title.

Decorative image with empty alt
✅ Empty alt attribute for decorative images. This tells screen readers to skip the image since it doesn't convey important information.

Decorative image with empty alt and title
Decorative image marked properly with empty alt, but unnecessarily includes a title. The title may still show tooltips to mouse users.

Image with aria-hidden
Image hidden from assistive technologies using aria-hidden. This is another way to mark decorative images, though empty alt is more common.
<svg> element
SVG elements can be made accessible using various techniques including title elements, aria-label, and role attributes.
SVG with title element
✅ SVG with a title element provides accessible names to screen readers. This is the standard way to make SVG content accessible.
SVG without title element
❌ SVG without title or other accessibility attributes. Screen readers may not be able to understand what this graphic represents.
SVG with aria-hidden
SVG hidden from assistive technologies. Use this for decorative graphics that don't convey important information.
SVG with aria-label
✅ SVG with aria-label attribute. This provides an accessible name without needing a title element.
SVG with img role
✅ SVG with explicit img role and aria-label. This clearly indicates the SVG is an image and provides its accessible name.
SVG with presentation role
SVG marked as decorative using role='presentation'. This removes semantic meaning from the SVG.
SVG inside link
SVG used as part of a link. The link text provides context, and the SVG itself may not need additional labeling.
role="img"
Elements with role="img"
should have accessible names, typically provided by aria-label.
role="img" with aria-label
✅ Proper use of role='img' with descriptive aria-label. This technique is useful for text-based graphics or emoji.
role="img" without aria-label
❌ Role='img' without aria-label provides no accessible name. Screen readers may read the literal text content, which could be confusing.
Buttons
Buttons are interactive elements that users activate to perform actions. They must be accessible to keyboard users and screen readers. The following examples show various button implementations and common accessibility issues.
<button> Element
Standard button element
✅ The most accessible way to create a button. Semantic HTML buttons are keyboard accessible by default and announced correctly by screen readers.
Button with aria-hidden
❌ Button hidden from assistive technologies. This makes the button inaccessible to screen reader users while remaining visible to sighted users.
Button containing image with alt text
✅ Button with an image that has proper alt text. The alt text becomes the accessible name of the button.
Button containing image without alt text
❌ Button with an image missing alt text. Screen readers cannot determine what this button does, making it inaccessible.
Button Role
Div with button role and tabindex
✅ Properly implemented custom button using a div. Includes role='button' and tabindex='0' to make it accessible. However, semantic HTML buttons are preferred.
Div as button without role
❌ Custom button missing role='button'. Screen readers won't identify this as an interactive element, making it inaccessible.
Div as button without tabindex
❌ Custom button that can't receive keyboard focus. Keyboard users won't be able to activate this button.
Input Elements
Input type="button"
✅ Input element with type='button'. Uses the value attribute to provide the button's accessible name.
Input type="button" without value
❌ Input button without a value attribute has no accessible name. Screen readers cannot identify what this button does.
Input type="submit"
✅ Submit button with proper value. Used within forms to submit data. Has default value of 'Submit' if none provided.
Input type="submit" without value
Submit button without explicit value. Browsers provide a default accessible name ('Submit'), but it's better to be explicit.
Input type="reset"
✅ Reset button that clears form data. Has proper value attribute for accessibility.
Input type="reset" without value
Reset button without explicit value. Browsers provide a default accessible name ('Reset'), but explicit values are clearer.
Input type="image"
❌ Image input without alt text. This creates an inaccessible submit button since screen readers can't determine its purpose.
Input type="image" with alt text
✅ Image input with proper alt text. The alt attribute provides the accessible name for this submit button type.
Summary Element
Summary element
✅ Summary element within details for creating disclosure widgets. Semantically correct and accessible by default.
Click Me
Details content revealed when summary is clicked.
Summary element without details
❌ Summary element used outside of details. This is invalid HTML and may not work as expected across all browsers.
Summary without accessible name
❌ Summary element with no text content or accessible name. Users won't know what this control does.
Details content that can't be properly accessed.
Links
Links are essential navigation elements that allow users to move between pages or sections. They must be properly implemented to ensure keyboard accessibility and clear communication to screen reader users.
<a> Element
Standard link with href
✅ Properly implemented link with href attribute. This is keyboard accessible and clearly identified by screen readers as a navigation element.
Anchor without href attribute
❌ Anchor element without href attribute. This is not a functional link and won't be keyboard accessible or announced properly by screen readers.
Link Role
Element with role="link"
✅ Custom link using role='link' with proper tabindex. While functional, semantic HTML links are preferred for better compatibility.
role="link" without tabindex
❌ Custom link that's not keyboard accessible. Missing tabindex='0' means keyboard users cannot navigate to this element.
Link Variations
Link with target='_blank'
Link that opens in a new window/tab. Consider adding rel='noopener noreferrer' for security and informing users about the new window behavior.
Icon Links
Link with only an icon
❌ Link containing only an icon without text or accessible name. Screen readers cannot determine the link's destination or purpose.
Link with icon and aria-label
✅ Icon link with proper aria-label providing accessible name. This tells screen readers what the link does.
Link with empty text content
❌ Link with no visible or accessible text. Screen readers cannot determine what this link does or where it leads.
Form Controls
Form controls are interactive elements that allow users to input data. They must have proper labels and be accessible to screen readers and keyboard users. The following examples demonstrate both accessible implementations and common accessibility issues.
Text Inputs
Input without label
❌ Text input without any label. Screen readers cannot determine what this field is for, making it inaccessible.
Input with proper label
✅ Text input with associated label using 'for' and 'id' attributes. This creates a programmatic relationship between label and input.
Input with aria-describedby referencing missing IDs
❌ Input using aria-describedby to reference description elements that don't exist in the document.
This input references help text (id="missing-help") and error message (id="missing-error") that don't exist.
Input with mixed existing and missing ID references
⚠️ Input where some referenced IDs exist and others don't. This creates partial accessibility relationships.
References: existing-help ✓, missing-help ❌, missing-error ❌, existing-label ✓, missing-label ❌
Select Elements
Select without label
❌ Select element without label. Users cannot determine what this dropdown is for.
Select with proper label
✅ Select element with associated label. Screen readers can announce both the label and the current selection.
Textarea Elements
Textarea without label
❌ Textarea without label. Users cannot understand what content should be entered here.
Textarea with proper label
✅ Textarea with associated label. Clearly communicates the purpose of the text area to all users.
Radio Buttons
Radio buttons with labels
✅ Properly labeled radio buttons with shared name attribute. Forms a logical group that screen readers can navigate.
Radio buttons without labels
❌ Radio buttons without proper labels. Text appears next to radios but isn't programmatically associated, making it inaccessible.
Radio buttons without name attribute
❌ Radio buttons without shared name attribute. These don't form a proper group, so both can be selected simultaneously.
Radio buttons with different name attributes
❌ Radio buttons with different name attributes don't form a logical group. Each acts as an independent radio button.
Checkboxes
Checkboxes with labels
✅ Properly labeled checkboxes. Each checkbox has a clear, accessible name that screen readers can announce.
Checkboxes without labels
❌ Checkboxes without proper labels. Text appears nearby but isn't programmatically associated with the checkboxes.
Custom styled checkbox with display: none
❌ Custom checkbox using 'display: none' which can remove the element from keyboard navigation and screen readers in some cases.
Label Issues
Orphaned label
❌ Label element not associated with any form control. This can confuse screen readers and doesn't provide any functional benefit.
Label with non-existent ID reference
❌ Label element referencing an ID that doesn't exist. Screen readers cannot establish the relationship between label and control.
The input with id="non-existent-input" doesn't exist in the document.
Input States
Required input
✅ Input with required attribute. Screen readers can announce that this field is required. Consider adding visual indicators and clear error messaging.
Read-only input
Read-only input that users cannot modify. Screen readers will announce this state. Useful for displaying non-editable information in form context.
Headings
Headings provide a hierarchical structure to web content, helping users understand page organization and navigate efficiently. Screen readers use headings as navigation landmarks, so proper heading structure is crucial for accessibility.
Heading Hierarchy
Heading hierarchy demonstration
This example shows the standard HTML heading hierarchy from h1 to h6, plus a custom heading using ARIA attributes. Notice how heading levels should follow a logical order.
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Best practices:
- Start with h1 for main page title
- Don't skip heading levels (h1 → h3 without h2)
- Use headings to create a logical content outline
- Each page should have only one h1
- Use role="heading" with aria-level for headings beyond h6
Problematic Headings
Problematic heading: Skipped level
❌ This example shows incorrect heading hierarchy where h4 appears without h2 or h3. This breaks the logical document structure.
Main Title (h1)
Skipped to h4 - This is problematic!
This h4 should be h2 to maintain proper hierarchy.
Empty heading
❌ Heading element with no text content. Screen readers cannot announce meaningful information about this heading.
This h6 element contains no text and provides no value to users.
Tables
Tables organize data in rows and columns and must be properly structured for screen readers to understand relationships between data. Proper table headers and semantic markup are essential for accessibility.
Table Structure
Table with proper headers
✅ Well-structured table with th elements for headers and proper scope attributes. Screen readers can announce column/row relationships.
Name | Age | City |
---|---|---|
John | 25 | New York |
Jane | 30 | London |
Table without headers
❌ Table using only td elements without proper th headers. Screen readers cannot establish relationships between data.
Name | Age | City |
John | 25 | New York |
Table Headers
Table with row headers
✅ Table with both column headers and row headers using appropriate scope attributes for complex data relationships.
Quarter | Sales | Profit |
---|---|---|
Q1 | $100K | $20K |
Q2 | $150K | $30K |
Table with caption
✅ Table with caption element providing context about the table's purpose. Helps users understand what data the table contains.
Name | Department |
---|---|
Alice | Engineering |
Bob | Marketing |
Table Misuse
Layout table (problematic)
❌ Table used for layout purposes rather than tabular data. Modern CSS should be used for layout instead of tables.
Sidebar content | Main content area |
Use CSS Grid or Flexbox for layout instead of tables.
ARIA Hidden
The aria-hidden attribute controls whether elements are exposed to assistive technologies. When properly used, it can hide decorative content, but when misused, it can make important content inaccessible.
Visible Content
Visible text with aria-hidden='false'
Text that is visible and explicitly exposed to assistive technologies. The aria-hidden='false' is usually unnecessary as elements are exposed by default.
This text is visible and accessible to screen readers.
Visible text with aria-hidden='true'
❌ Visible text hidden from assistive technologies. This creates a confusing experience where sighted users can see content that screen reader users cannot access.
Hidden Content
Hidden text with aria-hidden='true'
Properly hidden decorative or redundant content. Both visually hidden and hidden from assistive technologies.
Main content here
Hidden text with aria-hidden='false'
❌ Content hidden visually but forced to be exposed to screen readers. This creates confusion as screen readers announce content that sighted users cannot see.
Main content here
Icons
Decorative icon with aria-hidden='true'
✅ Proper use of aria-hidden for decorative icons that don't convey essential information. The icon is hidden while the text remains accessible.
Important icon without aria-hidden
❌ Icon that conveys important information but isn't hidden and lacks alternative text. Screen readers might announce confusing information or miss the meaning entirely.
Accessible icon with proper labeling
✅ Icon that conveys meaning with proper accessible labeling using aria-label. The icon provides both visual and programmatic meaning.
Layout & Landmarks
Semantic HTML elements and ARIA landmarks help users understand page structure and navigate efficiently. These elements provide important context about different sections of content.
Semantic Sections
Semantic HTML5 sections
✅ Proper use of HTML5 semantic elements that provide clear structure and meaning to page content.
<header> - Page or section header <main> - Main content area
ARIA Landmarks
ARIA landmark roles
✅ ARIA landmark roles that provide the same navigation benefits as semantic HTML elements. Use when semantic HTML isn't available.
role="banner" - Equivalent to <header>role="main" - Equivalent to <main>role="complementary" - Equivalent to <aside>role="contentinfo" - Equivalent to <footer>
Generic Containers
Generic div containers without semantic meaning
❌ Using generic div elements for major page sections provides no semantic information to assistive technologies.
These divs provide no information about content purpose or page structure.
Section Elements
Section with heading
✅ Proper use of section element with heading. Sections should have headings to provide context about their content.
About Our Services
This section element has a clear heading that describes its content.
Section without heading
❌ Section element without a heading. Sections should have headings to be meaningful landmarks for screen reader users.
This section lacks a heading, making it unclear what this content is about.
iFrame Elements
iFrame with title attribute
✅ iFrame with proper title attribute that describes the content. Essential for screen readers to understand what the frame contains.
iFrame without title attribute
❌ iFrame missing title attribute. Screen readers cannot determine what content the frame contains, making it inaccessible.
iFrame with loading='lazy'
iFrame with lazy loading for performance. Still needs proper title attribute for accessibility.
Dialog and Modal
Dialog element
Example of HTML5 dialog element. When opened with showModal(), it becomes a modal that traps focus and blocks interaction with background content.
Element with aria-modal='true'
✅ Custom modal implementation with proper focus management - traps focus inside the modal and returns focus to the opening button when closed.
Live Regions
Live regions announce dynamic content changes to screen readers. They're essential for providing feedback about status updates, errors, and other dynamic content that users need to be aware of immediately.
aria-live Attribute
aria-live='polite'
✅ Polite live region that announces changes when the user is idle. Good for status updates that aren't urgent.
aria-live='assertive'
✅ Assertive live region that immediately interrupts screen readers to announce changes. Use for critical alerts and errors.
Live Region Roles
role='status'
✅ Status role provides advisory information that isn't critical. Equivalent to aria-live='polite'.
role='alert'
✅ Alert role for important, time-sensitive information. Equivalent to aria-live='assertive'.
Output Element
<output> element
✅ Output element for displaying calculation results or form output. Automatically has live region behavior.
aria-atomic Attribute
Live region with aria-atomic='true'
Live region where the entire content is announced when any part changes, rather than just the changed portion.
Problematic Live Regions
Dynamic content without live region
❌ Content that changes dynamically but isn't marked as a live region. Screen readers won't announce these changes.
Screen readers won't announce the time update because this isn't a live region.
Continuously Updating Live Regions
Timer with polite announcements
Timer that updates every second with polite live region. Good for testing extension behavior with frequent updates.
Live counter with assertive announcements
Counter that auto-increments every 2 seconds with assertive live region. Useful for testing frequent interruptions.
Status updates with role='status'
Status messages that update every 3 seconds. Tests extension handling of role-based live regions with continuous updates.