Fix

Buttons that announce as nothing at all

Your search control, your cart toggle, your quantity steppers and your gallery arrows are almost certainly icons with no text. To a screen reader they announce as "button" — and to a voice-control user they have no name to say.

Auto-applied WCAG 4.1.2 axe rule button-name

Who this locks out

A nameless button — search, cart, quantity — cannot be operated by voice or announced by a screen reader.

  • Screen-reader users, who hear "button" with no indication of what it does
  • Voice-control users, who cannot say "click search" if nothing is called search
  • Anyone using a browser with images or icon fonts blocked or failing to load

The transform

Before

<button class="icon-search" type="submit"><svg class="icon"><use href="#search"/></svg></button>

After

<button class="icon-search" type="submit" aria-label="Search products"><svg class="icon" aria-hidden="true"><use href="#search"/></svg></button>

Detection

How this is tested here

Every scan runs three independent engines and nine custom probes against your rendered pages, and records which engine flagged what. These are the real rules behind this fix family.

WCAG success criteria this family covers, and the engine rules that detect them. Generated from the engine's own tables — never edited by hand.
Criterion Level Detected by What we do
4.1.2 Name, Role, Value A axe-core (aria-allowed-attr, aria-braille-equivalent, aria-command-name, aria-conditional-attr) · IBM Equal Access (aria_accessiblename_exists, aria_activedescendant_valid, aria_attribute_allowed) auto

This family is keyed to the axe rules button-name in the engine's own category map.

What Klarvo Access does

Klarvo drafts the name from the button's own context, has a second model audit that draft, and applies the high-confidence result server-side — then re-validates the served page to confirm the name is really there.

Auto-applied

Generated, then applied server-side in the HTML your store actually serves — and independently re-validated in the served page before it counts as resolved.

An automated finding is evidence, not a certificate. Conformance is certified only by the professional audit — how that works.

Do it yourself

Fixing this by hand

What “accessible name” actually means

Every interactive control has a name, a role and a value, and assistive technology needs all three. The role of a <button> is announced automatically. The name has to come from somewhere — and a browser will look, in order, for an aria-labelledby reference, an aria-label, the element’s own text content, and then a title attribute as a last resort.

An icon-only button breaks that chain. There is no text content, because the visible label is a glyph. If nobody added an ARIA attribute, the computation finds nothing, and the control ends up in the accessibility tree with an empty name. A screen reader has no choice but to announce it as button.

That is what the axe rule button-name reports, and it is one of the failures most likely to be sitting in your header right now.

Where it bites in a store

Four places, in roughly descending order of damage:

  • Search. A magnifier icon submitting a search form. If it has no name, the one control that helps someone find a product cannot be identified or spoken.
  • The cart toggle. A bag or trolley icon, usually with a count badge. Without a name, the item count is announced with no indication of what it counts.
  • Quantity steppers. The + and on the basket page. These are frequently <button> elements whose only content is a glyph drawn by a CSS pseudo-element — the computed name is then a meaningless character at best, and nothing at all when the glyph is an image.
  • Gallery and slider controls. Previous, next, close, zoom. Product galleries are a common source of several nameless buttons at once.

The checkout is the expensive one. A nameless “Apply coupon” or “Place order” button in a Woo block checkout is a barrier at the exact moment money changes hands.

How this is detected here

This family is keyed to the axe rule button-name, which fires when a <button> (or anything with the button role) computes an empty accessible name. The finding maps to WCAG Success Criterion 4.1.2 Name, Role, Value (Level A), and a second engine corroborates it: IBM Equal Access tests the same criterion through aria_accessiblename_exists and aria_widget_labelled, so a nameless control is usually named by two engines independently rather than asserted once. HTML_CodeSniffer references the criterion as well, without a stable rule id. No bespoke Klarvo probe is needed — the engines cover this ground thoroughly, and the scan records which of them flagged each control.

What Klarvo does about it

Nameless buttons are an auto-tier family with a two-model mechanism. One model drafts the name from the button’s own context — the form it submits, the icon it uses, the markup around it — and a second model audits that draft with no stake in it. A high-confidence result is applied server-side, in the HTML your store actually serves, and the served page is then independently re-scanned to confirm button-name has stopped firing before the finding is counted as resolved. A draft the audit doubts is never applied silently: it goes to your review queue with the proposed name ready to approve, edit or reject.

