How to Add Collections Slider in Shopify? Without App [2025]

<style>
  /* Outer section */
  #collections-slider-{{ section.id }} {
    width: 100%;
    text-align: center;
  }
  /* Container for heading & slider */
  #collections-slider-{{ section.id }} .collections-slider-container {
    margin: 0 auto;
  }
  /* Section Heading */
  #collections-slider-{{ section.id }} .section-heading {
    font-size: {% if section.settings.heading_size == 'small' %}24px{% elsif section.settings.heading_size == 'medium' %}32px{% elsif section.settings.heading_size == 'large' %}40px{% endif %};
    text-align: {{ section.settings.heading_alignment }};
    margin-bottom: 20px;
  }
  /* Slider Wrapper */
  #collections-slider-{{ section.id }} .collections-slider-wrapper {
    position: relative;
    overflow: hidden;
  }
  #collections-slider-{{ section.id }} .collections-slider {
    overflow: hidden;
    position: relative;
    width: 100%;
  }
  #collections-slider-{{ section.id }} .slider-track {
    display: flex;
    gap: 15px;
    transition: transform 0.5s ease-in-out;
    will-change: transform;
  }
  /* Desktop: Slide width based on visible_slides */
  #collections-slider-{{ section.id }} .slide {
    flex: 0 0 calc((100% - ({{ section.settings.visible_slides | minus: 1 }} * 15px)) / {{ section.settings.visible_slides }});
    box-sizing: border-box;
    padding: 20px;
    text-align: {{ section.settings.collection_title_alignment }};
    {% if section.settings.card_shadow %}
      box-shadow: 0px 4px 8px rgba(0,0,0,0.2);
    {% endif %}
  }
  /* Mobile: Use visible_mobile setting */
  @media (max-width: 767px) {
    #collections-slider-{{ section.id }} .slide {
      flex: 0 0 calc((100% - ({{ section.settings.visible_mobile | minus: 1 }} * 15px)) / {{ section.settings.visible_mobile }});
    }
  }
  #collections-slider-{{ section.id }} .slide a {
    text-decoration: none;
    color: inherit;
  }
  #collections-slider-{{ section.id }} .collection-image {
    width: 100%;
    object-fit: cover;
    {% case section.settings.card_design %}
      {% when "square" %}
        aspect-ratio: 1 / 1;
      {% when "portrait" %}
        aspect-ratio: 2 / 3;
      {% when "circle" %}
        aspect-ratio: 1 / 1;
        border-radius: 50%;
      {% else %}
        height: auto;
    {% endcase %}
  }
  #collections-slider-{{ section.id }} .collection-title {
    margin-top: 10px;
    font-size: {{ section.settings.collection_title_font_size }}px;
    text-align: {{ section.settings.collection_title_alignment }};
    text-decoration: none;
    {% if section.settings.hide_collection_title %}
      display: none;
    {% else %}
      display: block;
    {% endif %}
  }
  /* Arrow Buttons */
  #collections-slider-{{ section.id }} .arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background: {{ section.settings.arrow_bg_color }};
    color: #fff;
    border: none;
    font-size: 24px;
    padding: 10px 15px;
    cursor: pointer;
    z-index: 10;
    border-radius: {% if section.settings.arrow_shape == 'circle' %}50%{% else %}0{% endif %};

    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0px 0px;
    width: 50px;
    height: 50px;
  }
  #collections-slider-{{ section.id }} .left-arrow {
    left: 10px;
  }
  #collections-slider-{{ section.id }} .right-arrow {
    right: 10px;
  }
</style>

{% assign cloneCount = section.settings.visible_slides %}

