# Size, color and variant pickers AI agents can use

> Build size and color pickers AI agents can use: named options, a readable selected state, clear sold-out options, variant URLs and prices that update.

Published October 9, 2026 by Ghost Agent Labs · Navigability · https://ghostagentlab.com/articles/variant-pickers-ai-agents/

## Key takeaways

- Choosing a size or color is where many product pages lose AI agents, leading to abandoned tasks or wrong items in the cart.
- Agents can't read color swatches with no name, a selection shown only by a border, or sold-out sizes that are merely faded.
- Ask your developer or theme provider to rebuild swatches as named radio buttons styled the same way, the simplest and most reliable picker.

Ask an AI agent to buy "the navy jacket in a medium" and the hard part isn't finding the jacket. It's choosing navy and medium. Size, color and other variant pickers are where many product pages lose agents: the swatch has no name, the selected size looks different but reads the same, and the sold-out option can still be clicked. This guide covers how to build variant pickers AI agents can use without guessing.

## Why variant pickers trip agents up

A person sees a row of colored circles, notices a thicker border around one, and sees a crossed-out "XL". A browser agent mostly reads the page's structure: each control's role, its name and its state. If the swatch is a `<div>` with a background color, it has no role and no name. If "selected" is shown only with a border, there's no state to read. The agent may click the right circle by chance, click the wrong one, or not realize there's a choice to make at all.

The cost is direct. An agent that can't choose a size either gives up and tells the shopper it couldn't complete the task, or adds the wrong item to the cart. Both are lost or returned orders. And the same problems affect shoppers who use a keyboard or a screen reader, so fixing them helps people too.

Agents need four things from a picker: what each option is called, which one is chosen, which ones can't be bought, and confirmation that the page changed after they chose.

## 1. Make each option a real control with a name

The simplest, most reliable picker is a group of native radio buttons. Only one option can be chosen, the browser handles the keyboard, and every agent knows what a radio button is. You can style the label to look like a swatch or a size box.

```
<fieldset>
  <legend>Color</legend>
  <label class="swatch">
    <input type="radio" name="color" value="navy" checked>
    <span class="dot" style="background:#1f2a44" aria-hidden="true"></span>
    Navy
  </label>
  <label class="swatch">
    <input type="radio" name="color" value="olive">
    <span class="dot" style="background:#5b5e3a" aria-hidden="true"></span>
    Olive
  </label>
</fieldset>
```

- **Name every option.** The color name, such as "Navy", should be the control's name, as visible text or at least an `aria-label`. A hex code or an image file name isn't a name.
- **Name the group.** A `<fieldset>` with a `<legend>` ("Color", "Size") tells the agent what the choice is about.
- **Use the words shoppers use.** "Medium" or "M" is fine. An internal code like "SZ-03" isn't. If sizes need context ("UK 8 / US 4"), put it in the name.
- **Keep swatch images as decoration.** If a swatch is a photo of the fabric, give the control the color name and the image empty `alt=""`, so the name isn't read twice.

If your design uses buttons rather than radios, that works too, as long as they are real `<button>` elements with names. AgentScore's checks that buttons and links have names, and that clickable things are real buttons and links, look for exactly these problems, though they run on your home page. A product page needs the same care.

## 2. Show which option is selected, in the code

Selection is the detail most often shown only visually. Radio buttons report it for free through `checked`. Custom buttons have to say it themselves:

```
<div role="group" aria-labelledby="size-label">
  <span id="size-label">Size</span>
  <button type="button" aria-pressed="false">S</button>
  <button type="button" aria-pressed="true">M</button>
  <button type="button" aria-pressed="false">L</button>
</div>
```

- Use `aria-pressed="true"` on the chosen button and `"false"` on the others, and update them when the choice changes.
- Alternatively, use `role="radio"` with `aria-checked` inside a `role="radiogroup"`. It's more work to get the keyboard right, which is why native radios are usually the better choice.
- Repeat the current choice in text near the picker ("Color: Navy"). It gives agents and people a plain confirmation.

## 3. Mark out-of-stock options clearly

Hiding a sold-out size makes the shopper wonder whether it ever existed. Showing it with only a strike-through or faded color leaves an agent free to choose it, then fail at "Add to cart". Say it in words and in the control's state.

| Approach | What an agent sees |
| --- | --- |
| Option faded or struck through with CSS only | A normal option it can pick |
| Option removed from the page | No sign the size exists |
| Native radio with `disabled` and "XL, sold out" in the label | An option that can't be chosen, and why |
| Button with `aria-disabled="true"` and "XL, sold out" in its name | The same, and it stays reachable by keyboard |

If you offer back-in-stock alerts, make that a separate, named button ("Email me when XL is back"), so an agent can tell it apart from buying.