How to fix it yourself

Prefer real text

The most robust button is one with visible text. If the design allows, put the word in:

<button type="submit" class="search-submit">
  <svg class="icon" aria-hidden="true" focusable="false"><use href="#search" /></svg>
  Search
</button>

Note aria-hidden="true" on the icon. Without it, some SVG content is exposed to the accessibility tree and gets read alongside the label as noise. An icon accompanying real text should always be hidden from assistive technology.

Visually hidden text, when the design will not allow visible text

<button type="submit" class="search-submit">
  <svg class="icon" aria-hidden="true" focusable="false"><use href="#search" /></svg>
  <span class="screen-reader-text">Search products</span>
</button>

WordPress themes already ship a .screen-reader-text class for exactly this, and it is the right technique: the text is genuinely in the document, so it translates with the rest of your site and survives a plugin that strips ARIA attributes.

Whatever hiding class you use, make sure it clips rather than removes. display: none and visibility: hidden take the text out of the accessibility tree along with the pixels.

.screen-reader-text {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

aria-label, when you cannot add a child element

<button type="button" class="cart-toggle" aria-label="Basket, 3 items">
  <svg aria-hidden="true" focusable="false"><use href="#bag" /></svg>
  <span class="count" aria-hidden="true">3</span>
</button>

aria-label overrides the button’s own content and its title — only an aria-labelledby reference outranks it — which is both its use and its danger: if the visible text and the label disagree, sighted voice-control users are left saying a word that is not on screen. Where a button has any visible text, the accessible name must contain that text.

Naming, well

A good button name says what the control does, in the words a customer would use, and does not include the word “button” — the role is announced already.

Instead ofUse
aria-label="btn-search"aria-label="Search products"
aria-label="Click here"aria-label="Add Ceramic Mug to basket"
aria-label="Button"aria-label="Close quick view"
aria-label="+"aria-label="Increase quantity"

For repeated controls in a product grid, include the product: fifteen buttons all called “Add to basket” are technically named and practically useless when read as a list.

Where these live in WooCommerce

  • Search form: wp-content/themes/<theme>/searchform.php, or the Search block’s own settings in a block theme, where “Button only” layouts are the usual culprit.
  • Quantity steppers: usually theme JavaScript rather than a template. Search your theme for quantity and check what the generated markup contains.
  • Cart toggle: the header template or a block pattern. In a block theme, look at the template part rather than header.php.
  • Gallery arrows: woocommerce/single-product/product-image.php if overridden, otherwise the FlexSlider markup Woo generates.

How you know it worked

Three checks, in increasing order of confidence:

  1. Tab to the control and read the browser’s accessibility panel. Both Chrome and Firefox show the computed name in their accessibility inspector. Empty means not fixed.
  2. Turn on a screen reader and tab to it. VoiceOver on macOS is Cmd+F5. You should hear the name and then “button”.
  3. Re-scan the page. The button-name rule should no longer fire, and the finding should close.

A word of warning on the middle option: your own familiarity with the page will fill in gaps that a first-time visitor has nothing to fill them with. If the name only makes sense because you know what the icon is, it is not a good enough name.

Sources: W3C WAI — Understanding SC 4.1.2: Name, Role, Value · W3C — Accessible Name and Description Computation 1.2 · Deque University — axe rule button-name (axe-core 4.12) · MDN — ARIA: button role

FAQ

Questions this raises

Is an icon button with a title attribute good enough?

It is better than nothing and it is not reliable. A title becomes the accessible name only when nothing better exists, it is not shown on touch devices, and it is often not announced by voice-control software. Use visible text where you can and aria-label where you cannot.

What about the tooltip my theme shows on hover?

A CSS tooltip is decoration. If the tooltip text is not in the accessible name, the button still has no name. If it is a real element with text, make sure it is associated with the button rather than merely near it.

My button has a screen-reader-only span inside it. Does that count?

Yes — a visually hidden span with real text inside the button is a perfectly good accessible name, and it is often the best answer because it survives translation and does not need an ARIA attribute. Just make sure the hiding technique keeps the text in the accessibility tree rather than using display: none.

Find out whether your store has this one.

The free scan checks your real pages — home, product, populated basket, hydrated checkout — with all three engines and all nine probes, and tells you exactly what it found and where.