skills/storefront-ui/responsive-storefront/SKILL.md
Build a mobile-first storefront with thumb-friendly navigation, sticky add-to-cart buttons, and touch-optimized components for high mobile conversion
npx skillsauth add finsilabs/awesome-ecommerce-skills responsive-storefrontInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Apply mobile-first responsive design patterns to a commerce storefront so that the shopping experience is fast and usable on phones, where the majority of commerce traffic originates. Key patterns include thumb-zone aware layouts, a sticky buy bar that appears on scroll, tap-target sizing, and responsive product grids that reflow without horizontal scrolling.
| Platform | Recommended Approach | Why |
|----------|---------------------|-----|
| Shopify | Use a mobile-first OS2.0 theme (Dawn, Sense, Craft) — all are responsive by default; configure mobile layout in Theme Editor | Dawn scores 90+ on mobile PageSpeed out of the box; the Theme Editor exposes mobile-specific layout controls |
| WooCommerce | Use a mobile-first WooCommerce theme (Astra, Kadence, or Flatsome) — all include responsive breakpoints and mobile cart drawer built in | Astra and Kadence score well on Core Web Vitals; Flatsome has built-in sticky header and mobile menu without plugins |
| BigCommerce | Use Cornerstone theme which is mobile-first by design; configure breakpoints in Theme Editor | Cornerstone is BigCommerce's reference theme and passes Google's mobile usability tests |
| Custom / Headless | Write mobile-first CSS with min-width media queries and build a responsive product grid, sticky buy bar, and bottom-sheet cart drawer | Full control over all breakpoints and touch interactions; see patterns below |
Theme Editor mobile configuration:
Testing mobile performance:
Astra theme mobile configuration:
Kadence theme mobile configuration:
Flatsome theme:
Cornerstone mobile configuration:
Mobile-first CSS foundations:
/* tokens.css */
:root {
--space-sm: 0.5rem;
--space-md: 1rem;
--space-lg: 1.5rem;
--touch-target: 44px; /* WCAG 2.5.5 minimum tap target */
--content-max-width: 1200px;
}
/* Breakpoints: sm=640px, md=768px, lg=1024px */
/* Write base styles for mobile, add min-width queries for larger screens */
Responsive product grid (auto-fills columns based on available width):
.product-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(160px, 100%), 1fr));
gap: var(--space-md);
padding: var(--space-md);
}
@media (min-width: 640px) {
.product-grid { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
}
@media (min-width: 1024px) {
.product-grid { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--space-lg); }
}
/* Minimum 44px touch target on product card CTA */
.product-card__cta { min-height: var(--touch-target); display: flex; align-items: center; }
Sticky buy bar — appears when primary Add to Cart scrolls out of view:
export function StickyBuyBar({ product, onAddToCart }) {
const [visible, setVisible] = useState(false);
useEffect(() => {
const primaryBtn = document.getElementById('main-add-to-cart');
if (!primaryBtn) return;
const obs = new IntersectionObserver(([e]) => setVisible(!e.isIntersecting));
obs.observe(primaryBtn);
return () => obs.disconnect();
}, []);
return (
<div className={`sticky-buy-bar ${visible ? 'visible' : ''}`} aria-hidden={!visible}>
<img src={product.image} alt="" width="40" height="40" />
<span>{product.name}</span>
<span>${product.price}</span>
<button onClick={onAddToCart} tabIndex={visible ? 0 : -1}>Add to Cart</button>
</div>
);
}
.sticky-buy-bar {
position: fixed; bottom: 0; left: 0; right: 0;
background: #fff; border-top: 1px solid #e2e8f0;
transform: translateY(100%); transition: transform 0.2s ease; z-index: 50;
padding-bottom: env(safe-area-inset-bottom); /* iPhone home indicator */
display: flex; align-items: center; gap: 0.5rem; padding: 0.75rem 1rem;
}
.sticky-buy-bar.visible { transform: translateY(0); }
Mobile cart drawer (bottom sheet pattern):
.cart-drawer {
position: fixed; right: 0; top: 0; bottom: 0;
width: min(400px, 100vw); background: #fff;
transform: translateX(100%); transition: transform 0.3s ease;
overflow-y: auto; overscroll-behavior: contain;
}
@media (max-width: 640px) {
.cart-drawer {
top: auto; width: 100vw; height: 85vh;
transform: translateY(100%); border-radius: 16px 16px 0 0;
}
.cart-drawer.open { transform: translateY(0); }
}
.cart-drawer.open { transform: translateX(0); }
/* Checkout button stays within thumb reach */
.cart-checkout-btn {
position: sticky; bottom: 0; background: #fff;
padding: var(--space-md);
padding-bottom: calc(var(--space-md) + env(safe-area-inset-bottom));
}
Global 44px touch targets:
button, a, input[type="checkbox"], input[type="radio"], select, [role="button"] {
min-height: var(--touch-target);
min-width: var(--touch-target);
}
min-width media queries to enlarge; the reverse approach leads to specificity conflictsenv(safe-area-inset-bottom) — required for iPhone notch/home indicator; without it, bottom-fixed buttons are obscuredoverscroll-behavior: contain on scroll containers — prevents body scroll from leaking when users swipe in the cart drawer100dvh instead of 100vh on full-screen elements — iOS Safari's dynamic toolbar causes 100vh to include the toolbar height, causing overflow<body> — prevents iOS Safari from auto-zooming on input focus| Problem | Solution |
|---------|----------|
| Sticky buy bar obscures footer or checkout button | Hide the bar when the footer or checkout button enters the viewport using IntersectionObserver |
| iOS Safari layout jumps when toolbar appears | Use 100dvh (dynamic viewport height) instead of 100vh; fall back with @supports (height: 100dvh) |
| Font too small to read without pinch-zooming | Set font-size: 1rem (16px) on body; never set it lower on mobile |
| Cart drawer body scroll | Apply overflow: hidden on <body> when drawer is open; restore on close |
| Product images load slowly on mobile | Specify width and height attributes to prevent layout shift; use loading="lazy" for below-fold images |
tools
Let shoppers save products to a wishlist, share it with friends, and get notified when saved items come back in stock or drop in price
development
Build a themeable storefront with design tokens and CSS custom properties that supports white-labeling, multi-brand variants, and dark mode
development
Speed up product discovery with instant search suggestions, fuzzy typo matching, and category-aware results powered by Algolia or Elasticsearch
data-ai
Show shoppers the products they recently browsed using browser storage so they can easily pick up where they left off on your store