Skip to content
AccessibleOrNot

How to fix the 10 most common accessibility issues (with code)

Published: 9 min readThe AccessibleOrNot team

The most common accessibility issues on the web are low contrast text, missing alt text, unlabelled form fields, empty links, empty buttons and a missing page language. In WebAIM's February 2026 scan of one million home pages, these six types made up 96% of all errors found. All six can be detected automatically, and most are fixed with one change in a theme file. This post covers those six, plus four issues that block keyboard and zoom users directly, with before and after code.

In short

  • According to the WebAIM Million 2026, 95.9% of home pages had automatically detectable WCAG failures, with an average of 56.1 errors per page.
  • The six most common (low contrast 83.9%, missing alt text 53.1%, missing form labels 51%, empty links 46.3%, empty buttons 30.6%, missing language 13.5%) are 96% of all errors.
  • Most of these errors come from templates: fix one icon button in the product card and thousands of pages are fixed at once.
  • The contrast threshold is 4.5:1 for normal text and 3:1 for large text; WCAG 2.2 sets a minimum target size of 24×24 CSS pixels.
  • Fixing these closes the part that can be found automatically; keyboard flow and error messages still need a manual test.

What are the 10 most common accessibility issues?

The first six rows are WebAIM's frequency data. The last four were chosen without frequency data, on three criteria: they can be detected automatically, they're fixed in a few lines, and they directly block someone using a keyboard or zoom. The names in brackets are axe-core rule ids; that's how you'll see them in scan reports.

The 10 most common accessibility issues: WCAG criterion, frequency and typical effort
#Issue (axe rule)WCAGShare of home pages (WebAIM 2026)Effort
1Low contrast text (color-contrast)1.4.3 AA83.9%Hours
2Missing alt text (image-alt)1.1.1 A53.1%Hours
3Unlabelled form field (label)1.3.1, 4.1.2 A51%Hours
4Empty link (link-name)2.4.4, 4.1.2 A46.3%Hours
5Empty button (button-name)4.1.2 A30.6%Hours
6Missing page language (html-has-lang)3.1.1 A13.5%Minutes
7Zoom disabled (meta-viewport)1.4.4 AANo dataMinutes
8No skip link or main landmark (bypass)2.4.1 ANo dataMinutes
9Iframe without a title (frame-title)4.1.2 ANo dataMinutes
10Hidden but focusable element (aria-hidden-focus)4.1.2 ANo dataHours

Source: WebAIM, Deque Systems, GitHub

1. How do you fix low contrast text?

Give normal text a contrast ratio of at least 4.5:1 against its background, and large text (24 px and up, or about 18.7 px bold) at least 3:1. The usual problem spots: the struck-through old price, light grey placeholder text, white text on a light banner. Fix the colour in the theme's colour variables, not one element at a time. In the example, #aaaaaa on white is 2.3:1; #767676 passes 4.5:1.

Low contrast: before and after code
Code
Before<s class="price-old" style="color:#aaaaaa">$49.00</s>
After<s class="price-old" style="color:#767676">$49.00</s>

Shopify's theme guidelines ask for the same thresholds: 4.5:1 for small text, 3:1 for large text and for icons and borders.

Source: W3C, Shopify

2. How do you fix missing alt text?

Add an alt attribute to every <img>. For a product image, describe the product and what sets it apart (colour, angle, model); use alt="" only for decorative images. Alt text shouldn't be a file name or an empty word like "image" or "photo". If a lazy-load script swaps the image, check that the alt attribute is carried over.

Missing alt text: before and after code
Code
Before<img src="/products/navy-wool-coat-1.jpg">
After<img src="/products/navy-wool-coat-1.jpg" alt="Navy wool coat, front view">

If you edit in an admin panel rather than code: in Shopify, Products > product > media item > Add alt text; in WooCommerce, Media > Library > "Alternative Text". If a product card wraps the image and the product name in the same link, give the image alt="", or the screen reader reads the name twice.

Source: W3C, Deque Systems, GitHub

3. How do you fix an unlabelled form field?

Connect a visible <label for="..."> to every form field. Placeholder text isn't a label; it disappears once you start typing. Where the design has no room for a visible label (a header search box, for example), use aria-label. Size, colour and quantity selectors follow the same rule.

Unlabelled form field: before and after code
Code
Before<input type="email" name="email" placeholder="Your email address">
After<label for="newsletter-email">Your email address</label> <input type="email" id="newsletter-email" name="email">

Source: W3C, Shopify

5. How do you fix an empty button?

