Accessibility Checker plugin

This plugin is only available for paid TinyMCE subscriptions.

The a11ychecker premium plugin allows you to check the HTML in the editor for various WCAG & Section 508 accessibility problems. It has an auto-repair feature that lets the user fix identified problems.

Interactive example

  • TinyMCE

  • HTML

  • JS

  • Edit on CodePen

<textarea id="a11ychecker">
  <p><strong>Introduction</strong></p>
  <p>Note: This demo has been crafted to intentionally trigger most of our accessibility rules for demonstration purposes.</p>
  <hr>
  <h2><a id="example"></a>The Tiny Logo</h2>
  <p><a href="https://www.tiny.cloud/docs/tinymce/6/a11ychecker/#liveexample" target="_blank" rel="noopener"><img src="https://www.tiny.cloud/docs/images/logos/android-chrome-256x256.png" alt="" width="128" height="128"></a><a href="https://www.tiny.cloud/docs/tinymce/6/a11ychecker/#liveexample" target="_blank" rel="noopener">This is a link to this demo. The same link has been added to logo to the left.</a></p>
  <p>* This is a list.</p>
  <p>* That has been poorly formatted.</p>
  <p>* By using asterisks, instead of using &lt;ul&gt;&lt;li&gt; elements.</p>
  <h4><a id="example"></a>To create an <strong>inaccessible</strong> ordered list:</h4>
  <p>1. Pick a ordering scheme,</p>
  <p>2. Type the item number manually for each item,</p>
  <p>3. Don't use &lt;ol&gt;&lt;li&gt; elements.</p>
  <p>This sentence contains some words that have <span style="background-color: #5a5a5a;">low color contrast</span>, which makes them <span style="color: #ced4d9;">difficult to read</span>.</p>
  <h3>An inaccessible table</h3>
  <p>The below table is missing a caption and table header cells (&lt;th&gt; elements).</p>
  <table style="border-collapse: collapse; width: 100%;" border="1">
  <tbody>
  <tr>
  <td style="width: 31.819%;">&nbsp;</td>
  <td style="width: 31.819%;">&nbsp;</td>
  <td style="width: 31.819%;">&nbsp;</td>
  </tr>
  <tr>
  <td style="width: 31.819%;">&nbsp;</td>
  <td style="width: 31.819%;">&nbsp;</td>
  <td style="width: 31.819%;">&nbsp;</td>
  </tr>
  <tr>
  <td style="width: 31.819%;">&nbsp;</td>
  <td style="width: 31.819%;">&nbsp;</td>
  <td style="width: 31.819%;">&nbsp;</td>
  </tr>
  </tbody>
  </table>
  <p>&nbsp;</p>
</textarea>
tinymce.init({
  selector: 'textarea#a11ychecker',
  plugins: 'a11ychecker advcode table advlist lists image media anchor link autoresize',
  toolbar: 'a11ycheck | blocks bold forecolor backcolor | bullist numlist | link image media anchor | table | code',
  max_height: 500,
  a11y_advanced_options: true,
  a11ychecker_html_version: 'html5',
  a11ychecker_level: 'aaa',
  a11ychecker_allow_decorative_images: true,
  content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }'
});

Basic setup

To add the Accessibility Checker plugin to the editor, add a11ychecker to the plugins option in the editor configuration.

For example:

tinymce.init({
  selector: 'textarea',
  plugins: 'a11ychecker',
  toolbar: 'a11ycheck'
});

Accessibility Rules

The following checks are available for the Accessibility Checker plugin. The rules checked depends on:

  • The level of compliance (A, AA, or AAA), set using the a11ychecker_level option.

  • The HTML version of the content, set using the a11ychecker_html_version option.

Each rule has a severity level, which will be one of the following, listed in order of increasing severity:

  • Warning

  • Error

Document structure rules

D1 - Usage of paragraphs as headings

Rule description: this rule checks that h1-h6 tags are used for heading content, not p tags. Not using correct heading markup will make it difficult for assistive technologies to represent and navigate through your content.

Accessibility Checker rule details - D1
Notification level (severity)

Warning

WCAG level

Level A ; Level AA ; Level AAA

HTML version

HTML4 and HTML5

WCAG 2.1 specification
Examples
Non-compliant examples
<!-- Using paragraphs styled as headings -->
<p style="font-size: 24px; font-weight: bold;">This looks like a heading</p>

<!-- Using div as heading -->
<div class="heading">Another pseudo heading</div>

<!-- Styled paragraph with heading class -->
<p class="h2">Not a real heading</p>

These examples use non-semantic markup that looks like headings but won’t be recognized as such by assistive technologies.

Compliant examples
<!-- Proper heading tags -->
<h1>Main page title</h1>

<h2>Section heading</h2>

<!-- Styled heading for design purposes -->
<h3 class="custom-style">Subsection heading</h3>

These examples use proper heading tags that will be correctly interpreted by assistive technologies.

D2 - Sequential headings

Rule description: this rule checks that heading levels are sequential. Each heading level in a document should follow a logical sequence. That is, you should not skip heading levels (for example, from h2 to h4).

Accessibility Checker rule details - D2
Notification level (severity)

Error

WCAG level

Level A ; Level AA ; Level AAA

HTML version

HTML4 and HTML5

WCAG 2.1 specification

G141 - Organizing a page using headings.

Examples
Non-compliant examples
<!-- Skipping from h1 to h3 -->
<h1>Main title</h1>
<h3>Subsection</h3>

<!-- Skipping from h2 to h4 -->
<h2>Section</h2>
<h4>Sub-subsection</h4>

