Shopify Sticky Add to Cart Generator
A slim buy bar that appears once a shopper scrolls past your main Add to cart button.
Your details
Your section file (sections/sticky-add-to-cart.liquid)
{%- comment -%}
Sticky add-to-cart bar. Appears once the button matching the watch selector scrolls out of view.
Uses Shopify's {% raw %}{% form 'product', product %}{% endraw %}, so it submits like your theme's own form.
{%- endcomment -%}
{%- style -%}
.ea-stickycart{position:fixed;left:0;right:0;bottom:0;z-index:20;background:{{ section.settings.bg }};color:{{ section.settings.fg }};border-top:1px solid rgba(0,0,0,.1);box-shadow:0 -4px 16px rgba(0,0,0,.08)}
.ea-stickycart[hidden]{display:none}
.ea-stickycart__inner{max-width:1000px;margin:0 auto;display:flex;align-items:center;gap:.75rem;padding:.6rem 1rem}
.ea-stickycart__img{width:40px;height:40px;object-fit:cover;border-radius:6px;flex-shrink:0}
.ea-stickycart__info{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.ea-stickycart__title{font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ea-stickycart__price{font-size:12px;opacity:.75}
.ea-stickycart__form{display:flex;align-items:center;gap:.5rem;flex-shrink:0}
.ea-stickycart__variants,.ea-stickycart__qty{font:inherit;padding:.4em .5em;border:1px solid #ccc;border-radius:6px;max-width:130px}
.ea-stickycart__qty{width:56px}
.ea-stickycart__btn{padding:.6em 1.1em;border-radius:6px;background:{{ section.settings.fg }};color:{{ section.settings.bg }};border:0;font:inherit;font-weight:600;cursor:pointer;white-space:nowrap}
@media (max-width:749px){.ea-stickycart__title{display:none}}
{%- endstyle -%}
<ea-sticky-cart class="ea-stickycart" data-watch=".product-form__submit, [name='add'], .product__add-to-cart, .single_add_to_cart_button" data-mobile-only="false" hidden>
<div class="ea-stickycart__inner">
{%- if product.featured_media -%}
<img class="ea-stickycart__img" src="{{ product.featured_media | image_url: width: 80 }}" alt="" width="40" height="40" loading="lazy">
{%- endif -%}
<div class="ea-stickycart__info">
<span class="ea-stickycart__title">{{ product.title | escape }}</span>
<span class="ea-stickycart__price">{{ product.selected_or_first_available_variant.price | money }}</span>
</div>
{%- form 'product', product, class: 'ea-stickycart__form' -%}
{%- if product.variants.size > 1 -%}
<select name="id" class="ea-stickycart__variants" aria-label="Variant">
{%- for variant in product.variants -%}
<option value="{{ variant.id }}"{% if variant == product.selected_or_first_available_variant %} selected{% endif %}{% unless variant.available %} disabled{% endunless %}>{{ variant.title | escape }}{% unless variant.available %} - Sold out{% endunless %}</option>
{%- endfor -%}
</select>
{%- else -%}
<input type="hidden" name="id" value="{{ product.selected_or_first_available_variant.id }}">
{%- endif -%}
<input type="number" name="quantity" value="1" min="1" class="ea-stickycart__qty" aria-label="Quantity">
<button type="submit" class="ea-stickycart__btn">Add to cart</button>
{%- endform -%}
</div>
</ea-sticky-cart>
<script>
if (!customElements.get('ea-sticky-cart')) {
customElements.define('ea-sticky-cart', class extends HTMLElement {
connectedCallback() {
if (this.dataset.mobileOnly === 'true' && window.matchMedia('(min-width: 750px)').matches) return;
var target = document.querySelector(this.dataset.watch);
if (!target) return;
var self = this;
var observer = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) { self.hidden = entry.isIntersecting; });
});
observer.observe(target);
}
});
}
</script>
{% schema %}
{
"name": "Sticky add to cart",
"tag": "section",
"class": "ea-sticky-cart-section",
"settings": [
{
"type": "color",
"id": "bg",
"label": "Background",
"default": "#ffffff"
},
{
"type": "color",
"id": "fg",
"label": "Text color",
"default": "#1a1a1a"
}
],
"presets": [
{
"name": "Sticky add to cart"
}
]
}
{% endschema %}
To install: in Shopify admin go to Online Store → Themes, click … next to your theme → Edit code. Under Sections choose Add a new section, name it as shown above, replace the contents with this code and save. Then open Customize and add the section where you want it. Try it on a duplicate of your theme first. It stays hidden until the scroll trigger fires, so you can place it anywhere in the template.
If the bar never appears, your theme's Add to cart button doesn't match the watch selector. Inspect the button's HTML and update the selector field.
The price shown is set when the page loads. If a shopper picks a different variant here, the price isn't re-fetched live; check it at checkout.
Live preview
A self-contained mini buy box
This watches for the moment your real add-to-cart button scrolls out of view (using an IntersectionObserver, so it's cheap on scroll performance) and shows a slim bar with the product's image, title, price, a variant picker if it has more than one, and its own Add to cart button.
It uses Shopify's own {% form 'product', product %} tag, so it submits exactly the way your theme's real form does, with the correct hidden variant field, and works with quantity rules, selling plans and discounts the same as any other add-to-cart form.
Adding it to your theme
- 01
Add the section
Online Store → Themes → Edit code → Sections → Add a new section named
sticky-add-to-cart, paste the code, then add it anywhere in your product template in Customize (it stays hidden until the scroll trigger fires). - 02
Check the watch selector
It watches for your theme's real add-to-cart button using a CSS selector. Open your product page, find your button's class or
name="add"attribute, and adjust the field if the default doesn't match.
Questions people ask
The sticky bar never appears. What's wrong?
Your theme's add-to-cart button probably doesn't match the default watch selector. Inspect the button's HTML and update the selector field to match its class or attributes exactly.
Can I show it only on mobile?
Yes, turn on Mobile only; on desktop the bar stays hidden even after scrolling past the button.
Does it work with products that have a lot of variants?
Yes, it renders a native <select> for variants, which stays usable at any count. It won't replicate a theme's custom swatch or button-style picker.
Will it show the sale price if the product is discounted?
Yes, it reads product.price and, when set, shows compare_at_price struck through, the same as a normal price display.
Related tools
Last reviewed 30 September 2026.