<div id="collections-slider-{{ section.id }}" class="page-width collections-slider-section" style="background-color: {{ section.settings.section_bg_color }}; padding-top: {{ section.settings.section_padding_top }}px; padding-bottom: {{ section.settings.section_padding_bottom }}px;">
  <div class="collections-slider-container" style="width: {% if section.settings.full_width %}100%{% else %}80%{% endif %}; margin: 0 auto;">
    {% if section.settings.section_title != blank %}
      <div class="section-heading">
        {{ section.settings.section_title }}
      </div>
    {% endif %}
    <div class="collections-slider-wrapper">
      {% if section.settings.show_arrows %}
        <button class="arrow left-arrow">❮</button>
      {% endif %}
      <div class="collections-slider">
        <div class="slider-track">
          {%- comment -%}
            Clone the last {{ cloneCount }} blocks (for infinite looping) at the beginning.
          {%- endcomment -%}
          {% assign total = section.blocks.size %}
          {% if total > 0 %}
            {% assign start_offset = total | minus: cloneCount %}
            {% for block in section.blocks limit: cloneCount offset: start_offset %}
              {% assign coll_handle = block.settings.collection %}
              {% assign coll = collections[coll_handle] %}
              {% if coll %}
                <div class="slide clone">
                  <a href="{{ coll.url }}">
                    {% if coll.image %}
                      <img class="collection-image" src="{{ coll.image | img_url: section.settings.card_size }}" alt="{{ coll.title }}">
                    {% endif %}
                    <h3 class="collection-title">{{ coll.title }}</h3>
                  </a>
                </div>
              {% endif %}
            {% endfor %}
          {% endif %}
          {%- comment -%}
            Real slides (one per block)
          {%- endcomment -%}
          {% for block in section.blocks %}
            {% assign coll_handle = block.settings.collection %}
            {% assign coll = collections[coll_handle] %}
            {% if coll %}
              <div class="slide">
                <a href="{{ coll.url }}">
                  {% if coll.image %}
                    <img class="collection-image" src="{{ coll.image | img_url: section.settings.card_size }}" alt="{{ coll.title }}">
                  {% endif %}
                  <h3 class="collection-title">{{ coll.title }}</h3>
                </a>
              </div>
            {% endif %}
          {% endfor %}
          {%- comment -%}
            Clone the first {{ cloneCount }} slides at the end.
          {%- endcomment -%}
          {% for block in section.blocks limit: cloneCount %}
            {% assign coll_handle = block.settings.collection %}
            {% assign coll = collections[coll_handle] %}
            {% if coll %}
              <div class="slide clone">
                <a href="{{ coll.url }}">
                  {% if coll.image %}
                    <img class="collection-image" src="{{ coll.image | img_url: section.settings.card_size }}" alt="{{ coll.title }}">
                  {% endif %}
                  <h3 class="collection-title">{{ coll.title }}</h3>
                </a>
              </div>
            {% endif %}
          {% endfor %}
        </div>
      </div>
      {% if section.settings.show_arrows %}
        <button class="arrow right-arrow">❯</button>
      {% endif %}
    </div>
  </div>
</div>