<!-- Improper nesting -->
<h3>Higher level</h3>
<h2>Lower level</h2>

These examples show incorrect heading level progression that can confuse users of assistive technologies.

Compliant examples
<!-- Proper sequential headings -->
<h1>Main title</h1>
<h2>Section</h2>
<h3>Subsection</h3>
<h4>Sub-subsection</h4>

<!-- Multiple h2 sections -->
<h1>Main title</h1>
<h2>First section</h2>
<h3>Subsection</h3>
<h2>Second section</h2>
<h3>Another subsection</h3>

These examples demonstrate proper heading level progression.

D3 - Adjacent links

Rule description: this rule checks that links next to other links do not have the same href attribute.

For example: If an image link and a text link have the same href attribute, both elements should be in the same a element. If an image link and a text link point to the same URL but are two separate elements, it can be confusing for users of screen readers and other assistive technologies.

Accessibility Checker rule details - D3

Notification level (severity)

Error

WCAG level

Level A ; Level AA ; Level AAA

HTML version

HTML4 and HTML5

WCAG 2.1 specification

H2 - Combining adjacent image and text links for the same resource.

Examples
Non-compliant example
<a href="/download"><img src="download-icon.png" alt="Download"></a>
<a href="/download">Download User Guide</a>

This example has two separate links pointing to the same resource. Screen readers will announce these as two different links, which is redundant and potentially confusing.

Compliant example
<a href="/download">
  <img src="download-icon.png" alt="">
  Download User Guide
</a>

This example combines the image and text into a single link. The image is given an empty alt attribute since the text provides the link’s purpose.

D4O - Ordered list structure

Rule description: this rule checks that an ol element is used for ordered lists. Do not use paragraphs beginning with numbers or roman numerals instead of an ol element containing li items. This is to simplify navigation and parsing of the content for users of assistive technologies.

Accessibility Checker rule details - D4O

Notification level (severity)

Error

WCAG level

Level A ; Level AA ; Level AAA

HTML version

HTML4 and HTML5

WCAG 2.1 specification

H48 - Using ol, ul and dl for lists or groups of links.

Examples
Non-compliant example
<p>1. First prepare the ingredients</p>
<p>2. Mix the dry ingredients together</p>
<p>3. Add wet ingredients slowly</p>
<p>4. Bake at 350°F</p>

This example uses paragraphs with manual numbering instead of proper list markup. Screen readers won’t recognize this as a list structure.

Compliant example
<ol>
    <li>First prepare the ingredients</li>
    <li>Mix the dry ingredients together</li>
    <li>Add wet ingredients slowly</li>
    <li>Bake at 350°F</li>
</ol>

This example uses proper ordered list markup, allowing screen readers to announce the list structure and item count.

D4U - Unordered list structure

Rule description: this rule checks that a ul element is used for unordered lists. Do not use paragraphs beginning with * or - or some similar character instead of an ol element containing li items. This is to simplify navigation and parsing of the content for users of assistive technologies.

Accessibility Checker rule details - D4U

Notification level (severity)

Error

WCAG level

Level A ; Level AA ; Level AAA

HTML version

HTML4 and HTML5

WCAG 2.1 specification

H48 - Using ol, ul and dl for lists or groups of links.

Examples
Non-compliant example
<p>• Fresh vegetables</p>
<p>• Whole grains</p>
<p>- Lean proteins</p>
<p>* Healthy fats</p>

This example uses paragraphs with bullet characters instead of proper list markup. Screen readers won’t recognize this as a list structure.

Compliant example
<ul>
    <li>Fresh vegetables</li>
    <li>Whole grains</li>
    <li>Lean proteins</li>
    <li>Healthy fats</li>
</ul>

This example uses proper unordered list markup, allowing screen readers to announce it as a list and navigate through items efficiently.

D5 - Contrast ratio of the text (D5A, D5B, and D5C)

Rule description: this rule checks that the contrast ratio of the text is above the following values:

  • When the compliance level is set to AA,

    • 4.5:1 for normal text

    • 3:1 for large text

  • When the compliance level is set to AAA,

    • 7:1 for any text

Text with a low contrast ratio is hard to read for users with impaired vision.

Accessibility Checker rule details - D5A

Accessibility Checker rule details - D5B

Accessibility Checker rule details - D5C

Examples
Non-compliant examples
<!-- Light gray text on white background (contrast ratio: 2.3:1) -->
<p style="color: #999999; background-color: #FFFFFF;">This text has insufficient contrast</p>

<!-- Yellow text on white background (contrast ratio: 1.2:1) -->
<p style="color: #FFFF00; background-color: #FFFFFF;">This text is very hard to read</p>

<!-- Large text with insufficient contrast for AA level -->
<h1 style="color: #777777; background-color: #FFFFFF; font-size: 24px;">Large heading with poor contrast</h1>

These examples demonstrate text with insufficient contrast ratios that fail WCAG requirements.

Compliant examples
<!-- Dark gray text on white background (contrast ratio: 4.5:1) -->
<p style="color: #767676; background-color: #FFFFFF;">This text meets AA standard for normal text</p>

<!-- Black text on white background (contrast ratio: 21:1) -->
<p style="color: #000000; background-color: #FFFFFF;">This text exceeds AAA requirements</p>

<!-- Large dark gray text meeting AA requirements for large text -->
<h1 style="color: #959595; background-color: #FFFFFF; font-size: 24px;">Large heading with good contrast</h1>

These examples meet WCAG contrast requirements for their respective sizes and levels.


