LiquidBoost
← Back to library
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 + IntersectionObserver means no scroll listeners and no layout jank.