<script>
document.addEventListener("DOMContentLoaded", function() {
  var container = document.getElementById("collections-slider-{{ section.id }}");
  if (!container) return;
  
  var sliderTrack = container.querySelector(".slider-track");
  var slides = container.querySelectorAll(".slide");
  if (slides.length === 0) return;
  
  var gap = 15; // Must match the CSS gap
  
  // Determine visible slides based on viewport width:
  var visibleSlides = window.innerWidth <= 767 
                      ? {{ section.settings.visible_mobile }} 
                      : {{ section.settings.visible_slides }};
  
  // We'll compute the "slide slot" as the effective width of one slide plus the gap.
  var slider = container.querySelector(".collections-slider");
  var sliderWidth = slider.offsetWidth;
  // Calculate the effective slide width (as per our CSS calc)
  var effectiveSlideWidth = (sliderWidth - ((visibleSlides - 1) * gap)) / visibleSlides;
  var slideSlot = effectiveSlideWidth + gap;
  
  // For infinite loop: cloneCount is equal to the number of visible slides.
  var cloneCount = visibleSlides;
  
  // currentIndex should start at cloneCount so that the first real slide is shown.
  var currentIndex = cloneCount;
  
  // Total slides = real slides + 2*cloneCount.
  var totalSlides = slides.length;
  // Real slide count:
  var realCount = totalSlides - 2 * cloneCount;
  // Maximum valid index before reset is:
  var maxIndex = cloneCount + (realCount - visibleSlides);
  
  function updateSlidePosition() {
    sliderTrack.style.transform = "translateX(-" + (currentIndex * slideSlot) + "px)";
  }
  
  updateSlidePosition();
  
  function nextSlide() {
    currentIndex++;
    sliderTrack.style.transition = "transform 0.5s ease-in-out";
    updateSlidePosition();
    // Reset when currentIndex exceeds the real slide block
    if (realCount > visibleSlides && currentIndex >= cloneCount + realCount) {
      setTimeout(function() {
        sliderTrack.style.transition = "none";
        currentIndex = cloneCount;
        updateSlidePosition();
        void sliderTrack.offsetWidth;
        sliderTrack.style.transition = "transform 0.5s ease-in-out";
      }, 500);
    }
  }
  
  function prevSlide() {
    currentIndex--;
    sliderTrack.style.transition = "transform 0.5s ease-in-out";
    updateSlidePosition();
    if (realCount > visibleSlides && currentIndex < cloneCount) {
      setTimeout(function() {
        sliderTrack.style.transition = "none";
        currentIndex = cloneCount + realCount - 1;
        updateSlidePosition();
        void sliderTrack.offsetWidth;
        sliderTrack.style.transition = "transform 0.5s ease-in-out";
      }, 500);
    }
  }
  
  var rightArrow = container.querySelector(".right-arrow");
  var leftArrow = container.querySelector(".left-arrow");
  if (rightArrow) rightArrow.addEventListener("click", nextSlide);
  if (leftArrow) leftArrow.addEventListener("click", prevSlide);
  
  var autoplay = {{ section.settings.auto_slide | json }};
  var autoplaySpeed = {{ section.settings.auto_slide_speed | json }};
  if (autoplay) {
    setInterval(nextSlide, autoplaySpeed);
  }
  
  window.addEventListener("resize", function() {
    visibleSlides = window.innerWidth <= 767 
                    ? {{ section.settings.visible_mobile }} 
                    : {{ section.settings.visible_slides }};
    // Recalculate cloneCount, effective slide width and slide slot based on new slider width
    cloneCount = visibleSlides;
    var sliderWidth = slider.offsetWidth;
    effectiveSlideWidth = (sliderWidth - ((visibleSlides - 1) * gap)) / visibleSlides;
    slideSlot = effectiveSlideWidth + gap;
    // Recalculate maxIndex and realCount:
    totalSlides = slides.length;
    realCount = totalSlides - 2 * cloneCount;
    maxIndex = cloneCount + (realCount - visibleSlides);
    sliderTrack.style.transition = "none";
    updateSlidePosition();
  });
});
</script>