HTML rules

H93 - IDs must be unique

Rule description: this rule checks that all id attributes are unique in the editor. Duplicate id attributes are known to cause problems for assistive technologies when parsing the content.

Accessibility Checker rule details - H93
Notification level (severity)

Error

WCAG level

Level A ; Level AA ; Level AAA

HTML version

HTML4 and HTML5

WCAG 2.1 specification

H93: Ensuring that id attributes are unique on a Web page.

Examples
Non-compliant examples
<!-- Multiple elements with same ID -->
<div id="section1">First section</div>
<div id="section1">Second section</div>

<!-- Duplicate IDs in different elements -->
<button id="submit">Submit</button>
<input id="submit" type="submit" value="Send">

<!-- Form fields with same ID -->
<label for="name">First name:</label>
<input id="name" type="text">
<label for="name">Last name:</label>
<input id="name" type="text">

These examples show incorrect use of duplicate IDs that can confuse assistive technologies.

Compliant examples
<!-- Unique IDs for sections -->
<div id="section1">First section</div>
<div id="section2">Second section</div>

<!-- Unique IDs for form controls -->
<button id="submit-button">Submit</button>
<input id="submit-input" type="submit" value="Send">

<!-- Form fields with unique IDs -->
<label for="firstname">First name:</label>
<input id="firstname" type="text">
<label for="lastname">Last name:</label>
<input id="lastname" type="text">

These examples demonstrate proper use of unique IDs.


Image rules

I1 - Conflicting or incomplete image accessibility

Rule description: this rule checks that all images have complete and non-conflicting accessibility information. It flags images that send mixed signals about their purpose (both decorative and informative) or have incomplete accessibility information. When a11ychecker_allow_decorative_images is false, this rule also flags decorative images as not allowed.

Accessibility Checker rule details - I1

In TinyMCE 6.3 and later, rule I3 can also be applied. If applied, an Image alternative text should be less than 100 characters warning dialog presents if the alternative (alt) text is longer than 100 characters. This dialog also presents the alternative text in an editable field, for immediate repair.

Examples
Non-compliant examples
<!-- Mixed signals: has alt text but marked as decorative -->
<img src="logo.jpg" alt="Company Logo" role="presentation">

<!-- Incomplete: no accessibility information -->
<img src="chart.jpg">

<!-- Conflicting: decorative intent with aria-label -->
<img src="icon.jpg" role="presentation" aria-label="Icon">

<!-- Conflicting: empty alt with aria-label -->
<img src="decoration.jpg" alt="" aria-label="Decoration">

<!-- Conflicting: decorative with title (interferes with intent) -->
<img src="spacer.gif" role="presentation" title="Spacer">

<!-- Invalid: empty role -->
<img src="photo.jpg" alt="Description" role="">

<!-- When decorative not allowed (if a11ychecker_allow_decorative_images = false) -->
<img src="spacer.gif" alt="" role="presentation">

These examples show various accessibility issues: mixed signals, incomplete intent, and decorative images when not allowed.

Compliant examples
<!-- Informative image with meaningful alt text -->
<img src="logo.jpg" alt="Company Logo">

<!-- Decorative image with empty alt -->
<img src="divider.png" alt="">

<!-- Decorative image with role only -->
<img src="spacer.gif" role="presentation">

<!-- Decorative image with both (redundant but valid) -->
<img src="pattern.jpg" alt="" role="presentation">

<!-- Informative image with supporting aria-describedby -->
<img src="chart.png"
     alt="Sales performance chart"
     aria-describedby="chart-desc">
<p id="chart-desc">Detailed breakdown of Q3 sales performance...</p>

These examples demonstrate proper accessibility markup with clear intent and ARIA compliance.

I2 - Missing alt attribute

Rule description: this rule checks that all <img> elements include an alt attribute, even if other accessible name properties like aria-label, aria-labelledby, or title are present. The alt attribute is required for all images, and informative images must have at least one meaningful text alternative.

Accessibility Checker rule details - I2
Notification level (severity)

Error

WCAG level

Level A ; Level AA ; Level AAA

HTML version

HTML4 and HTML5

WCAG 2.1 specification

F65 - Failure of Success Criterion 1.1.1 due to omitting the alt attribute on img elements.

In TinyMCE 6.3 and later, rule I3 can also be applied. If applied, an Image alternative text should be less than 100 characters warning dialog presents if the alternative (alt) text is longer than 100 characters. This dialog also presents the alternative text in an editable field, for immediate repair.

Examples
Non-compliant examples
<!-- No alt attribute at all -->
<img src="chart.jpg">

<!-- No alt attribute (even with aria-label) -->
<img src="icon.jpg" aria-label="Settings">

<!-- No alt attribute (but has aria-labelledby) -->
<img src="chart.jpg" aria-labelledby="chart-caption">

<!-- No alt attribute (but has title) -->
<img src="button.jpg" title="Submit">

These examples fail because they’re missing the required alt attribute. Note: Images with no attributes at all trigger rule I1 for incomplete intent, not I2.

Compliant examples
<!-- Basic alt attribute usage -->
<img src="product.jpg" alt="Red coffee mug">

<!-- Decorative image with empty alt -->
<img src="separator.png" alt="" role="presentation">

<!-- Alt with supporting aria-describedby -->
<img src="chart.png"
     alt="Sales performance chart"
     aria-describedby="chart-desc">
<p id="chart-desc">Detailed breakdown of Q3 sales performance...</p>

<!-- Alt with matching title for tooltip -->
<img src="icon.png"
     alt="Settings"
     title="Settings">

