auditmysitev2.0.2

ARIA reference points to an ambiguous ID

aria/owns-conflict

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
duplicate-id-aria

Why we flag this

Assistive technologies cannot reliably determine which element is referenced.

The referenced ID occurs more than once in the DOM.

What the rule checks

Scope. Elements in the accessibility tree with aria-owns.

Expectation. Fails when an id already owned by one element's aria-owns appears in another element's aria-owns; the owner is then undetermined. Reported once, at the second owner. Owners of distinct ids pass. Hidden owners are out of scope; ids compare within one tree (document or shadow root).

Source. WCAG 2.2 SC 4.1.2 Name, Role, Value; WAI-ARIA 1.2 aria-owns ("An element's ID MUST NOT be specified in more than one other element's aria-owns attribute at any time")

Detection: shared; needs dom, ax_tree.

Failing example

The check reports a violation here. Corpus case aria_attrs_invalid, element div#owner-b. The page may contain further findings for other rules.

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

        <h2>Contact</h2>
        <!-- aria/attribute-unknown: typo, the hint is never announced -->
        <label for="email">E-mail address</label>
        <input id="email" type="email" autocomplete="email" aria-describeby="email-hint">
        <p id="email-hint">We only use it for order confirmations.</p>

        <!-- aria/reference-missing: the referenced hint does not exist -->
        <label for="phone">Phone number</label>
        <input id="phone" type="tel" autocomplete="tel" aria-describedby="phone-hint">

        <!-- aria/attribute-value-invalid: aria-pressed is a tristate -->
        <button type="button" id="mute" aria-pressed="yes">Mute notifications</button>

        <!-- aria/attribute-value-invalid: aria-level is an integer -->
        <div id="privacy-heading" role="heading" aria-level="two">Privacy</div>

        <!-- aria/attribute-not-allowed: ARIA in HTML forbids aria-checked on a
             native checkbox -->
        <input type="checkbox" id="agree" aria-checked="true">
        <label for="agree">Share my wish list</label>

        <!-- aria/attribute-not-allowed: listitem does not support aria-selected -->
        <ul id="sections">
            <li id="sec-overview" aria-selected="true">Overview</li>
            <li id="sec-details">Details</li>
        </ul>

        <!-- aria/attribute-prohibited: naming is prohibited on paragraph -->
        <p id="lead" aria-label="Introduction">Manage how we contact you.</p>
        <p id="lead-2" aria-labelledby="privacy-heading">Your data stays with us.</p>

        <!-- aria/owns-conflict: two groups claim the same element -->
        <div role="group" id="owner-a" aria-label="Billing" aria-owns="shared-address"></div>
        <div role="group" id="owner-b" aria-label="Shipping" aria-owns="shared-address"></div>
        <p id="shared-address">Main Street 1, 12345 Sampletown</p>

        <!-- aria/reference-missing: an expanded button points at nothing -->
        <button type="button" id="more-btn" aria-expanded="true" aria-controls="more-panel">More options</button>
    </main>
    <footer>
        <p>Example shop</p>
    </footer>
</body>
</html>

Passing example

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

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

        <h2>Contact</h2>
        <!-- Correctly spelled attributes; aria-description is a WAI-ARIA 1.3
             attribute that browsers already map -->
        <label for="email">E-mail address</label>
        <input id="email" type="email" autocomplete="email" aria-describedby="email-hint" aria-description="Required for orders">
        <p id="email-hint">We only use it for order confirmations.</p>

        <!-- The referenced hint exists but is hidden: referring to hidden
             content is allowed (accname 1.2, step 2B) -->
        <label for="phone">Phone number</label>
        <input id="phone" type="tel" autocomplete="tel" aria-describedby="phone-hint">
        <p id="phone-hint" hidden>Only used for delivery questions.</p>

        <!-- aria-errormessage only matters while aria-invalid is true -->
        <label for="zip">Postal code</label>
        <input id="zip" type="text" autocomplete="postal-code" aria-invalid="false" aria-errormessage="zip-error">

        <!-- Valid tokens, including the boundary values of each value type -->
        <button type="button" id="mute" aria-pressed="mixed">Mute notifications</button>
        <button type="button" id="filter" aria-expanded="undefined">Filter</button>
        <div id="privacy-heading" role="heading" aria-level="3">Privacy</div>
        <div id="storage" role="meter" aria-label="Storage used" aria-valuenow="2.5" aria-valuemin="0" aria-valuemax="1e1">2.5 of 10 GB</div>
        <a href="/settings" id="current" aria-current="page">Settings</a>

        <!-- Attributes the role supports; a native checkbox with ARIA it does
             not duplicate -->
        <input type="checkbox" id="agree" aria-describedby="agree-hint">
        <label for="agree">Share my wish list</label>
        <p id="agree-hint">Friends with the link can see it.</p>
        <div role="checkbox" id="newsletter" tabindex="0" aria-checked="false" aria-label="Newsletter"></div>

        <!-- Naming is allowed on region and navigation -->
        <section id="data-section" aria-label="Your data">
            <p id="lead">Your data stays with us.</p>
        </section>

        <!-- Each group owns a different element -->
        <div role="group" id="owner-a" aria-label="Billing" aria-owns="billing-address"></div>
        <div role="group" id="owner-b" aria-label="Shipping" aria-owns="shipping-address"></div>
        <p id="billing-address">Main Street 1, 12345 Sampletown</p>
        <p id="shipping-address">Harbour Road 7, 12345 Sampletown</p>

        <!-- Collapsed: the controlled panel may only be created on opening
             (WAI-ARIA 1.2 combobox/disclosure, ACT 6a7281) -->
        <button type="button" id="more-btn" aria-expanded="false" aria-controls="more-panel">More options</button>
        <button type="button" id="less-btn" aria-expanded="true" aria-controls="less-panel">Fewer options</button>
        <div id="less-panel">Only the essentials are shown.</div>
    </main>
    <footer>
        <p>Example shop</p>
    </footer>
</body>
</html>

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