Add an aria-label or visually hidden text to icon buttons (add to cart, menu, close, wishlist) and hide the icon with aria-hidden="true". If a product list has many buttons with the same name, include the product in the name. A screen reader user who hears "Add to cart" 24 times can't tell which button belongs to which product.

Empty button: before and after code
Code
Before<button class="add-to-cart"><i class="icon-cart"></i></button>
After<button class="add-to-cart" aria-label="Add navy coat to cart"><i class="icon-cart" aria-hidden="true"></i></button>

Source: Deque Systems, GitHub

6. What if the page language is missing?

Add the page language to the <html> element: lang="en" for English pages. Without it, a screen reader may read the text with another language's pronunciation. On a multilingual site, the value should come from the template for the current language. It must be a valid language code: "en" or "en-GB"; "en_GB" and "english" are invalid.

Page language: before and after code
Code
Before<html>
After<html lang="en">

In Shopify, in layout/theme.liquid: <html lang="{{ request.locale.iso_code }}">. In WordPress themes, in header.php: <html <?php language_attributes(); ?>>; the value comes from Settings > General > Site Language.

Source: Shopify, WordPress Developer Resources

7. What if zoom is disabled?

Remove user-scalable=no and maximum-scale from the viewport meta tag. A customer with low vision who can't pinch to zoom on a phone can't read the price or the size chart. These values are often added to stop iOS zooming in when a form field gets focus; the right fix for that is a 16 px font size on the fields.

Zoom: before and after code
Code
Before<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
After<meta name="viewport" content="width=device-width, initial-scale=1">

Source: Shopify, Deque Systems, GitHub

9. How do you fix an iframe without a title?

Give every <iframe> a title attribute that says what's inside: "Store location map", "Product video", "Card details". Third-party embeds (YouTube, maps, live chat) usually arrive without one; add it when you paste the code. On a checkout page, the card form is often an iframe; without a name, a screen reader just says "frame".

Iframe without a title: before and after code
Code
Before<iframe src="https://www.youtube.com/embed/abc123"></iframe>
After<iframe src="https://www.youtube.com/embed/abc123" title="Coat fabric and stitching details video"></iframe>

Source: Deque Systems, GitHub

10. How do you fix a hidden but focusable element?

Links and buttons inside a section marked aria-hidden="true" must not be reachable by keyboard. This is common in closed cart drawers and modals: each Tab press takes a keyboard user to an invisible "Checkout" link, while the screen reader says nothing. For closed drawers and modals, use the inert attribute or hidden/display:none instead of aria-hidden.

Hidden focus: before and after code
Code
Before<div class="cart-drawer" aria-hidden="true"><a href="/checkout">Checkout</a></div>
After<div class="cart-drawer" inert><a href="/checkout">Checkout</a></div>

Source: Deque Systems, GitHub

What's left after you fix these 10?

You'll have closed the part that can be found automatically: necessary for an accessible site, but not enough. According to Deque's study, automated testing finds about 57% of issues by volume. For the rest, complete your main flow (product, cart, checkout) with a keyboard only and with a screen reader; check that focus is always visible, that you don't get stuck in pop-ups and that error messages are stated in text. The 20-minute protocol is in our post on automated testing, and platform steps are in our checklists.

Source: Deque Systems

Frequently asked questions

What is the most common accessibility issue?

Low contrast text. According to the WebAIM Million 2026, it appears on 83.9% of home pages. Normal text needs 4.5:1 contrast and large text 3:1.

What does an "empty button" error mean?

The button has no name a screen reader can announce. It usually happens with cart, menu or close buttons that contain only an icon, and is fixed with an aria-label or visually hidden text.

Can a plugin or widget fix these issues?

Not reliably. A widget doesn't change your site's source code, and only the site owner knows what an image's alt text or a button's name should be. Make the fixes in your theme and content.

Should I fix these page by page?

No, fix the template first. One fix in a repeated component, such as the product card, header or footer, fixes thousands of pages at once. What's left at page level is mostly content work, such as alt text.

Sources

  1. The WebAIM Million, 2026 report · WebAIM · February 2026
  2. axe-core rule descriptions · Deque Systems, GitHub · current
  3. WCAG 2.2 · W3C · 5 October 2023 (current version)
  4. Shopify theme accessibility best practices · Shopify · accessed October 2026
  5. language_attributes() function reference · WordPress Developer Resources · accessed October 2026
  6. Automated testing study identifies 57 percent of digital accessibility issues · Deque Systems · 10 March 2021

Related articles

Which of these 10 does your site have?

Enter your URL. We group the issues by template and list them with before/after code and the admin panel steps for your platform.