These examples all include the required alt attribute and provide meaningful text alternatives for informative images.

I3 - Filename used as alt text

Rule description: this rule checks that the alt attribute does not use a filename (e.g., photo.jpg) as a substitute for meaningful image description. Filenames like "IMG_1234.jpg" or "photo.png" don’t help users understand the image content.

Accessibility Checker rule details - I3

In TinyMCE 6.3 and later, rule I3 can also be applied. If applied, an Image alternative text should be less than 100 characters warning dialog presents if the alternative (alt) text is longer than 100 characters. This dialog also presents the alternative text in an editable field, for immediate repair.

Examples
Non-compliant examples
<!-- Alt text matches filename -->
<img src="sunset.jpg" alt="sunset.jpg">

<!-- Alt text matches filename without extension -->
<img src="photo.png" alt="photo">

<!-- Generic filename used as alt -->
<img src="DSC_0123.jpg" alt="DSC_0123.jpg">

<!-- Filename with path used as alt -->
<img src="/images/team/john-smith.png" alt="john-smith.png">

These examples use filenames as alt text, which provides no meaningful information about the image content.

Compliant examples
<!-- Descriptive alt text instead of filename -->
<img src="sunset.jpg" alt="Vibrant orange sunset over ocean waves">

<!-- Meaningful description instead of generic name -->
<img src="photo.png" alt="Team celebrating product launch">

<!-- Descriptive text instead of camera filename -->
<img src="DSC_0123.jpg" alt="Students collaborating in the library">

<!-- Meaningful description for a team member -->
<img src="/images/team/john-smith.png" alt="John Smith, Senior Developer">

These examples use descriptive alt text that explains what the image shows or represents.

I4 - Overly long alt text

Rule description: this rule checks for alt text that exceeds the configured character limit (default: 150 characters). Long descriptions can be difficult for screen reader users to process. Complex images might need detailed descriptions in the surrounding text instead, though some images may require longer descriptions to be fully understood.

Accessibility Checker rule details - I4
Notification level (severity)

Warning

WCAG level

Level A ; Level AA ; Level AAA

HTML version

HTML4 and HTML5

WCAG 2.1 specification

N/A

Examples
Non-compliant examples
<img src="office-photo.jpg"
     alt="Our modern office space features an open floor plan with collaborative workstations, standing desks, and multiple meeting rooms. The space is brightly lit with natural light from floor-to-ceiling windows, and includes a fully stocked kitchen area, relaxation zone with comfortable seating, and a game room with ping pong tables and video games for employee breaks.">

<img src="chart.png"
     alt="Bar graph showing monthly sales data for the past year, with blue bars representing domestic sales and red bars representing international sales, demonstrating a steady increase in both markets with particular growth in Q3 and Q4, reaching peak sales in December.">

These examples use overly detailed alt text that may overwhelm screen reader users with too much information at once.

Compliant examples
<img src="office-photo.jpg"
     alt="Modern open-plan office with collaborative spaces"
     aria-describedby="office-details">
<p id="office-details">Our office features collaborative workstations, standing desks, and meeting rooms, complemented by natural lighting, a kitchen area, and recreational spaces including a game room.</p>

<img src="chart.png"
     alt="Monthly sales growth chart for domestic and international markets"
     aria-describedby="chart-details">
<p id="chart-details">The bar graph shows steady growth in both domestic (blue) and international (red) sales throughout the year, with significant increases in Q3 and Q4, peaking in December.</p>

These examples use concise alt text with additional details provided in the surrounding content.


Table rules

T1 - Table caption

Rule description: this rule checks that all table elements have a caption element describing the data inside the table to simplify parsing and navigation of the content for users of assistive technologies.

Accessibility Checker rule details - T1
Notification level (severity)

Error

WCAG level

Level A ; Level AA ; Level AAA

HTML version

HTML4 and HTML5

WCAG 2.1 specification

H39 - Using caption elements to associate data table captions with data tables.

Examples
Non-compliant examples
<!-- Table without caption -->
<table>
    <tr>
        <th>Product</th>
        <th>Price</th>
    </tr>
    <tr>
        <td>Widget A</td>
        <td>$10.00</td>
    </tr>
</table>

<!-- Using text outside the table -->
<p>Product Pricing Table</p>
<table>
    <tr>
        <th>Product</th>
        <th>Price</th>
    </tr>
    <!-- ... table content ... -->
</table>

These examples lack proper caption elements, making it harder for screen reader users to understand the table’s purpose.

Compliant examples
<!-- Simple table with caption -->
<table>
    <caption>Product Pricing</caption>
    <tr>
        <th>Product</th>
        <th>Price</th>
    </tr>
    <tr>
        <td>Widget A</td>
        <td>$10.00</td>
    </tr>
</table>

<!-- Table with detailed caption -->
<table>
    <caption>2023 Quarterly Sales by Region (in thousands USD)</caption>
    <tr>
        <th>Region</th>
        <th>Q1</th>
        <th>Q2</th>
        <th>Q3</th>
        <th>Q4</th>
    </tr>
    <!-- ... table content ... -->
</table>

These examples include proper caption elements that describe the table’s contents and purpose.

T2 - Complex table summary

Rule description: this rule checks that all complex tables must have a summary attribute explaining to users of assistive technologies how to navigate through the data inside of the table.

This rule only applies to HTML 4 content and is not checked when a11ychecker_html_version is set to html5.

Accessibility Checker rule details - T2
Notification level (severity)

Warning

WCAG level

