benjaminsehl/liquid-skills/liquid-theme-a11y
Claude Code and agent skill by benjaminsehl/liquid-skills
- community
Checking that the SKILL.md file is still in the repository.
Implement WCAG 2.2 accessibility patterns in Shopify Liquid themes. Covers e-commerce-specific components including product cards, carousels, cart drawers, price display, forms, filters, and modals. Use when building accessible theme components, fixing accessibility issues, or reviewing ARIA patterns in .liquid files.
Install
npx vskill@latest install benjaminsehl/liquid-skills/liquid-theme-a11ySKILL.md
Accessibility for Shopify Liquid Themes
Core Principle
Every interactive component must work with keyboard only, screen readers, and reduced-motion preferences. Start with semantic HTML — add ARIA only when native semantics are insufficient.
Decision Table: Which Pattern?
| Component | HTML Element | ARIA Pattern | Reference | |
|---|---|---|---|---|
| Expandable content | <details>/<summary> | None needed | Accordion | |
| Modal/dialog | <dialog> | aria-modal="true" | Modal | |
| Tooltip/popup | [popover] attribute | role="tooltip" fallback | Tooltip | |
| Dropdown menu | <nav> + <ul> | aria-expanded on triggers | Navigation | |
| Tab interface | <div> | role="tablist/tab/tabpanel" | Tabs | |
| Carousel/slider | <div> | role="region" + aria-roledescription | Carousel | |
| Product card | <article> | aria-labelledby | Product card | |
| Form | <form> | aria-invalid, aria-describedby | Forms | |
| Cart drawer | <dialog> | Focus trap | Cart drawer | |
| Price display | <span> | aria-label for context | Prices | |
| Filters | <form> + <fieldset> | aria-expanded for disclosures | Filters |
Page Structure
Landmarks
- Single
<header>,<main>,<footer>per page - Multiple
<nav>elements must have distinctaria-label - All content must live inside a landmark
Skip Link
Headings
- One
<h1>per page, never skip levels (h1 → h3) - Use real heading elements, not styled divs
- Template:
<h1>is typically the page/product title
Focus Management
Focus Indicators
- Minimum 3:1 contrast ratio for focus indicators
- Use
:focus-visible(not:focus) to avoid showing on click - Never
outline: nonewithout a visible replacement
Focus Trapping (Modals/Drawers)
- Trap focus inside modals, drawers, and dialogs
- Return focus to trigger element on close
- First focusable element gets focus on open
- Query all focusable elements:
a[href], button:not([disabled]), input:not([disabled]), select, textarea, [tabindex]:not([tabindex="-1"])
See focus and keyboard patterns for full FocusTrap implementation.
Component Patterns
Product Card
Rules:
- Single tab stop per card (the main link)
tabindex="-1"on mouse-only shortcuts (quick add)aria-labelledbyon<article>pointing to the title- Descriptive alt text on images; empty
alt=""if decorative
Carousel
Rules:
- Auto-rotation minimum 5 seconds, pause on hover/focus
- Play/pause button required for auto-rotating carousels
aria-live="polite"on slide container (set to"off"during auto-rotation)aria-hidden="true"on inactive slides- Each slide:
role="group"+aria-roledescription="slide"
Modal
Rules:
- Use native
<dialog>element aria-labelledbypointing to the title- Close on Escape key (native with
<dialog>) - Focus first interactive element on open
- Return focus to trigger on close
Cart Drawer
Same as modal pattern but with additional:
- Live region for cart count updates:
<span aria-live="polite" aria-atomic="true"> - Clear "remove item" buttons with
aria-label="{{ 'cart.remove_item' | t: title: item.title }}" - Quantity inputs with associated labels
Forms
Rules:
- Every input has a visible
<label>with matchingfor/id - Use
<fieldset>/<legend>for radio/checkbox groups - Error messages:
role="alert"+aria-describedbylinking to input aria-invalid="true"on invalid inputsautocompleteattributes on common fields- Required fields:
required+aria-required="true"+ visual indicator
Product Filters
Price Display
- Use
aria-labelto provide full price context (sale vs. original) aria-hidden="true"on the visual strikethrough to avoid duplicate reading
Accordion
Native <details>/<summary> provides keyboard and screen reader support automatically.
Tabs
- Arrow keys navigate between tabs (left/right)
- Only active tab has
tabindex="0", others-1
Dropdown Navigation
Tooltip
Mobile Accessibility
- Touch targets: minimum 44x44px, 8px spacing between targets
- No orientation lock: never restrict to portrait/landscape
- No hover-only content: everything accessible via tap
- Use
dvhinstead ofvhfor mobile viewport units
Animation & Motion
- No flashing above 3 times per second
- Auto-playing animations need pause/stop controls
- Meaningful animations only — don't animate for decoration
Visually Hidden Utility
Use for screen-reader-only content like labels and descriptions.
Color Contrast
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/liquid-theme-a11y/SKILL.md
Popularity
- Repository stars
- 120
- Repository forks
- 15
- 7-day trend score
- 24
Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 22 Mar 2026, 7 months ago.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/benjaminsehl/liquid-skills/liquid-theme-a11y)