Behavior
On this page

AndOr widgets use real HTML controls, labels and live regions, so they work with a keyboard and a screen reader. This page lists what each widget does, so you keep it when you restyle.

Per widget

Sale price

  • The host has aria-live="polite" and aria-atomic="true", set in Liquid. It announces only when the sale amount changes, never at page load.
  • Both amounts carry a visually hidden label, “Regular price” and “Sale price”.

Savings badge and code chips

  • A visually hidden “Discount” label leads the badge.
  • A code is a real <button>. Its aria-label is the full sentence, for example “Copy discount code AUTUMN15”.
  • Copying confirms in two ways: the button text changes to “Copied”, and a role="status" element announces it. Focus stays on the button.
  • The applied check mark is aria-hidden="true". The words say “applied”, so the state is not shown by color alone.

Countdown

  • role="timer", and no aria-live on purpose. A live region would announce every tick. A timer is read when the shopper moves to it.
  • A visually hidden “Sale countdown” label names it.

Offers list

  • The heading level is a block setting (default h3, or plain text).
  • The list is a real <ul>, linked to its heading with aria-labelledby.
  • Codes are real buttons, the same as on the badge.

Volume table and volume picker

  • The table’s current row has aria-current="true".
  • The picker cards are a radio group (role="radiogroup", cards with role="radio" and aria-checked). One card holds the tab stop, the arrow keys move the choice, and Space or Enter picks.
  • The List, Mini buttons and Boxes layouts use real radio inputs in a <fieldset>, so Tab and the arrow keys work natively.
  • The line under the picker (“Add 1 more and get 15% off”) is a polite live region.

Goal bar

  • The track has role="progressbar".
  • The sentence is a polite live region, so a screen reader hears the new amount after a cart change.

Discount callout and collection banner

  • Both have role="note".

Cart claim rows and gift slot

  • Claim is a real button named “Claim ”. A variant choice is a labelled select.
  • While a gift is being added for the shopper, the box has aria-busy="true".
  • After a redraw removes the button the shopper pressed, focus moves to the box’s title (tabindex="-1"), so the next Tab starts there. The title draws no focus outline on purpose. Do not add one back.

Gift chooser

  • A native <dialog> opened with showModal(), so focus is trapped and the page behind it is inert.
  • Each option is a <fieldset> of real radio inputs. Arrow keys move within a group, Tab moves between groups.
  • A sold-out value is disabled, and its accessible name ends with “Sold out”.
  • Escape closes the chooser and leaves the cart drawer open. Focus returns to the button that opened it.

Product card recipes

  • The complete price recipe labels both amounts for screen readers.
  • The volume hint’s info icon is a real <button> with aria-label="Volume pricing" and aria-describedby pointing at the step list. The list shows on hover and on keyboard focus.

Reduced motion

The widget stylesheets that move (the skeleton shimmer, the goal bar fill, the gift chooser sliding up on phones) stop that motion under prefers-reduced-motion: reduce.

Visually hidden text: .andor-vh

.andor-vh is AndOr’s visually hidden class. .andor-price__label and .andor-code__status are aliases of it. It hides labels and status text from sight but keeps them for screen readers.

Caution Do not restyle .andor-vh or its aliases. Removing the clipping prints screen-reader-only text into the page.

When you restyle

  • Check contrast. Target at least 4.5:1 for normal text. The pairs that matter: badge text on badge background, and the sale price, countdown and offers accent on the section background. The shipped default is #ffffff on #c0392b.
  • Keep focus visible. The picker cards show an outline on :focus-visible. Do not remove it.
  • Do not force hidden parts back on. A hidden part is meant to be hidden for everyone, including screen readers.

Next steps

Last updated

Was this page helpful?

No

Questions? Email andor@backtrackhq.com or use the chat in the app.