Level A ; Level AA ; Level AAA

HTML version

HTML4

WCAG 2.1 specification

H73 - Using the summary attribute of the table element to give an overview of data tables.

Examples
Non-compliant examples
<!-- Complex table without summary -->
<table>
    <caption>Employee Performance Review Scores</caption>
    <tr>
        <th rowspan="2">Department</th>
        <th colspan="2">Q1 2023</th>
        <th colspan="2">Q2 2023</th>
    </tr>
    <tr>
        <th>Average</th>
        <th>Range</th>
        <th>Average</th>
        <th>Range</th>
    </tr>
    <!-- ... table content ... -->
</table>

<!-- Summary that just repeats caption -->
<table summary="Employee Performance Review Scores">
    <caption>Employee Performance Review Scores</caption>
    <!-- ... table content ... -->
</table>

These examples either lack a summary or provide one that doesn’t explain the table’s structure.

Compliant examples
<!-- Complex table with descriptive summary -->
<table summary="Performance scores arranged by department. Each department has average scores and score ranges for Q1 and Q2 2023. Read across for quarterly comparisons or down for departmental comparisons.">
    <caption>Employee Performance Review Scores</caption>
    <tr>
        <th rowspan="2">Department</th>
        <th colspan="2">Q1 2023</th>
        <th colspan="2">Q2 2023</th>
    </tr>
    <tr>
        <th>Average</th>
        <th>Range</th>
        <th>Average</th>
        <th>Range</th>
    </tr>
    <!-- ... table content ... -->
</table>

<!-- Table with navigation instructions -->
<table summary="Monthly sales data in a matrix format. Rows represent products, columns represent months. Subtotals are provided at the bottom of each quarter.">
    <caption>2023 Product Sales by Month</caption>
    <!-- ... table content ... -->
</table>

These examples include summaries that explain the table’s structure and how to navigate it.

T3 - Table caption and summary

Rule description: this rule checks that the table caption and summary does not have the same text content. The caption should explain what the table is about while the summary should explain how to navigate the data inside of the table.

The table summary attribute was deprecated in HTML 5, both the what and how information should be moved to the table caption.

Accessibility Checker rule details - T3
Notification level (severity)

Error

WCAG level

Level A ; Level AA ; Level AAA

HTML version

HTML4 and HTML5

WCAG 2.1 specification

H73 - Using the summary attribute of the table element to give an overview of data tables.

Examples
Non-compliant examples
<!-- HTML4: Identical caption and summary -->
<table summary="Quarterly Sales Report 2023">
    <caption>Quarterly Sales Report 2023</caption>
    <!-- ... table content ... -->
</table>

<!-- HTML4: Summary that doesn't add value -->
<table summary="This table shows sales data">
    <caption>Quarterly Sales Report 2023</caption>
    <!-- ... table content ... -->
</table>

<!-- HTML5: Caption that doesn't explain structure -->
<table>
    <caption>Sales Data 2023</caption>
    <!-- ... complex table content ... -->
</table>

These examples show redundant or insufficient information in captions and summaries.

Compliant examples
<!-- HTML4: Complementary caption and summary -->
<table summary="Sales data is organized by product category (rows) and quarter (columns). Each cell contains both revenue and units sold. Totals are provided in the last row.">
    <caption>2023 Quarterly Sales by Product Category</caption>
    <!-- ... table content ... -->
</table>

<!-- HTML5: Comprehensive caption with both what and how -->
<table>
    <caption>
        2023 Quarterly Sales by Product Category
        (Data organized with product categories in rows and quarters in columns.
        Each cell shows revenue and units sold, with totals in the bottom row)
    </caption>
    <!-- ... table content ... -->
</table>

These examples show proper differentiation between what the table contains and how to navigate it.

T4A - Table markup

Rule description: this rule checks that all tables contain both tr and td elements.

Accessibility Checker rule details - T4A
Notification level (severity)

Error

WCAG level

Level A ; Level AA ; Level AAA

HTML version

HTML4 and HTML5

WCAG 2.1 specification

H51 - Using table markup to present tabular information.

Examples
Non-compliant examples
<!-- Table with direct content -->
<table>
    Content without rows or cells
</table>

<!-- Table with only divs -->
<table>
    <div>Row 1, Cell 1</div>
    <div>Row 1, Cell 2</div>
    <div>Row 2, Cell 1</div>
    <div>Row 2, Cell 2</div>
</table>

<!-- Table with paragraphs -->
<table>
    <p>Header 1</p>
    <p>Header 2</p>
    <p>Data 1</p>
    <p>Data 2</p>
</table>

These examples lack proper table structure with rows and cells, making them inaccessible to screen readers.

Compliant examples
<!-- Simple table with proper markup -->
<table>
    <tr>
        <td>Row 1, Cell 1</td>
        <td>Row 1, Cell 2</td>
    </tr>
    <tr>
        <td>Row 2, Cell 1</td>
        <td>Row 2, Cell 2</td>
    </tr>
</table>

<!-- Table with headers and data cells -->
<table>
    <tr>
        <th>Header 1</th>
        <th>Header 2</th>
    </tr>
    <tr>
        <td>Data 1</td>
        <td>Data 2</td>
    </tr>
</table>

<!-- Table with thead and tbody -->
<table>
    <thead>
        <tr>
            <th>Column 1</th>
            <th>Column 2</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Data 1</td>
            <td>Data 2</td>
        </tr>
    </tbody>
</table>

These examples use proper table markup with rows and cells, ensuring accessibility.

T4B - Table headers

