Skip to content

Accessibility

Platmart Color Swatches ships keyboard navigation, screen reader labels, and non-color state indicators on every storefront swatch. This page describes what the widgets do today, the standards they’re built against, and where the gaps still are. Useful for procurement reviews, accessibility audits, and merchant questions.

  • WCAG 2.1 Level AA as the practice we measure against
  • ADA as it applies to e-commerce in the US
  • EAA / EN 301 549 considerations for European markets

These are targets, not certifications. We haven’t commissioned a third-party audit ourselves, but the practices below were updated based on findings from a WCAG 2.1 AA audit one of our customers commissioned in early 2026. We don’t claim full WCAG conformance. The sections below describe what we do and what we don’t.

The app renders three widget patterns. Their accessibility behavior differs, so it helps to know which one you’re looking at.

  • Product groups - linked-product swatches on product and collection pages. Each swatch navigates to a different product.
  • Variant swatches on product pages - swatches that change the selected variant on the current product without navigating away.
  • Variant swatches on collection cards - swatches that update the card’s image, price, and link to the matching variant.

Product groups (links). Each swatch is a real <a href> and lives in the tab order. Enter activates it. Native links don’t respond to Space, which is standard browser behavior. The “Show more” control under a collapsed list is a real <button> and works with Enter or Space.

Variant swatches on product pages. These render as native <input type="radio"> paired with a <label for="...">. All inputs in one option share a name, so the browser treats them as a single radio group: Tab moves into the group, arrow keys move between values like native radios. The inputs are visually hidden using the screen-reader-only pattern (clip-path: inset(50%), 1px size, opacity: 0) instead of display: none, so they stay in the focus tree. The visible focus ring is painted on the swatch wrapper through a :focus-visible adjacent-sibling selector, so keyboard users see which swatch is focused.

Variant swatches on collection cards. These render as <div role="radio"> inside a role="radiogroup" container labelled with the option name. The group uses roving tabindex - only the active value is in the tab order, so the whole group is one Tab stop. Once focused, Arrow keys move between values (Left/Up back, Right/Down forward, with wraparound), Home and End jump to the ends, and Enter or Space activate. Arrow keys also activate on move, matching native radio behavior.

What’s exposed to assistive technology depends on the widget.

  • Product group links. Container has role="group" with the option name as aria-label. Each link carries an aria-label with the swatch name. Out-of-stock values append “(sold out)” and add aria-disabled="true". The active swatch (the one matching the current product) uses aria-current="page". With tooltips off, a title attribute carries the same name as a fallback.
  • Variant swatches on product pages. Container is role="radiogroup" with the option name as aria-label, so screen readers announce the group’s name on entry. Each radio carries an explicit aria-label with the value name, so swatches with no visible text - one-color, two-color, and image styles - still have a non-empty accessible name. Out-of-stock values append “(sold out)” and add aria-disabled="true". When the option is split into sections, each section renders as its own radiogroup labelled by the section name.
  • Variant swatches on collection cards. Each value is role="radio" with aria-label and aria-checked, inside a role="radiogroup" labelled with the option name. Out-of-stock values append “(sold out)” and add aria-disabled="true". With tooltips off, a title attribute carries the value name. Linked-product variants on cards use <a> with aria-label, aria-disabled, and aria-current="page" instead.
  • Inner swatch images. Variant images, custom images, and image-with-text pills are marked decorative with alt="" and aria-hidden="true", so screen readers don’t double-announce the option name from the surrounding label and the inner image.

The third-party audit mentioned above covered all three swatch surfaces. We haven’t run a separate full screen-reader pass against VoiceOver, NVDA, or TalkBack ourselves, so we don’t claim verified compatibility across every reader. If you’ve tested with a specific reader, share what you found - we’ll take a look.

Each swatch type ships a visible :focus-visible outline (a 2px solid ring, 2px offset), so keyboard users always see which control they’re on regardless of whether the underlying theme strips outlines. On product pages, the outline is painted on the swatch wrapper through the radio’s adjacent-sibling selector, so the visually-hidden radio drives a visible ring on the swatch you actually see.

After variant swatches on product pages re-render (price or inventory updates), focus is restored to the previously focused control. Because the radio inputs stay focusable, that restored focus is visible.

We don’t rely on color alone to indicate state, in line with WCAG 1.4.1 (Use of Color):

  • Selected - the active swatch gets a darker outer ring (box-shadow), not just a color change. Linked-product swatches on the current product also expose aria-current="page", and selectable swatches on collection cards expose aria-checked.
  • Out of stock - shown with a strikethrough, cross-out overlay, or a faded swatch (depending on the merchant’s setting), not just a faded color. The state is also announced to assistive technology: aria-disabled="true" is set on the swatch and “(sold out)” is appended to the accessible name. The suffix is localised and follows the storefront language, with English as the fallback.
  • Hover - reflected in the cursor and, when tooltips are enabled, a tooltip.

Tooltips appear on hover. They’re a visual convenience, not a screen reader feature.

The swatch’s accessible name (via aria-label for links and the collection-card radios, or the associated <label for="..."> for native radios) carries the same text the tooltip shows, so screen reader users get the information through the label whether tooltips are on or off. We don’t wire tooltips through aria-describedby because that would cause assistive tech to announce the same name twice.

When tooltips are off, both product group links and variant swatches on collection cards expose a title attribute as a fallback for browsers that show native tooltips.

Default swatch styles meet WCAG 2.1 AA contrast ratios for text and UI controls (4.5:1 for normal text, 3:1 for large text and UI components).

The swatch colors themselves are values you (the merchant) configure, and the surrounding theme controls page background and text color. The contrast of your custom values against your theme context is your responsibility to verify. If you’re not sure, email support and we’ll review specific cases.

Some things depend on your theme, not the app:

  • Theme-level accessibility - page structure, heading hierarchy, navigation, and focus management outside our widget
  • Theme color contrast - the text and background colors on your storefront are governed by your theme
  • Other apps - bundle apps, page builders, and third-party integrations are responsible for their own UI

If you’ve found something that doesn’t work for assistive technology, tell us. We treat accessibility issues as priority bugs.

Email support@colorswatchesapp.com with:

  • Your store URL
  • The page or screen where the issue happens
  • The assistive technology you’re using (screen reader, keyboard-only, magnifier, etc.)
  • What you expected versus what happened