Product page Free
Sticky add-to-cart bar
A slim bar that slides in with product title, price and a buy button once the main form scrolls out of view.
<div id="sticky-atc" class="sticky-atc" hidden>
<div class="sticky-atc__info">
<span class="sticky-atc__title">{{ product.title }}</span>
<span class="sticky-atc__price">{{ product.selected_or_first_available_variant.price | money }}</span>
</div>
<button type="submit" form="product-form-{{ section.id }}" class="sticky-atc__btn"
{% unless product.selected_or_first_available_variant.available %}disabled{% endunless %}>
{% if product.selected_or_first_available_variant.available %}Add to cart{% else %}Sold out{% endif %}
</button>
</div>
<style>
.sticky-atc{position:fixed;left:0;right:0;bottom:0;z-index:50;display:flex;
align-items:center;justify-content:space-between;gap:12px;padding:10px 16px;
background:#fff;border-top:1px solid #e2e2e2;box-shadow:0 -2px 10px rgba(0,0,0,.06)}
.sticky-atc__info{display:flex;flex-direction:column;font-size:13px}
.sticky-atc__title{font-weight:600;max-width:55vw;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sticky-atc__btn{padding:12px 22px;border:0;border-radius:6px;background:#111;color:#fff;font-weight:600;cursor:pointer}
.sticky-atc__btn:disabled{opacity:.5;cursor:not-allowed}
</style>
<script>
(function(){
var bar = document.getElementById('sticky-atc');
var form = document.getElementById('product-form-{{ section.id }}');
if(!bar || !form) return;
var io = new IntersectionObserver(function(entries){
bar.hidden = entries[0].isIntersecting;
});
io.observe(form);
})();
</script>
Keeps the buy button one tap away on long mobile product pages, which lifts add-to-cart rate. Paste into main-product.liquid, inside the product section so section.id resolves.
Notes
- Assumes your product form id is
product-form-{{ section.id }}(Dawn and most OS 2.0 themes). Check your form’s real id and adjust if different. - The bar hides itself while the main form is visible, so there is no duplicate button on screen.
hidden+IntersectionObservermeans no scroll listeners and no layout jank.