Rule description: this rule checks that all table elements contain at least one table header (th) element.

Accessibility Checker rule details - T4B
Notification level (severity)

Error

WCAG level

Level A ; Level AA ; Level AAA

HTML version

HTML4 and HTML5

WCAG 2.1 specification

H51 - Using table markup to present tabular information.

Examples
Non-compliant examples
<!-- Table without headers -->
<table>
    <tr>
        <td>Product</td>
        <td>Price</td>
    </tr>
    <tr>
        <td>Widget</td>
        <td>$10.00</td>
    </tr>
</table>

<!-- Headers using regular cells -->
<table>
    <tr>
        <td><strong>Name</strong></td>
        <td><strong>Position</strong></td>
    </tr>
    <tr>
        <td>John Smith</td>
        <td>Developer</td>
    </tr>
</table>

These examples lack proper header cells, making it difficult for screen readers to understand the table’s structure.

Compliant examples
<!-- Simple table with column headers -->
<table>
    <tr>
        <th>Product</th>
        <th>Price</th>
    </tr>
    <tr>
        <td>Widget</td>
        <td>$10.00</td>
    </tr>
</table>

<!-- Table with row and column headers -->
<table>
    <tr>
        <th scope="col">Quarter</th>
        <th scope="col">Revenue</th>
        <th scope="col">Growth</th>
    </tr>
    <tr>
        <th scope="row">Q1</th>
        <td>$10,000</td>
        <td>5%</td>
    </tr>
    <tr>
        <th scope="row">Q2</th>
        <td>$15,000</td>
        <td>50%</td>
    </tr>
</table>

<!-- Complex table with multiple header levels -->
<table>
    <thead>
        <tr>
            <th rowspan="2">Product</th>
            <th colspan="2">2023</th>
            <th colspan="2">2024</th>
        </tr>
        <tr>
            <th>Q1</th>
            <th>Q2</th>
            <th>Q1</th>
            <th>Q2</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th scope="row">Widget A</th>
            <td>100</td>
            <td>150</td>
            <td>200</td>
            <td>250</td>
        </tr>
    </tbody>
</table>

These examples demonstrate proper use of table headers for different levels of complexity.

T4C - Table heading scope

Rule description: this rule checks that all table header (th) elements have a scope attribute clarifying what scope the heading has inside of the table. The allowed values are row, col, rowgroup, and colgroup. This is important for users of assistive technologies to be able to parse table data.

Accessibility Checker rule details - T4C

Notification level (severity)

Error

WCAG level

Level A ; Level AA ; Level AAA

HTML version

HTML4 and HTML5

WCAG 2.1 specification

H63 - Using the scope attribute to associate header cells and data cells in data tables.

Examples
Non-compliant examples
<!-- Headers without scope -->
<table>
    <tr>
        <th>Product</th>
        <th>Q1</th>
        <th>Q2</th>
    </tr>
    <tr>
        <th>Widget A</th>
        <td>100</td>
        <td>150</td>
    </tr>
</table>

<!-- Incorrect scope usage -->
<table>
    <tr>
        <th scope="row">Name</th>
        <th scope="row">Department</th>
    </tr>
    <tr>
        <td>John Smith</td>
        <td>Engineering</td>
    </tr>
</table>

These examples either lack scope attributes or use them incorrectly.

Compliant examples
<!-- Simple table with proper scope -->
<table>
    <tr>
        <th scope="col">Product</th>
        <th scope="col">Q1</th>
        <th scope="col">Q2</th>
    </tr>
    <tr>
        <th scope="row">Widget A</th>
        <td>100</td>
        <td>150</td>
    </tr>
</table>

<!-- Complex table with rowgroup and colgroup -->
<table>
    <thead>
        <tr>
            <th scope="col" rowspan="2">Department</th>
            <th scope="colgroup" colspan="2">2023</th>
            <th scope="colgroup" colspan="2">2024</th>
        </tr>
        <tr>
            <th scope="col">Budget</th>
            <th scope="col">Actual</th>
            <th scope="col">Budget</th>
            <th scope="col">Forecast</th>
        </tr>
    </thead>
    <tbody>
        <th scope="rowgroup" rowspan="2">Engineering</th>
        <tr>
            <th scope="row">Development</th>
            <td>100K</td>
            <td>95K</td>
            <td>120K</td>
            <td>125K</td>
        </tr>
    </tbody>
</table>

These examples demonstrate proper use of scope attributes for different table structures.


Options

The following configuration options affect the behavior of the Accessibility Checker plugin.

a11y_advanced_options

This option affects the functionality of:

Setting a11y_advanced_options to true:

  • Adds the Image is decorative option to the Insert/Edit Image dialog, allowing users to specify that an image is decorative and does not require alternative text for accessibility purposes.

  • Adds the Decorative image button to Image Optimizer’s Alt text context toolbar, allowing users to specify that an image is decorative and does not require alternative text for accessibility purposes.

  • Adds the Image is decorative option to the Accessibility Checker error dialog for images that need to be marked as decorative.

If a11ychecker_allow_decorative_images is not explicitly set, the value defined in a11y_advanced_options will be used.

Type: Boolean

Default value: false

Possible values: true, false

Example: using a11y_advanced_options

tinymce.init({
  selector: 'textarea',  // change this value according to your HTML
  plugins: 'a11ychecker',
  toolbar: 'a11ycheck',
  a11y_advanced_options: true,
});

a11ychecker_alt_text_max_length

This option sets the maximum length for image alternative text before triggering a warning.

Type: Number

Default value: 150

