auditmysitev2.0.2

Form field labeled only via the title attribute

forms/title-only-label

WCAG success criterion
1.3.1 (level A)
Outcome class
Hint only. An automated check that by design reports review hints only: its findings are marked for manual review, never as confirmed violations.
Area
Accessibility, Structure & Semantics
Default severity
medium
axe-core rule
label-title-only

Why we flag this

The title attribute is read inconsistently or not at all by many screen readers; sighted users only see it on hover.

Form element without <label>/aria-label, name derived only from title.

What the rule checks

Scope. Rendered text-entry, select, slider and spinbutton fields (native or ARIA) without placeholder.

Expectation. Needs review when the field's name comes only from its title attribute: visible on mouse hover only, not to keyboard or touch users. H65 allows it when the purpose is clear from the visible context, so never a confirmed violation. A field with a label and a title is not reported; a field with a placeholder is forms/placeholder-as-label's case.

Source. WCAG 2.2 SC 1.3.1, 3.3.2; technique H65 (title attribute to identify form controls)

Detection: shared; needs dom, ax_tree.

Failing example

The check flags this for review. Corpus case forms_extended. The page may contain further findings for other rules.

forms_extended.htmlHTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Extended form checks corpus case</title>
<meta name="viewport" content="width=device-width, initial-scale=1"><style>
  /* #783: page shell, so the case only reports what it is about */
  .skip, nav a { display: inline-block; padding: 12px; min-height: 44px; min-width: 44px; box-sizing: border-box; }
  button, input, select, textarea { min-height: 44px; min-width: 44px; box-sizing: border-box; }
  input[type="checkbox"], input[type="radio"] { width: 44px; height: 44px; }
</style>
</head>
<body>
    <a class="skip" href="#main">Skip to main content</a>
<header><p>Example Shop</p><nav aria-label="Main"><a href="/" aria-current="page">Home</a> <a href="/help">Help</a></nav></header>
<main id="main">
        <h1>Error messages, context changes, labels, redundant entry, table headers</h1>

        <input type="text" aria-invalid="true" aria-label="Email">

        <select aria-label="Navigate to page" onchange="location.href=this.value">
            <option value="/a">Page A</option>
            <option value="/b">Page B</option>
        </select>

        <div onfocus="this.style.color='red'" tabindex="0">Non-interactive element with an onfocus handler</div>

        <input type="text" title="Search the site">

        <form>
            <label for="email1">Email</label>
            <input id="email1" name="email" type="email">
            <label for="billing-email">Billing Email</label>
            <input id="billing-email" name="billing_email" type="email">
            <button type="submit">Submit</button>
        </form>

        <table>
            <thead>
                <tr><th id="col-name">Name</th></tr>
            </thead>
            <tbody>
                <tr><td headers="does-not-exist">Alice</td></tr>
            </tbody>
        </table>
    </main>
<footer><p>Example Shop, 2026</p></footer>
</body>
</html>

Passing example

The check reports nothing here. Corpus case forms_labels, element input#lbl-title. The page may contain further findings for other rules.

forms_labels.htmlHTML
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Delivery preferences</title>
<style>
  body { font-family: sans-serif; color: #222; background: #fff; line-height: 1.5; margin: 0 16px; }
  a { color: #0050a0; }
  .skip, nav a, .solo { display: inline-block; padding: 12px; min-height: 44px; min-width: 44px; box-sizing: border-box; }
  button, input, select, textarea, [role="button"], [role="textbox"], [role="radio"], [role="link"], [role="searchbox"] {
    display: inline-block; min-height: 44px; min-width: 44px; box-sizing: border-box; font-size: 1rem; }
  input[type="checkbox"], input[type="radio"] { width: 44px; height: 44px; }
  .visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
</style>
</head>
<body>
<a class="skip" href="#main">Skip to main content</a>
<header><p>Example Shop</p>
<nav aria-label="Main"><a href="/" aria-current="page">Home</a> <a href="/help">Help</a></nav>
</header>
<main id="main">
<h1>Delivery preferences</h1>
<!-- G2 #783: every labelling mechanism next to fields without one. A field needs a programmatic name (4.1.2, 1.3.1) and a visible label (3.3.2); a placeholder or title names it but is no lasting visible label. -->
<form action="/preferences" method="post">
  <p><input id="coupon-code" name="coupon" type="text"></p>
  <p><textarea id="gift-message" name="gift"></textarea></p>
  <p><select id="wrap-style" name="wrap"><option>Plain</option><option>Festive</option></select></p>
  <p><input id="voucher" name="voucher" type="text" placeholder="Voucher code"></p>
  <p><input id="door-code" name="door" type="text" title="Door code"></p>
  <p><label for="lbl-for">Gate number</label> <input id="lbl-for" name="gate" type="text"></p>
  <p><label>Floor <input id="lbl-wrap" name="floor" type="text"></label></p>
  <p><input id="lbl-aria" name="stairs" type="text" aria-label="Stairwell"></p>
  <p><span id="bell-label">Doorbell label</span> <input id="lbl-by" name="bell" type="text" aria-labelledby="bell-label"></p>
  <p><label for="lbl-ph">Courier note</label> <input id="lbl-ph" name="note" type="text" placeholder="Leave at the door"></p>
  <p><label for="lbl-title">Drop-off spot</label> <input id="lbl-title" name="spot" type="text" title="Where to leave the parcel"></p>
  <p><label for="lbl-select">Wrapping paper</label> <select id="lbl-select" name="paper"><option>Kraft</option><option>Gloss</option></select></p>
  <p><label for="lbl-area">Card text</label> <textarea id="lbl-area" name="card"></textarea></p>
  <p><span id="title-aria" role="textbox" contenteditable="true" tabindex="0" title="Gift note"></span></p>
  <input type="hidden" name="token" value="abc">
  <p><button type="submit">Save preferences</button></p>
</form>
</main>
<footer><p>Example Shop, 2026</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.