{% schema %}
{
  "name": "Collections Slider",
  "settings": [
    {
      "type": "richtext",
      "id": "section_title",
      "label": "Section Title",
      "default": "<p>Collections</p>"
    },
    {
      "type": "select",
      "id": "heading_alignment",
      "label": "Section Title Alignment",
      "options": [
        { "value": "left", "label": "Left" },
        { "value": "center", "label": "Center" },
        { "value": "right", "label": "Right" }
      ],
      "default": "center"
    },
    {
      "type": "select",
      "id": "heading_size",
      "label": "Section Title Size",
      "options": [
        { "value": "small", "label": "Small" },
        { "value": "medium", "label": "Medium" },
        { "value": "large", "label": "Large" }
      ],
      "default": "medium"
    },
    {
      "type": "checkbox",
      "id": "full_width",
      "label": "Full Width Section (applies to heading & slider)",
      "default": false
    },
    {
      "type": "checkbox",
      "id": "mobile_full_width",
      "label": "Full Width Section on Mobile",
      "default": false
    },
    {
      "type": "checkbox",
      "id": "hide_collection_title",
      "label": "Hide Collection Title",
      "default": false
    },
    {
      "type": "color",
      "id": "section_bg_color",
      "label": "Section Background Color",
      "default": "#ffffff"
    },
    {
      "type": "range",
      "id": "section_padding_top",
      "label": "Section Padding Top (px)",
      "min": 0,
      "max": 200,
      "step": 5,
      "default": 40
    },
    {
      "type": "range",
      "id": "section_padding_bottom",
      "label": "Section Padding Bottom (px)",
      "min": 0,
      "max": 200,
      "step": 5,
      "default": 40
    },
    {
      "type": "checkbox",
      "id": "auto_slide",
      "label": "Enable Auto Slide",
      "default": true
    },
    {
      "type": "range",
      "id": "auto_slide_speed",
      "label": "Auto Slide Speed (ms)",
      "min": 1000,
      "max": 7000,
      "step": 500,
      "default": 6000
    },
    {
      "type": "checkbox",
      "id": "show_arrows",
      "label": "Show Left/Right Arrows",
      "default": true
    },
    {
      "type": "select",
      "id": "arrow_shape",
      "label": "Arrow Shape",
      "options": [
        { "value": "circle", "label": "Circle" },
        { "value": "square", "label": "Square" }
      ],
      "default": "circle"
    },
    {
      "type": "color",
      "id": "arrow_bg_color",
      "label": "Arrow Background Color",
      "default": "#000000"
    },
    {
      "type": "range",
      "id": "visible_slides",
      "label": "Number of Visible Slides (Desktop)",
      "min": 1,
      "max": 5,
      "step": 1,
      "default": 1
    },
    {
      "type": "range",
      "id": "visible_mobile",
      "label": "Number of Visible Slides (Mobile)",
      "min": 1,
      "max": 5,
      "step": 1,
      "default": 1
    },
    {
      "type": "select",
      "id": "image_ratio",
      "label": "Collection Card Image Ratio",
      "options": [
        { "value": "portrait", "label": "Portrait (2:3)" },
        { "value": "square", "label": "Square (1:1)" },
        { "value": "adapt", "label": "Adapt" },
        { "value": "circle", "label": "Circle" }
      ],
      "default": "adapt"
    },
    {
      "type": "select",
      "id": "card_size",
      "label": "Collection Card Size",
      "options": [
        { "value": "small", "label": "Small" },
        { "value": "medium", "label": "Medium" },
        { "value": "large", "label": "Large" }
      ],
      "default": "medium"
    },
    {
      "type": "select",
      "id": "card_design",
      "label": "Collection Card Design",
      "options": [
        { "value": "square", "label": "Square" },
        { "value": "adapt", "label": "Adapt" },
        { "value": "portrait", "label": "Portrait" },
        { "value": "circle", "label": "Circle" }
      ],
      "default": "adapt"
    },
    {
      "type": "checkbox",
      "id": "card_shadow",
      "label": "Enable Collection Card Shadow",
      "default": false
    },
    {
      "type": "select",
      "id": "media_size",
      "label": "Media Size (for images/videos)",
      "options": [
        { "value": "small", "label": "Small" },
        { "value": "medium", "label": "Medium" },
        { "value": "large", "label": "Large" }
      ],
      "default": "medium"
    },
    {
      "type": "select",
      "id": "media_design",
      "label": "Media Design",
      "options": [
        { "value": "square", "label": "Square" },
        { "value": "portrait", "label": "Portrait" },
        { "value": "adapt", "label": "Adapt" }
      ],
      "default": "adapt"
    },
    {
      "type": "checkbox",
      "id": "media_shadow",
      "label": "Enable Media Shadow",
      "default": false
    },
    {
      "type": "select",
      "id": "collection_title_alignment",
      "label": "Collection Title Alignment",
      "options": [
        { "value": "left", "label": "Left" },
        { "value": "center", "label": "Center" },
        { "value": "right", "label": "Right" }
      ],
      "default": "center"
    },
    {
      "type": "range",
      "id": "collection_title_font_size",
      "label": "Collection Title Font Size (px)",
      "min": 12,
      "max": 36,
      "step": 1,
      "default": 18
    }
  ],
  "blocks": [
    {
      "type": "collection",
      "name": "Collection",
      "settings": [
        {
          "type": "collection",
          "id": "collection",
          "label": "Select Collection"
        }
      ]
    },
    {
      "type": "carousel_image",
      "name": "Carousel Image",
      "settings": [
        {
          "type": "image_picker",
          "id": "media",
          "label": "Image"
        }
      ]
    },
    {
      "type": "carousel_video",
      "name": "Carousel Video",
      "settings": [
        {
          "type": "url",
          "id": "media",
          "label": "Video URL"
        }
      ]
    }
  ],
  "max_blocks": 10,
  "presets": [
    {
      "name": "Collections Slider"
    }
  ]
}
{% endschema %}