Example:

tinymce.init({
  selector: 'textarea',
  plugins: 'a11ychecker',
  toolbar: 'a11ycheck',
  a11ychecker_alt_text_max_length: 200  // Allow longer descriptions if needed
});

a11ychecker_allow_decorative_images

This option determines whether the Accessibility Checker should allow decorative images. Decorative images are those that are used purely for visual enhancement and do not convey meaningful content or serve a specific function.

When this option is set to true, decorative images must be marked using one or both of these methods:

  • An empty alternative text attribute (alt=""), OR

  • The role="presentation" or role="none" attribute, OR

  • Both methods together

Any of these approaches explicitly tells assistive technologies to ignore these images, improving the browsing experience for users of screen readers.

Common Use Cases for Decorative Images

  • Background patterns or textures

  • Aesthetic borders or dividers

  • Purely decorative icons that repeat nearby text

  • Images that are described by adjacent text content

  • Spacer images used for layout purposes

Examples of Decorative Images:

<!-- Using empty alt attribute -->
<img src="decorative-border.png" alt="" />

<!-- Using role="presentation" -->
<img src="spacer.gif" role="presentation" />

<!-- Using both approaches -->
<img src="pattern.png" role="presentation" alt="" />

<!-- Using empty alt and title attribute -->
<img src="decorative-border.png" alt="" title=""/>

Example of an Informative Image (non-decorative):

<img src="company-logo.png" alt="Company Name Logo" />

Validation Rules

If a11ychecker_allow_decorative_images is set to true, the Accessibility Checker will present an error when:

  • An image has conflicting accessibility information (e.g., both meaningful alt text and role="presentation").

  • An image has incomplete accessibility information (no clear decorative or informative intent).

If a11ychecker_allow_decorative_images is set to false, the Accessibility Checker will present an error when:

  • An image does not have the alternative text attribute (alt).

  • An image has an empty alternative text attribute.

  • An image has the role="presentation" attribute.

If a11ychecker_allow_decorative_images is not explicitly set, the value defined in a11y_advanced_options will be used.

Type: Boolean

Default value: false

Possible values: true, false

Example: using a11ychecker_allow_decorative_images

tinymce.init({
  selector: 'textarea',
  plugins: 'a11ychecker',
  toolbar: 'a11ycheck',
  a11ychecker_allow_decorative_images: true
});

a11ychecker_filter_issue

The a11ychecker_filter_issue option allows Accessibility Checker issues to be removed from the Accessibility Checker report using a callback function. This option is a flexible alternative to the a11ychecker_ignored_rules option. This option can remove issues from the results shown in the dialog and the getReport API.

The callback function will be passed issue objects generated by the getReport() API. To remove an issue from the Accessibility Checker report the callback needs to return false for that particular issue.

Type: Function

Default value:

(issue) => true;

Example: using a11ychecker_filter_issue to filter out the Accessibility Checker T1 rule

The callback function in the following example will return false if the issue id value is 'T1', filtering 'T1' issues from the Accessibility Checker report.

tinymce.init({
  selector: 'textarea',  // change this value according to your html
  plugins: 'a11ychecker',
  toolbar: 'a11ycheck',
  a11ychecker_filter_issue: (issue) => {
    return issue.id !== 'T1';
  }
});

Example: using a11ychecker_filter_issue to filter out all Accessibility Checker table rules and rules less than 'error' level

The callback function in the following example will only return false if the issue element is a 'table' and the 'severity' level is not 'error', filtering all low-severity and table element-related issues from the Accessibility Checker report.

tinymce.init({
  selector: 'textarea',  // change this value according to your html
  plugins: 'a11ychecker',
  toolbar: 'a11ycheck',
  a11ychecker_filter_issue: (issue) => {
	  return !(issue.element.nodeName.toLowerCase() === 'table' || issue.severity !== 'error');
  }
});

Example: using a11ychecker_filter_issue to filter images with empty alternative text from the Accessibility Checker I1 rule

The callback function in the following example will only return false for any issues with 'I1' as the 'id' for image elements with an empty +'alt+' attribute, otherwise the issue won’t be filtered out. This implementation can be useful when you want to allow images with empty alternative text to be treated as decorative.

tinymce.init({
  selector: 'textarea',  // change this value according to your html
  plugins: 'a11ychecker',
  toolbar: 'a11ycheck',
  a11ychecker_filter_issue: (issue) => {
    const element = issue.element;
    const isImageAndI1Issue = issue.id === 'I1' && element.nodeName.toLowerCase() === 'img';
    const hasEmptyAltAttribute = element.hasAttribute('alt') && element.alt === '';
    return !(isImageAndI1Issue && hasEmptyAltAttribute);
  }
});

a11ychecker_html_version

This configuration option sets the HTML version to use when checking issues.

For example: Setting the version to HTML 4 will enable the rule "Complex tables should have summaries", where summary is a valid attribute in HTML 4 but not HTML 5.

Type: String

Default value: html5

Possible values: html4, html5

Example: using a11ychecker_html_version

tinymce.init({
  selector: 'textarea',
  plugins: 'a11ychecker',
  toolbar: 'a11ycheck',
  a11ychecker_html_version: 'html4'
});

a11ychecker_ignored_rules

The a11ychecker_ignored_rules option prevents specific Accessibility Checker rules from being checked. This feature allows developers to skip rules that they do not wish to check. For example: To skip rules that flag known content issues or custom HTML that should not be checked.

Type: A comma-separated string.

Default value: ''

