Add Scrolling Discount Text Or Custom Glassy Badges On Shopify Collection Pages

Saif - Saif

Why Add A Scrolling Discount Or Custom Badge?

Your Shopify collection pages are prime real estate. If a product is on sale, low in stock, or deserves attention — show it. But Shopify doesn’t offer native badge options. A scrolling badge or dynamic discount label makes deals visible, adds urgency, and improves click-through without bloated apps.

⚠️ Heads-up Before You Start

Editing your Shopify theme code requires a basic understanding of HTML, CSS, and JavaScript. Always duplicate your theme to create a backup before making any changes.

Step 1: Add Custom Metafield For Badge Text

From your Shopify admin:

  1. Go to → Settings → Metafields and metaobjects → Products
  2. Click Add definition for creating metafields:
    • Name: Scrolling Badge Text
    • Select type: Single line text
    • Enable Storefronts API access: On
  3. Then open any product → Scroll to Metafields
  4. Add text like: 🔥 Limited Time Offer or 💸 10% Off - Today Only

Step 2: Create A Snippet

In your theme:

  • Go to Online Store → Themes → Edit code
  • Under the Snippets folder, create a New file
  • Name it: a-sale-badge-snippet.liquid
  • Add the following code and Save it
Copy

<style>
.card-wrapper,
.product-card,
.product-media,
.grid__item {
  position: relative;
}

.xlr_scrolling-badge {
  position: absolute;
  bottom: 0;
  width: 100%;
  overflow: hidden;
  white-space: nowrap;
  z-index: 5;
}

.xlr_scroll-track {
  display: flex;
  white-space: nowrap;
  will-change: transform;
  gap: 10px;
}

.xlr_scroll-content {
  display: flex;
}

.xlr_scroll-content span {
  display: inline-block;
  padding: 4px 12px;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #fff;
  background-color: rgba(0, 0, 0, 0.4);
  border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: 9999px;
  line-height: 1.2;
  margin: 2px;
  white-space: nowrap;
  -webkit-backdrop-filter: blur(6px) saturate(120%);
  backdrop-filter: blur(6px) saturate(120%);
}

@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))) {
  .badge {
    background-color: rgba(0, 0, 0, 0.2);
  }
}

@media (max-width: 749px) {
  .xlr_scroll-content span {
    padding: 3px 8px;
    font-size: 10px;
  }

  .xlr_scrolling-badge {
    max-width: 100%;
    margin: 0 auto;
    left: 0;
    right: 0;
    padding: 0;
    bottom: 4px;
  }

  .xlr_scroll-track {
    gap: 6px;
    animation: xlr-scroll 15s linear infinite;
  }
}

@media (max-width: 480px) {
  .xlr_scroll-content span {
    padding: 2px 6px;
    font-size: 9px;
  }

  .xlr_scrolling-badge {
    bottom: 2px;
  }

  .xlr_scroll-track {
    gap: 4px;
    animation: xlr-scroll 20s linear infinite;
  }
}
</style>

{% assign display_product = card_product | default: product %}

{% if display_product %}
  {% assign metafield_text = display_product.metafields.custom.scrolling_badge_text %}

  {% if metafield_text != blank %}
    {% assign badge_text = metafield_text %}
  {% elsif display_product.compare_at_price > display_product.price %}
    {% assign discount_percentage = display_product.compare_at_price
      | minus: display_product.price
      | times: 100.0
      | divided_by: display_product.compare_at_price
      | round %}
    {% assign badge_text = "🔥 Sale " | append: discount_percentage | append: "% OFF" %}
  {% endif %}

  {% if badge_text %}
    <div class="xlr_scrolling-badge">
      <div class="xlr_scroll-track">
        <div class="xlr_scroll-content">
          <span>{{ badge_text }}</span>
        </div>
      </div>
    </div>
  {% endif %}
{% endif %}

<script>
  document.addEventListener('DOMContentLoaded', function () {
    document.querySelectorAll('.xlr_scroll-track').forEach(track => {
      const content = track.querySelector('.xlr_scroll-content');
      const clone = content.cloneNode(true);
      track.appendChild(clone);
  
      let speed = window.innerWidth < 750 ? 0.3 : 0.6;
      let x = 0;
  
      function animate() {
        x -= speed;
        if (x <= -content.offsetWidth) x = 0;
        track.style.transform = `translateX(${x}px)`;
        requestAnimationFrame(animate);
      }
      animate();
    });
  });
</script>

Step 3: Add Snippet To Your Collection Grid Items

In the theme edit code editor Open:

  • Global search by pressing Ctrl+Shift+F
  • Write badge text into the search field
  • Identify the .liquid file(s) where the badge appears
  • sections/main-collection-product-grid.liquid or
  • snippets/card-product.liquid (based on your theme)
  • Inside the file, look for the main product wrapper badge
  • It usually starts with: <div class="card-wrapper">
  • Delete the old badge code if it’s already there
  • For example: <div class="card__badge">
  • Replace it with this line:
Copy

{% render 'a-sale-badge-snippet', product: product %}
  • Save and preview

Real-World Insight

Brands like FashionNova or allbirds use dynamic labels like "🔥 Trending" or "💥 Almost Gone" to catch the shopper’s eye and push urgency. These small visual cues often lift conversions by 10–18% — especially on mobile.

Final Thoughts

Product badges don’t just look good — they make your deals obvious. With this quick Shopify Liquid snippet, you can skip the apps, add a scrolling discount or label, and drive more clicks right from the collection grid.

Back to blog