## 4. Give each variant its own URL

Many AI assistants fetch pages rather than click through them. They can't press a swatch, but they can open a link. If each variant has its own address, an assistant can point a shopper straight to "the navy jacket in medium", and a browser agent can recover if a click doesn't take.

```
https://northwind.example/products/field-jacket?color=navy&size=m
https://northwind.example/products/field-jacket?variant=40318
```

- Update the address when a shopper picks an option, so the current view always has a link.
- Make the URL load with that variant already selected, its price and stock shown, when opened fresh.
- Point the canonical URL at the main product page unless variants are really separate products. See [canonical URLs and duplicate pages](https://ghostagentlab.com/articles/canonical-urls-ai-agents/).

## 5. Update price, stock and photos where agents can see it

Choosing a larger size or a different material often changes the price. If the new price only appears in an image, or changes quietly in a corner of the page, an agent may report the old one to the shopper.

- Show price and availability as text, and update them when the variant changes.
- Wrap the price and stock line in a live region (`aria-live="polite"`), so the change is announced to assistive tech and is easier for agents reading the page structure to notice.
- Keep "Add to cart" a real button with the same name throughout. If it's disabled until a size is chosen, say so next to it: "Choose a size". AgentScore's add-to-cart check accepts a button that's disabled until options are chosen, because agents can handle that, as long as they can tell what's missing.

## 6. Describe variants in your structured data

Agents that read your page HTML rather than click it rely on structured data for the full list of options. schema.org has a [ProductGroup](https://schema.org/ProductGroup) type for this: one group, with `variesBy` naming the dimensions and `hasVariant` listing each variant as a `Product` with its own offer. Google documents the pattern in its [product variant structured data guide](https://developers.google.com/search/docs/appearance/structured-data/product-variants).

```
{
  "@context": "https://schema.org",
  "@type": "ProductGroup",
  "name": "Field jacket",
  "productGroupID": "FJ-100",
  "variesBy": ["https://schema.org/color", "https://schema.org/size"],
  "hasVariant": [{
    "@type": "Product",
    "sku": "FJ-100-NAV-M",
    "color": "Navy",
    "size": "M",
    "url": "https://northwind.example/products/field-jacket?variant=40318",
    "offers": {
      "@type": "Offer",
      "price": "189.00",
      "priceCurrency": "USD",
      "availability": "https://schema.org/InStock"
    }
  }]
}
```

AgentScore's "Product pages give price and stock in a form agents can read" check reads offers inside `ProductGroup` and `hasVariant`, as well as on a plain `Product`. For more on the fields that matter, see [product data AI shopping agents can read](https://ghostagentlab.com/articles/structured-data-ai-shopping-agents/) and [prices AI agents can read](https://ghostagentlab.com/articles/machine-readable-prices/).

## How to test your pickers

1. **Use only the keyboard.** Tab to the color and size pickers, choose an option, and add to cart. If you can't, many agents can't either.
2. **Inspect the accessibility tree.** In Chrome's developer tools, the Accessibility pane should show each option as a radio or button with a name like "Navy", and its checked or pressed state.
3. **Pick a sold-out size.** The page should tell you, in words, before you reach the cart.
4. **Copy the URL after choosing.** Open it in a private window. The same variant should be selected.
5. **Run a journey.** AgentScore's free scan doesn't choose options on your product pages, so the best test is an agent trying it. A [Ghost Agent](https://ghostagentlab.com/ghost-agent/) can run "find the field jacket, choose navy in medium, add it to the cart" on a schedule and replay each step when it gets stuck. See [testing key journeys with AI agents](https://ghostagentlab.com/articles/test-journeys-with-ai-agents/).

> **Where to start.** If your theme uses `<div>` swatches, switching to labelled radio buttons styled the same way usually fixes naming, selection state and keyboard use in one change. Ask your developer or theme provider for that first.

For the rest of the page's controls, see [buttons, links and forms agents can use](https://ghostagentlab.com/articles/agent-friendly-buttons-forms/). For what happens after "Add to cart", see [carts AI agents can manage](https://ghostagentlab.com/articles/cart-ai-agents/).

## Sources and further reading

- [Radio group pattern (ARIA Authoring Practices Guide)](https://www.w3.org/WAI/ARIA/apg/patterns/radio/) (W3C)
- [Button pattern (ARIA Authoring Practices Guide)](https://www.w3.org/WAI/ARIA/apg/patterns/button/) (W3C)
- [ProductGroup](https://schema.org/ProductGroup) (schema.org)
- [Product variant structured data](https://developers.google.com/search/docs/appearance/structured-data/product-variants) (Google Search Central)