Possible values: 'D1', 'D2', 'D3', 'D4O', 'D4U', 'D5A', 'D5B', 'D5C', 'H93', 'I1', 'I2', 'T1', 'T2', 'T3', 'T4A', 'T4B', 'T4C'

Example: using a11ychecker_ignored_rules

This examples shows how to ignore the following checks (rules):

  • D2 - Sequential headings

  • I2 - Image alt text is not the image filename

  • T4B - Table headers

tinymce.init({
  selector: 'textarea',  // change this value according to your html
  plugins: 'a11ychecker',
  toolbar: 'a11ycheck',
  a11ychecker_ignored_rules: 'D2, I2, T4B'
});

a11ychecker_issue_url_callback

The a11ychecker_issue_url_callback option is used to change the target URL for the "Click for more info" button (help icon - a question mark inside a circle) in the Accessibility Checker dialog. By default, the "more info" links will point to https://www.tiny.cloud/docs/tinymce/8/a11ychecker/#<ruleId>, such as https://www.tiny.cloud/docs/tinymce/8/a11ychecker/#D1. This option can be used to set the target URL to a page or pages outside https://www.tiny.cloud/docs/.

Type: Function

Default value:

(ruleId) => `https://www.tiny.cloud/docs/tinymce/6/a11ychecker/#${ruleId}`

Example: using a11ychecker_issue_url_callback

This example shows how to change the link for the "Click for more info" button (help icon - a question mark inside a circle) on the Accessibility Checker dialog to point to anchors at www.example.com/tinymce/a11ychecker/more_info.

tinymce.init({
  selector: 'textarea',  // change this value according to your html
  plugins: 'a11ychecker',
  toolbar: 'a11ycheck',
  a11ychecker_issue_url_callback: (ruleId) =>
    `https://www.example.com/tinymce/a11ychecker/more_info#${ruleId}`
});

a11ychecker_level

This configuration option sets the WCAG level to use when checking issues.

For example, the "Text must have a contrast ratio of at least …​" rule:

  • When using AA, Accessibility Checker will check that the contrast ratio is not less than 4.5:1.

  • When using AAA, Accessibility Checker will check that the contrast ratio is not less than 7.0:1.

Type: String

Default value: aa

Possible values: a, aa, aaa

Example: using a11ychecker_level

tinymce.init({
  selector: 'textarea',
  plugins: 'a11ychecker',
  toolbar: 'a11ycheck',
  a11ychecker_level: 'aaa'
});

Toolbar buttons

The Accessibility Checker plugin provides the following toolbar buttons:

Toolbar button identifier Description

a11ycheck

Opens the accessibility checker dialog.

These toolbar buttons can be added to the editor using:

The Accessibility Checker plugin provides the following menu items:

Menu item identifier Default Menu Location Description

a11ycheck

Tools

Opens the accessibility checker dialog.

These menu items can be added to the editor using:

Events

The Accessibility Checker plugin provides the following events.

Name Data Description

A11ycheckStart

N/A

Fired when the Accessibility Checker is opened

A11ycheckStop

N/A

Fired when the Accessibility Checker is closed

A11ycheckIgnore

N/A

Fired when the Ignore button is pressed

A11ycheckRepair

N/A

Fired when the Repair button is pressed

A11ycheckShowDetails

N/A

Fired when the Click for more info button is pressed

APIs

The Accessibility Checker plugin provides the following APIs.

toggleaudit()

Opens and closes the accessibility checker dialog with the results of the audit and options to correct the problems, if any.

Example: using toggleaudit()

tinymce.activeEditor.plugins.a11ychecker.toggleaudit();

getReport()

Conducts an accessibility audit and reports the results without opening the dialog. The report produced is an array of objects, where each object represents an issue.

Example: using getReport()

const issues = tinymce.activeEditor.plugins.a11ychecker.getReport();

console.log(issues);

// Example result
[
  {
    "contentID": "<div id=\"accessibility-issue__contentID\"><span>Text:&nbsp;</span><span>\"H5\"</span></div>",
    "description": "Headings must be applied in sequential order. For example: Heading 1 should be followed by Heading 2, not Heading 3.",
    "element": h5, // reference to the DOM element where the issue was found
    "id": "D2",
    "severity": "error",
    "url": "https://www.w3.org/WAI/WCAG21/Techniques/general/G141.html",
  },
  {
    "contentID": "<div id=\"accessibility-issue__contentID\"><span>Table:&nbsp;</span><span>\"2x2\"</span></div>",
    "description": "Tables must have captions",
    "element": table, // reference to the DOM element where the issue was found
    "id": "T1",
    "severity": "error",
    "url": "https://www.w3.org/WAI/WCAG21/Techniques/html/H39.html",
  }
]

The issue object

In a11ychecker, when the content within the editor is audited, each element is checked to ensure that no Accessibility rules are violated. Any element which doesn’t adhere to a rule will generate an issue within the audit; the details of which are to be displayed in the a11ychecker dialog.

The 'issue' object provides relevant data pertaining to any issue generated by an element which violates an Accessibility rule:

  • id : String A11ychecker issue identifier used by TinyMCE, such as D1, T4A. For a description and other details about the issue, see Accessibility Rules.

  • description : String description of the issue; as will be displayed in the dialog.

  • severity : String severity level of the issue; either warning or error.

  • url : String URL reference for the issue. By default, this will be a link to the W3 website, containing the W3 WCAG technique that needs to be addressed to clear the issue.

  • element : Object DOM element where the issue was found.

  • contentID : String A short snippet of the content (such as text, link, image, or table) where the issue was found.