Skip to content

[Accessibility] Insufficient contrast for keyboard focus indicator on "Add to Basket" button (WCAG 2.2 SC 1.4.11) #2210

Description

@robcmcdowall

Describe the bug

The default purple focus indicator (#7F54B3) has a contrast ratio of 2.29:1 against the charcoal "Add to basket" button border and background (#333333). This fails the WCAG SC 1.4.11 Non-text Contrast (Level AA) requirement of 3:1.

WebAim Contrast Checker Report for #7F54B3 and #333333

Without an outline-offset, the focus indicator sits directly on the border of the button. Since both colours are relatively dark, the focus indicator blends into the button, making it almost indistinguishable to all users.

This is especially problematic for users with low vision or colour vision deficiency (CVD), who might perceive purple as a low-contrast grey or a darker shade that lacks sufficient luminosity to be distinguished from the button.

Note: This also fails WCAG SC 2.4.11 Focus Appearance, which requires a visible focus indicator to provide a contrast ratio of at least 3:1 between the focused and unfocused states. The current contrast ratio of 2.29:1 does not meet this requirement.

a:focus, input:focus, textarea:focus, button:focus {
	outline: 2px solid #7f54b3;
}
  • I have deactivated other plugins and themes and confirmed this bug occurs when only WooCommerce + Storefront theme are active.
  • I can reproduce this bug consistently using the steps below.

To Reproduce

Steps to reproduce the behavior:

  1. Perform a clean install of WordPress locally.
  2. Install and activate the Storefront Theme and WooCommerce.
  3. Import the WooCommerce sample products.
  4. Open any product page and use the Tab key to navigate to the "Add to basket" button.
  5. Observe the colour of the focus indicator.
  6. Inspection:
  • Open Browser DevTools.
  • Right-click the button > Inspect.
  • Toggle the pseudo class to :hov.
  • Force the element state to :focus.
  • Observe the outline property in the Styles pane.
  1. Use a tool like the TPGi Color Contrast Analyser or the WebAIM Contrast Checker to compare the computed purple outline (#7F54B3) against the dark button background (#333333).

Accessibility Simulation (Firefox)

To verify the impact on users with colour vision deficiency (CVD), I used the Firefox Accessibility Inspector:

  1. Simulate Persistent Focus: Because the focus state clears when interacting with the Firefox Accessibility Inspector, manually force the style:

    • Right-click the button > Inspect.
    • In the Rules/Styles pane, manually add outline: 2px solid #7f54b3; to the element to simulate a permanent focus state.
button.alt {
    background-color: #333333;
    border-color: #333333;
    color: #ffffff;
+   outline: 2px solid #7f54b3;
}
  1. Right-click the button > Inspect Accessibility Properties.
  2. Locate the "Simulate" dropdown menu in the toolbar.
  3. Select Tritanopia (no blue) and Achromatopsia (no colour).
  4. Observe how under these simulations, the purple indicator (#7F54B3) desaturates into a washed out purple and grey.

Screenshots

Screenshot of WooCommerce product page highlighting insufficient contrast on add to basket focus indicator

Expected behavior

To comply with WCAG SC 1.4.11 while maintaining the default WooCommerce brand colour, an outline-offset should be added. This creates a gap between the button border and the focus indicator, ensuring the outline is perceivable against the page background rather than blending into the dark button.

Browser Environment

Firefox Developer Edition 149.0b1 (Windows 11 Home)
Firefox 148.0 (Windows 11 Home)
Chrome 145.0.7632.117 (Windows 11 Home)

WordPress Environment

System Status Report
### WordPress Environment ###

WordPress address (URL): [Redacted]
Site address (URL): [Redacted]
WC Version: 10.5.3
Legacy REST API Package Version: The Legacy REST API plugin is not installed on this site.
Action Scheduler Version: ✔ 3.9.3
Log Directory Writable: ✔
WP Version: 6.9.1
WP Multisite: –
WP Memory Limit: 256 MB
WP Debug Mode: –
WP Cron: ✔
WP Environment Type: local
Language: en_GB
External object cache: –

### Server Environment ###

Server Info: nginx/1.26.1
Server Architecture: Windows NT 10.0 AMD64
PHP Version: 8.4.4
PHP Post Max Size: 1,000 MB
PHP Time Limit: 1200
PHP Max Input Vars: 4000
cURL Version: 8.10.1
OpenSSL/3.0.15

SUHOSIN Installed: –
MySQL Version: 8.0.16
Max Upload Size: 300 MB
Default Timezone is UTC: ✔
fsockopen/cURL: ✔
SoapClient: ✔
DOMDocument: ✔
GZip: ✔
Multibyte String: ✔
Remote Post: ✔
Remote Get: ✔

### Database ###

[REDACTED]

### Post Type Counts ###

attachment: 23
customize_changeset: 1
page: 7
post: 2
product: 23
product_variation: 7
revision: 1
wp_navigation: 1

### Security ###

Secure connection (HTTPS): ❌
					Your store is not using HTTPS. Learn more about HTTPS and SSL Certificates.
Hide errors from visitors: ✔

### Active Plugins (1) ###

WooCommerce: by Automattic – 10.5.3

### Inactive Plugins (0) ###


### Settings ###

Legacy API Enabled: –
Force SSL: –
Currency: GBP (£)
Currency Position: left
Thousand Separator: ,
Decimal Separator: .
Number of Decimals: 2
Taxonomies: Product Types: external (external)
grouped (grouped)
simple (simple)
variable (variable)

Taxonomies: Product Visibility: exclude-from-catalog (exclude-from-catalog)
exclude-from-search (exclude-from-search)
featured (featured)
outofstock (outofstock)
rated-1 (rated-1)
rated-2 (rated-2)
rated-3 (rated-3)
rated-4 (rated-4)
rated-5 (rated-5)

Connected to WooCommerce.com: –
Enforce Approved Product Download Directories: ✔
HPOS feature enabled: ✔
Order datastore: Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore
HPOS data sync enabled: –
Enabled Features: analytics
marketplace
order_attribution
site_visibility_badge
remote_logging
email_improvements
blueprint
point_of_sale
custom_order_tables


### Logging ###

Enabled: ✔
Handler: Automattic\WooCommerce\Internal\Admin\Logging\LogHandlerFileV2
Retention period: 30 days
Level threshold: –
Log directory size: 12 KB

### WC Pages ###

Shop base: #7 - /shop/
Basket: #8 - /cart/ -  Contains the woocommerce/cart block
Checkout: #9 - /checkout/ -  Contains the woocommerce/checkout block
My account: #10 - /my-account/ -  Contains the [woocommerce_my_account] shortcode
Terms and conditions: ❌ Page not set

### Theme ###

Name: Storefront
Version: 4.6.2
Author URL: https://woocommerce.com/
Child Theme: ❌ – If you are modifying WooCommerce on a parent theme that you did not build
personally we recommend using a child theme. See: How to create a child theme

Theme type: Classic theme
WooCommerce Support: ✔

### Templates ###

Overrides: –

### Admin ###

Enabled Features: activity-panels
analytics
analytics-scheduled-import
product-block-editor
experimental-iapi-mini-cart
coupons
core-profiler
customize-store
customer-effort-score-tracks
import-products-task
experimental-fashion-sample-products
shipping-smart-defaults
shipping-setting-tour
homescreen
marketing
mobile-app-banner
onboarding
onboarding-tasks
pattern-toolkit-full-composability
product-custom-fields
remote-inbox-notifications
remote-free-extensions
payment-gateway-suggestions
printful
shipping-label-banner
subscriptions
store-alerts
transient-notices
woo-mobile-welcome
wc-pay-promotion
wc-pay-welcome-page
launch-your-store

Disabled Features: product-data-views
experimental-blocks
experimental-iapi-runtime
coming-soon-newsletter-template
minified-js
product-pre-publish-modal
products-catalog-api
settings
async-product-editor-category-field
product-editor-template-system
use-wp-horizon
rest-api-v4

Daily Cron: ❌ Not scheduled
Options: ✔
Notes: 61
Onboarding: completed

### Action Scheduler ###

Canceled: 1
Oldest: 2026-02-27 08:36:48 +0000
Newest: 2026-02-27 08:36:48 +0000

Complete: 144
Oldest: 2026-02-27 08:35:23 +0000
Newest: 2026-03-03 12:32:41 +0000

Failed: 3
Oldest: 2026-02-27 08:48:02 +0000
Newest: 2026-03-01 13:10:39 +0000

Pending: 14
Oldest: 2026-03-03 12:35:14 +0000
Newest: 2026-03-15 08:18:55 +0000


### Status report information ###

Generated at: 2026-03-03 12:33:05 +00:00

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions