How to fix nested interactive on Shopify

Remove or restructure focusable elements nested inside interactive controls so that no interactive element contains another focusable child.

Steps for Shopify

  1. In your Shopify Admin go to Online Store → Themes → (your active theme) → Actions → Edit code.
  2. Open the file most likely to contain the offending component. Product cards are typically in snippets/product-card.liquid or snippets/card-product.liquid (Dawn theme). Navigation dropdowns are in snippets/header.liquid or sections/header.liquid.
  3. Search for the outer interactive wrapper (e.g. <a … class="card__inner"> or <button>) and look for any focusable child element nested inside it.
  4. Restructure the Liquid template following the 'sibling' pattern in the code example above: replace the wrapping <a> with a <div>, then add a dedicated <a> for the product title/image and keep the Add to Cart button as a sibling.
  5. Save the file, then preview the theme and tab through the product grid with a keyboard to confirm focus order is correct.
  6. If you use a page-builder app (like Shogun or PageFly), open the page in that app's editor, select the block, and edit its HTML/custom code section directly using the same pattern.
Official Shopify documentation ↗
<!-- ❌ WRONG: <a> wrapping a <button> — invalid nested interactive -->
<a href="/products/widget">
  <img src="widget.jpg" alt="Blue Widget">
  <span>Blue Widget</span>
  <button type="button">Add to Cart</button>  <!-- nested interactive! -->
</a>

<!-- ✅ CORRECT: non-interactive wrapper; link and button are siblings -->
<div class="product-card">
  <!-- Stretch the link to cover the card visually with CSS -->
  <a href="/products/widget" class="card-link">
    <img src="widget.jpg" alt="Blue Widget">
    <span>Blue Widget</span>
  </a>
  <!-- Button sits above the stretched link via z-index -->
  <button type="button" class="add-to-cart">Add to Cart</button>
</div>

<!-- CSS for the "full-card link" pattern -->
<style>
.product-card { position: relative; }
.card-link::after {
  content: '';
  position: absolute;
  inset: 0;          /* covers the full card */
  z-index: 0;
}
.add-to-cart { position: relative; z-index: 1; }
</style>

What is nested interactive?

WCAG Success Criterion 4.1.2 requires that every interactive component on a page has a clear name, role, and value that assistive technologies can understand. A "nested interactive" violation means a clickable or focusable element — like a button, link, or input — contains another focusable element inside it. For example, a product card that is wrapped in a `<a>` tag but also contains a separate "Add to Cart" `<button>` inside it, or a `<button>` that wraps a `<label>` and an `<input>`. HTML does not allow interactive elements to be nested inside other interactive elements — it is invalid markup that breaks predictable keyboard and screen-reader behavior.

Keyboard-only users and screen-reader users (blind shoppers, people with motor disabilities) navigate your store by tabbing through focusable elements. When interactive elements are nested, the browser renders the structure unpredictably: focus may skip the inner element, become trapped, or announce confusing information (e.g. reading an entire product card as one gigantic link). This directly prevents some customers from adding items to their cart, completing checkout, or using navigation menus — losing you real revenue. In many jurisdictions (US ADA, EU EAA, UK PSBAR) inaccessible ecommerce sites expose businesses to legal complaints and lawsuits. Fixing nested interactive elements is one of the most impactful keyboard-accessibility improvements you can make.

See the complete Nested interactive guide for every platform and the full background.

Not sure if your Shopify store has this?

Run a free SEOLZ audit — we’ll find nested interactive and every other issue across your whole site.

Scan my site free

Fix nested interactive on another platform