Creating a Custom Slider for Shopify
In this guide, we will create a custom slider for your Shopify store. This slider will allow you to showcase images, headings, subheadings, discount tags, and buttons with customizable styles and behaviors. Follow the steps below to implement the custom slider.
Step 1: Add CSS Files
First, ensure you have the necessary CSS files in your theme. Add the following lines to include your CSS files:
{{ 'section-image-banner.css' | asset_url | stylesheet_tag }}
{{ 'component-slider.css' | asset_url | stylesheet_tag }}
{{ 'component-slideshow.css' | asset_url | stylesheet_tag }}
Step 2: Define Slider Section
Create a new section in your Shopify theme. Let’s call it custom-slideshow.liquid
. Add the following code to define the structure and settings for the slider:
{% schema %}
{
"name": "Custom Slide Show",
"tag": "section",
"class": "section",
"settings": [
{
"type": "select",
"id": "layout",
"options": [
{ "value": "full_bleed", "label": "Full Bleed" },
{ "value": "grid", "label": "Grid" }
],
"default": "full_bleed",
"label": "Layout"
},
{
"type": "select",
"id": "slide_height",
"options": [
{ "value": "adapt_image", "label": "Adapt to Image" },
{ "value": "small", "label": "Small" },
{ "value": "medium", "label": "Medium" },
{ "value": "large", "label": "Large" }
],
"default": "medium",
"label": "Slide Height"
},
{
"type": "select",
"id": "slider_visual",
"options": [
{ "value": "dots", "label": "Dots" },
{ "value": "counter", "label": "Counter" },
{ "value": "numbers", "label": "Numbers" }
],
"default": "counter",
"label": "Slider Visual"
},
{
"type": "checkbox",
"id": "auto_rotate",
"label": "Auto Rotate",
"default": false
},
{
"type": "range",
"id": "change_slides_speed",
"min": 3,
"max": 9,
"step": 2,
"unit": "s",
"label": "Change Slides Speed",
"default": 5
},
{
"type": "header",
"content": "Animation Settings"
},
{
"type": "select",
"id": "image_behavior",
"options": [
{ "value": "none", "label": "None" },
{ "value": "ambient", "label": "Ambient" }
],
"default": "none",
"label": "Image Behavior"
},
{
"type": "checkbox",
"id": "show_text_below",
"label": "Show Text Below",
"default": true
},
{
"type": "text",
"id": "accessibility_info",
"label": "Accessibility Information",
"default": "Slideshow about our brand"
}
],
"blocks": [
{
"type": "slide",
"name": "Slide",
"settings": [
{
"type": "image_picker",
"id": "image",
"label": "Image"
},
{
"type": "inline_richtext",
"id": "heading",
"default": "Image slide",
"label": "Heading"
},
{
"type": "select",
"id": "heading_size",
"options": [
{ "value": "h2", "label": "H2" },
{ "value": "h1", "label": "H1" },
{ "value": "h0", "label": "H0" }
],
"default": "h1",
"label": "Heading Size"
},
{
"type": "inline_richtext",
"id": "subheading",
"default": "Tell your brand's story through images",
"label": "Subheading"
},
{
"type": "inline_richtext",
"id": "discounttag",
"default": "99% Off",
"label": "Discount Tag"
},
{
"type": "color",
"id": "discounttag_color",
"default": "#FF0000",
"label": "Discount Tag Color"
},
{
"type": "color",
"id": "content_container_background",
"default": "#FF0000",
"label": "Content Box Background"
},
{
"type": "text",
"id": "button_label",
"default": "Button label",
"label": "Button Label"
},
{
"type": "url",
"id": "link",
"label": "Button Link"
},
{
"type": "checkbox",
"id": "button_style_secondary",
"label": "Secondary Button Style",
"default": false
},
{
"type": "select",
"id": "box_align",
"options": [
{ "value": "top-left", "label": "Top Left" },
{ "value": "top-center", "label": "Top Center" },
{ "value": "top-right", "label": "Top Right" },
{ "value": "middle-left", "label": "Middle Left" },
{ "value": "middle-center", "label": "Middle Center" },
{ "value": "middle-right", "label": "Middle Right" },
{ "value": "bottom-left", "label": "Bottom Left" },
{ "value": "bottom-center", "label": "Bottom Center" },
{ "value": "bottom-right", "label": "Bottom Right" }
],
"default": "middle-center",
"label": "Box Alignment"
},
{
"type": "checkbox",
"id": "show_text_box",
"label": "Show Text Box",
"default": true
},
{
"type": "select",
"id": "text_alignment",
"options": [
{ "value": "left", "label": "Left" },
{ "value": "center", "label": "Center" },
{ "value": "right", "label": "Right" }
],
"default": "center",
"label": "Text Alignment"
},
{
"type": "range",
"id": "image_overlay_opacity",
"min": 0,
"max": 100,
"step": 10,
"unit": "%",
"label": "Image Overlay Opacity",
"default": 0
},
{
"type": "color_scheme",
"id": "color_scheme",
"label": "Color Scheme",
"default": "scheme-1"
},
{
"type": "select",
"id": "text_alignment_mobile",
"options": [
{ "value": "left", "label": "Left" },
{ "value": "center", "label": "Center" },
{ "value": "right", "label": "Right" }
],
"default": "center",
"label": "Text Alignment Mobile"
}
]
}
],
"presets": [
{
"name": "Default",
"category": "Custom"
}
]
}
{% endschema %}
Step 3: Add Slider HTML and Liquid Code
Add the following HTML and Liquid code to custom-slideshow.liquid
to render the slider:
<slideshow-component
class="slider-mobile-gutter{% if section.settings.layout == 'grid' %} page-width{% endif %}{% if section.settings.show_text_below %} mobile-text-below{% endif %}"
role="region"
aria-roledescription="{{ 'sections.slideshow.carousel' | t }}"
aria-label="{{ section.settings.accessibility_info | escape }}"
>
{%- if section.settings.auto_rotate and section.blocks.size > 1 -%}
<div class="slideshow__controls slideshow__controls--top slider-buttons no-js-hidden{% if section.settings.show_text_below %} slideshow__controls--border-radius-mobile{% endif %}">
<button
type="button"
class="slider-button slider-button--prev"
name="previous"
aria-label="{{ 'sections.slideshow.previous_slideshow' | t }}"
aria-controls="Slider-{{ section.id }}"
>
{% render 'icon-caret' %}
</button>
<div class="slider-counter slider-counter--{{ section.settings.slider_visual }}{% if section.settings.slider_visual == 'counter' or section.settings.slider_visual == 'numbers' %} caption{% endif %}">
{%- if section.settings.slider_visual == 'counter' -%}
<span class="slider-counter--current">1</span>
<span aria-hidden="true"> / </span>
<span class="slider-counter--total">{{ section.blocks.size }}</span>
{%- endif -%}
</div>
<button
type="button"
class="slider-button slider-button--next"
name="next"
aria-label="{{ 'sections.slideshow.next_slideshow' | t }}"
aria-controls="Slider-{{ section.id }}"
>
{% render 'icon-caret' %}
</button>
</div>
{%- endif -%}
<ul class="slideshow__slides slider slider--{{ section.settings.slider_visual }}{% if section.settings.slider_visual == 'dots' %} dots{% endif %}"
id="Slider-{{ section.id }}"
role="list"
data-autoplay="{% if section.settings.auto_rotate %}true{% else %}false{% endif %}"
data-autoplay-speed="{{ section.settings.change_slides_speed * 1000 }}"
>
{%- for block in section.blocks -%}
{% assign color_scheme_classes = '' %}
{% if block.settings.color_scheme %}
{% assign color_scheme_classes = block.settings.color_scheme | color_scheme_classes: 'color-background color-inverse' %}
{% endif %}
<li id="Slide-{{ section.id }}-{{ block.id }}"
class="slideshow__slide slider__slide{% if forloop.first %} slider__slide--current{% endif %}{% if section.settings.image_behavior != 'none' %} slider__slide--{{ section.settings.image_behavior }}{% endif %}{% if block.settings.show_text_box %} slider__slide--overlay{% endif %}"
role="listitem"
data-color-scheme="{{ block.settings.color_scheme }}"
>
<div class="slideshow__image-wrapper">
<img
src="{{ block.settings.image | image_url: '1x1' }}"
srcset="{{ block.settings.image | image_url: 'master' }} 1x"
alt="{{ block.settings.image.alt | escape }}"
class="slideshow__image"
data-image="{% if section.settings.image_behavior == 'ambient' %} ambient {% else %} none {% endif %}"
role="presentation"
aria-hidden="true"
>
{%- if block.settings.image_overlay_opacity > 0 -%}
<div class="slideshow__overlay slider__overlay slider__overlay--{{ block.settings.image_overlay_opacity }}" aria-hidden="true"></div>
{%- endif -%}
</div>
<div class="slideshow__text-container slider__text-container{% if block.settings.show_text_box %} has-text{% endif %}">
{%- if block.settings.show_text_box -%}
<div class="slider__content{{ color_scheme_classes }}">
<div class="slider__content-inner slider__content-inner--{{ block.settings.box_align }}">
<div class="slider__content-container{% if block.settings.text_alignment %} text-{{ block.settings.text_alignment }}{% endif %}">
{%- if block.settings.heading != blank -%}
<{{ block.settings.heading_size }} class="slider__heading">
{{ block.settings.heading }}
</{{ block.settings.heading_size }}>
{%- endif -%}
{%- if block.settings.subheading != blank -%}
<div class="slider__subheading">
{{ block.settings.subheading }}
</div>
{%- endif -%}
{%- if block.settings.discounttag != blank -%}
<div class="slider__discounttag" style="color: {{ block.settings.discounttag_color }}">
{{ block.settings.discounttag }}
</div>
{%- endif -%}
{%- if block.settings.button_label != blank and block.settings.link != blank -%}
<a href="{{ block.settings.link }}"
class="button{% if block.settings.button_style_secondary %} button--secondary{% endif %}"
aria-label="{{ block.settings.button_label }}"
>
{{ block.settings.button_label }}
</a>
{%- endif -%}
</div>
</div>
</div>
{%- endif -%}
</div>
</li>
{%- endfor -%}
</ul>
</slideshow-component>
{% if section.settings.image_behavior == 'ambient' %}
<script src="{{ 'ambient-image.js' | asset_url }}"></script>
{% endif %}
Step 4: Include JavaScript for Slider Functionality
Create a JavaScript file, let’s call it custom-slider.js
, and add the following code to handle slider functionality:
javascriptCopy codedocument.addEventListener('DOMContentLoaded', function() {
const slideshows = document.querySelectorAll('slideshow-component');
slideshows.forEach(slideshow => {
const slider = slideshow.querySelector('.slider');
const slides = slideshow.querySelectorAll('.slider__slide');
const prevButton = slideshow.querySelector('.slider-button--prev');
const nextButton = slideshow.querySelector('.slider-button--next');
const autoPlay = slideshow.dataset.autoplay === 'true';
const autoPlaySpeed = parseInt(slideshow.dataset.autoplaySpeed, 10);
let currentIndex = 0;
let autoPlayInterval;
function goToSlide(index) {
slides.forEach((slide, i) => {
slide.classList.toggle('slider__slide--current', i === index);
});
currentIndex = index;
}
function nextSlide() {
goToSlide((currentIndex + 1) % slides.length);
}
function prevSlide() {
goToSlide((currentIndex - 1 + slides.length) % slides.length);
}
if (prevButton) {
prevButton.addEventListener('click', prevSlide);
}
if (nextButton) {
nextButton.addEventListener('click', nextSlide);
}
if (autoPlay) {
autoPlayInterval = setInterval(nextSlide, autoPlaySpeed);
slider.addEventListener('mouseenter', () => clearInterval(autoPlayInterval));
slider.addEventListener('mouseleave', () => autoPlayInterval = setInterval(nextSlide, autoPlaySpeed));
}
});
});
Step 5: Include JavaScript in Your Theme
Include the custom-slider.js
file in your theme by adding the following line to your theme.liquid file:
{{ 'custom-slider.js' | asset_url | script_tag }}
Conclusion
Following these steps, you will have a fully functional custom slider in your Shopify store with configurable images, headings, subheadings, discount tags, and buttons. You can further customize the styles and behaviors by adjusting the CSS and JavaScript as needed.