auditmysitev2.0.2

Invalid modern interaction attributes

popover/target-invalid

WCAG success criterion
4.1.2 (level A)
Outcome class
Automatic. An automated check that can report a confirmed violation.
Area
Accessibility, Technical Robustness
Default severity
high
axe-core rule
modern-attribute-misuse

Why we flag this

Screen reader and keyboard users cannot reliably access dialogs, popovers, or disabled regions.

Broken popovertarget references, unnamed surfaces, or active focus inside inert regions.

What the rule checks

Scope. Elements with a popovertarget attribute whose target exists (Markup scope).

Expectation. Fails when the referenced element has no popover attribute: activation does nothing. A target with popover passes, whether open or closed (hidden).

Source. WCAG 2.2 SC 4.1.2 Name, Role, Value; HTML Living Standard, the popover target attributes (the target must be a popover)

Detection: shared; needs dom.

Failing example

The check reports a violation here. Corpus case aria_widgets_broken, element button#shipping-btn. The page may contain further findings for other rules.

aria_widgets_broken.htmlHTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Trail running shoe - Example shop</title>
</head>
<body>
    <header>
        <p>Example shop</p>
    </header>
    <main>
        <h1>Trail running shoe</h1>

        <!-- aria/tab-selected-missing and aria/tabpanel-missing: no tab is
             selected, and the document has no tab panel -->
        <div id="product-tabs" role="tablist" aria-label="Product information">
            <button type="button" role="tab" id="tab-desc">Description</button>
            <button type="button" role="tab" id="tab-reviews">Reviews</button>
        </div>
        <div id="product-text">Lightweight shoe with a grippy sole.</div>

        <!-- aria/combobox-popup-missing: expanded, popup not referenced -->
        <label for="size">Size</label>
        <input id="size" type="text" role="combobox" aria-expanded="true" aria-autocomplete="list">
        <ul id="size-options" role="listbox" aria-label="Sizes">
            <li role="option" id="size-42" aria-selected="false">42</li>
            <li role="option" id="size-43" aria-selected="false">43</li>
        </ul>

        <!-- popover/target-missing and popover/target-invalid -->
        <button type="button" id="guide-btn" popovertarget="size-guide">Size guide</button>
        <button type="button" id="shipping-btn" popovertarget="shipping-info">Shipping</button>
        <div id="shipping-info">Free shipping from 50 EUR.</div>

        <!-- patterns/accordion-controls-missing: expanded, region unknown -->
        <button type="button" id="care-btn" aria-expanded="true">Care instructions</button>
        <div id="care-text">Clean with a damp cloth.</div>
        <div id="fit-btn" role="button" tabindex="0" aria-expanded="true">Fit</div>
        <div id="fit-text">True to size.</div>

        <!-- patterns/tooltip-unreferenced: nothing points at the tooltip -->
        <button type="button" id="fav-btn">Add to wish list</button>
        <div role="tooltip" id="fav-tip">Saved items stay for 30 days</div>

        <!-- modern-attribute-misuse (active_surface_inert): the promotion is
             shown as an open popover but marked inert, so its button cannot be
             reached or operated -->
        <div id="promo" popover="manual" inert aria-label="Promotion">
            <p>10 % off your first order.</p>
            <button type="button" id="promo-close">Close</button>
        </div>
    </main>
    <footer>
        <p>Example shop</p>
    </footer>
    <script>
        document.getElementById('promo').showPopover();
    </script>
</body>
</html>

Passing example

The check passes here and reports nothing. Corpus case aria_widgets_valid. The page may contain further findings for other rules.

aria_widgets_valid.htmlHTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Trail running shoe - Example shop</title>
</head>
<body>
    <header>
        <p>Example shop</p>
    </header>
    <main>
        <h1>Trail running shoe</h1>

        <!-- One tab selected, panel present -->
        <div id="product-tabs" role="tablist" aria-label="Product information">
            <button type="button" role="tab" id="tab-desc" aria-selected="true" aria-controls="panel-desc">Description</button>
            <button type="button" role="tab" id="tab-reviews" aria-selected="false" aria-controls="panel-desc" tabindex="-1">Reviews</button>
        </div>
        <div id="panel-desc" role="tabpanel" aria-labelledby="tab-desc">Lightweight shoe with a grippy sole.</div>

        <!-- Expanded combobox referencing its popup; a collapsed one needs no
             reference -->
        <label for="size">Size</label>
        <input id="size" type="text" role="combobox" aria-expanded="true" aria-autocomplete="list" aria-controls="size-options">
        <ul id="size-options" role="listbox" aria-label="Sizes">
            <li role="option" id="size-42" aria-selected="false">42</li>
            <li role="option" id="size-43" aria-selected="false">43</li>
        </ul>
        <label for="colour">Colour</label>
        <input id="colour" type="text" role="combobox" aria-expanded="false" aria-autocomplete="list">

        <!-- The native select has its popup built in -->
        <label for="qty">Quantity</label>
        <select id="qty"><option>1</option><option>2</option></select>

        <!-- A visible menu named by its heading -->
        <h2 id="sort-label">Sort reviews</h2>
        <div id="sort-menu" role="menu" aria-labelledby="sort-label">
            <div role="menuitem" id="sort-new" tabindex="0">Newest first</div>
            <div role="menuitem" id="sort-best" tabindex="-1">Best rated</div>
        </div>

        <!-- popovertarget points at a (closed, hence hidden) popover -->
        <button type="button" id="guide-btn" popovertarget="size-guide">Size guide</button>
        <div id="size-guide" popover>EU 42 equals UK 8.</div>

        <!-- Expanded button naming the region it controls -->
        <button type="button" id="care-btn" aria-expanded="true" aria-controls="care-text">Care instructions</button>
        <div id="care-text">Clean with a damp cloth.</div>

        <!-- Tooltips referenced as description and as name -->
        <button type="button" id="fav-btn" aria-describedby="fav-tip">Add to wish list</button>
        <div role="tooltip" id="fav-tip">Saved items stay for 30 days</div>
        <button type="button" id="share-btn" aria-labelledby="share-tip"><span aria-hidden="true">&#x2197;</span></button>
        <div role="tooltip" id="share-tip">Share</div>

        <!-- Open, operable popover -->
        <div id="promo" popover="manual" aria-label="Promotion">
            <p>10 % off your first order.</p>
            <button type="button" id="promo-close">Close</button>
        </div>
    </main>
    <footer>
        <p>Example shop</p>
    </footer>
    <script>
        document.getElementById('promo').showPopover();
    </script>
</body>
</html>

This page is generated from the rule catalogue and the rule contracts; see therule overview for how the outcome classes are derived.