Featured Collection Product Image slider for Shopify Dawn theme with Option

Featured Collection Product Image slider for Shopify Dawn theme with Option

Compatibility: Dawn 2.0 to Shopify 2.0 FREE themes

I created a Collection with numbers and dots (see version here). This time I added a clickable slider option. Please see the checkbox in the section setting and check for the corresponding version. 

NOTE: The quick-view button in the demo is a separate code. Check this link for quick-view button.

Check DEMO store here 💻. Password: made4uo

I have a checkbox available in the theme editor to convert the code to newer or older version of Shopify Dawn Theme. 

What is a featured collection with slider option in Shopify Dawn?

A featured collection with slider option is a way to display a collection of products on your Shopify Dawn theme with a slider. This can be a great way to highlight your latest products or to promote a specific collection.

Why use the featured collection with slider option?

There are a number of reasons why you might want to use the featured collection with slider option. One reason is to highlight your latest products or to promote a specific collection. This can help to increase sales and drive traffic to your store.

Another reason to use the featured collection with slider option is to create a more visually appealing and engaging website. The slider can help to add some movement and interest to your page, and it can also help to break up the text and make the page more visually appealing.

[]

Steps on how to add the featured collection with slider option?

Step #1. Open your code editor

From you Admin page, go to Online store, then Themes. Choose the theme you want to edit, then click the three dots, then Edit code

Step #2. Create a new section file

In Section folder, create a new section, name it "Collection Slider", then replace the default code with the code below.

{{ 'component-card.css' | asset_url | stylesheet_tag }}
{{ 'component-price.css' | asset_url | stylesheet_tag }}
{{ 'component-product-grid.css' | asset_url | stylesheet_tag }}
{{ 'featured-slider.css' | asset_url | stylesheet_tag }}
 
<link rel="stylesheet" href="{{ 'component-slider.css' | asset_url }}" media="print" onload="this.media='all'">
<link rel="stylesheet" href="{{ 'template-collection.css' | asset_url }}" media="print" onload="this.media='all'">
<noscript>{{ 'template-collection.css' | asset_url | stylesheet_tag }}</noscript>
 
{%- liquid
assign products_to_display = section.settings.collection.all_products_count
assign swipe_on_mobile = true
 
if section.settings.collection.all_products_count > section.settings.products_to_show
assign products_to_display = section.settings.products_to_show
assign more_in_collection = true
endif
-%}
 
<div class="collectionSlider" style= "padding-top: {{ section.settings.padding_top  | append: "&" }}; padding-bottom: {{section.settings.padding_bottom  | append: "&" }}">
<div class="featured-title-wrapper{% if section.settings.title == blank %} title-wrapper-with-link--no-heading{% endif %}">
{% if section.settings.title != blank %}
<h2 class="featured-title">{{ section.settings.title | escape }}</h2>
{% endif %}
{% if section.settings.show_view_all %}
<a href="{{ section.settings.collection.url }}" class="button">{{ 'sections.featured_collection.view_all' | t }}</a>
{% endif %}
</div>
 
<collection-slider-component style="--border-color: {{section.settings.border_color}};">
{% if section.settings.slider_visual == 'slider' %}<div class="sliderCounterBox">
<button type="button" class="sliderCounterButton sliderCounterButton--prev slider-button"
data-step="1"
name="previous"
aria-label="{{ 'sections.slideshow.previous_slideshow' | t }}"
style"display: flex"
aria-controls="Slider-{{ section.id }}">{% render 'icon-caret' %}</button>
{% endif %}
<ul id="Slider-{{ section.id }}"
class="featured-grid
product-grid
{% if section.settings.collection.all_products_count > 2 and swipe_on_mobile and section.settings.products_to_show > 2 %}
slider slider--tablet grid--peek{% endif %}
{% if section.settings.show_view_all and section.settings.collection.products.size > section.settings.products_to_show %}
negative-margin--small{% endif %}" role="list">
{%- for product in section.settings.collection.products limit: section.settings.products_to_show -%}
<li id="Slide-{{ section.id }}-{{ forloop.index }}"
data-image="{{forloop.index0}}"
class="grid--col {% if section.settings.collection.all_products_count > 2 and swipe_on_mobile and section.settings.products_to_show > 2 %} slider__slide{% endif %}">
{% if section.settings.newer_version %}
{% render 'card-product',
card_product: product,
media_aspect_ratio: section.settings.image_ratio,
show_secondary_image: section.settings.show_secondary_image,
show_vendor: section.settings.show_vendor,
show_rating: section.settings.show_rating
%}
{% else %}
{% render 'product-card',
product_card_product: product,
media_size: section.settings.image_ratio,
show_secondary_image: section.settings.show_secondary_image,
add_image_padding: section.settings.add_image_padding,
show_vendor: section.settings.show_vendor,
show_image_outline: section.settings.show_image_outline,
show_rating: section.settings.show_rating
%}
{% endif %}
</li>
{%- else -%}
{%- for i in (1..4) -%}
<li class="grid__item">
{% render 'card-product', show_vendor: section.settings.show_vendor %}
</li>
{%- endfor -%}
{%- endfor -%}
</ul>
{% if section.settings.slider_visual == 'slider' %}
<button type="button" class="sliderCounterButton sliderCounterButton--next slider-button {% if section.settings.slider_visual != 'slider' %}hidden {% endif %}"
name="next"
data-step="1"
style="display: flex"
aria-label="{{ 'sections.slideshow.next_slideshow' | t }}"
aria-controls="Slider-{{ section.id }}">{% render 'icon-caret' %}
</button>
</div>
{% endif %}
{%- if section.settings.collection.all_products_count > 2 and swipe_on_mobile and section.settings.products_to_show > 2 -%}
 
{%- if section.settings.slider_visual == 'slider' -%}
<div class="sliderContainer">
<input type="range" min="0" max="{{products_to_display | minus: 1}}" value="1" class="sliderCounter" id="myRange">
</div>
<style>
.collectionSlider .sliderCounter::-webkit-slider-thumb {
width: calc(100% / {{products_to_display }});
}
 
.collectionSlider .sliderCounter::-moz-range-thumb {
width: calc(100% / {{products_to_display}});
}
</style>
{% endif %}
 
<div class="slideshow__controls slider-buttons no-js-hidden {% if section.settings.slider_visual == 'slider' %}hidden {% endif %}"
style="display: flex">
<button type="button" class="slider-button slider-button--prev"
data-step="1"
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 == 'numbers' %} caption{% endif %}">
<div class="counter--mobile">
<span class="slider-counter--current">1</span>
<span aria-hidden="true"> / </span>
<span class="slider-counter--total">
{% if section.settings.products_to_show < section.settings.collection.products %}
{{section.settings.products_to_show }}
{% else %}
{{section.settings.collection.all_products_count}}
{% endif %}
</span>
</div>
<div class="slideshow__control-wrapper slider">
{%- for product in section.settings.collection.products limit: section.settings.products_to_show -%}
<button class="slider-counter__link slider-counter__link--{{ section.settings.slider_visual }} link"
data-dot="{{forloop.index0}}"
style="padding: 1rem; width: 100%"
aria-label="{{ 'sections.slideshow.load_slide' | t }} {{ forloop.index }} {{ 'general.slider.of' | t }}
{{ forloop.length}}" aria-controls="Slider-{{ section.id }}">
{%- if section.settings.slider_visual == 'numbers' -%}{{ forloop.index }}{% else %}<span class="dot"></span>{%- endif -%}
</button>
{%- endfor -%}
</div>
</div>
<button type="button" class="slider-button slider-button--next"
name="next"
data-step="1"
aria-label="{{ 'sections.slideshow.next_slideshow' | t }}"
aria-controls="Slider-{{ section.id }}">{% render 'icon-caret' %}
</button>
</div>
 
<noscript>
<div class="slider-buttons" style="display: flex">
<div class="slider-counter">
{%- for product in section.settings.collection.products limit: section.settings.products_to_show -%}
<a href="#Slide-{{ section.id }}-{{ forloop.index }}"
data-dot="{{forloop.index}}"
class="slider-counter__link link" aria-label="{{ 'sections.slideshow.load_slide' | t }} {{ forloop.index }} {{ 'general.slider.of' | t }} {{ forloop.length}}">
{{ forloop.index }}
</a>
{%- endfor -%}
</div>
</div>
</noscript>
{%- endif -%}
</collection-slider-component>
</div>
 
{% schema %}
{
"name": "Collection Slider",
"tag": "section",
"class": "spaced-section",
"settings": [
{
"type": "checkbox",
"id": "newer_version",
"default": true,
"label": "Dawn version 2.6 and above"
},
{
"type": "text",
"id": "title",
"default": "Featured collection",
"label": "t:sections.featured-collection.settings.title.label"
},
{
"type": "collection",
"id": "collection",
"label": "t:sections.featured-collection.settings.collection.label"
},
{
"type": "range",
"id": "products_to_show",
"min": 2,
"max": 99,
"step": 1,
"default": 4,
"label": "t:sections.featured-collection.settings.products_to_show.label"
},
{
"type": "checkbox",
"id": "show_view_all",
"default": true,
"label": "t:sections.featured-collection.settings.show_view_all.label"
},
{
"type": "header",
"content": "Additional Section padding"
},
{
"type": "range",
"id": "padding_top",
"min": 0,
"max": 99,
"step": 1,
"unit": "%",
"default": 0,
"label": "Section padding top"
},
{
"type": "range",
"id": "padding_bottom",
"min": 0,
"max": 99,
"step": 1,
"unit": "%",
"default": 0,
"label": "Section padding bottom"
},
{
"type": "header",
"content": "t:sections.featured-collection.settings.header.content"
},
{
"type": "select",
"id": "image_ratio",
"options": [
{
"value": "adapt",
"label": "t:sections.featured-collection.settings.image_ratio.options__1.label"
},
{
"value": "portrait",
"label": "t:sections.featured-collection.settings.image_ratio.options__2.label"
},
{
"value": "square",
"label": "t:sections.featured-collection.settings.image_ratio.options__3.label"
}
],
"default": "adapt",
"label": "t:sections.featured-collection.settings.image_ratio.label"
},
{
"type": "checkbox",
"id": "show_secondary_image",
"default": false,
"label": "show secondary image"
},
{
"type": "checkbox",
"id": "add_image_padding",
"default": false,
"label": "add image padding"
},
{
"type": "checkbox",
"id": "show_image_outline",
"default": true,
"label": "show image outline"
},
{
"type": "checkbox",
"id": "show_vendor",
"default": false,
"label": "show vendor"
},
{
"type": "checkbox",
"id": "show_rating",
"default": false,
"label": "show product rating",
"info": "To display a rating, add a product rating app. Learn more"
},
{
"type": "color",
"id": "border_color",
"label": "border color",
"default": "#eee"
},
{
"type": "select",
"id": "slider_visual",
"options": [
{
"value": "dots",
"label": "dots"
},
{
"value": "numbers",
"label": "numbers"
},
{
"value": "slider",
"label": "slider"
}
],
"default": "numbers",
"label": "numbers"
}
],
"presets": [
{
"name": "Collection Slider"
}
]
}
{% endschema %}


Step #3. Open Asset folder

Next, we need to add some beauty to it. Open the Asset folder, and "create a new asset." Name it "collection-slider." Then place the code below.

.collectionSlider {
padding: 5%;
overflow: hidden;
}
 
.collectionSlider slider-component {
position: relative;
display: block;
}
 
@media screen and (max-width: 989px) {
.no-js slider-component .slider {
padding-bottom: 3rem;
}
}
 
.slider__slide {
scroll-snap-align: start;
flex-shrink: 0;
}
 
@media screen and (max-width: 749px) {
.grid--col {
width: 33%;
}
}
 
@media screen and (max-width: 481px) {
.grid--col {
width: 50%;
}
}
 
@media screen and (min-width: 750px) {
.grid--col {
width: 20%;
}
}
 
.collectionSlider .featured-title-wrapper {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 2rem;
}
 
.collectionSlider .featured-title {
margin: auto 0;
}
 
.collectionSlider .featured-grid {
display: flex;
padding: 0;
}
 
.collectionSlider .featured-grid li {
list-style: none;
}
 
.collectionSlider .slider.slider--tablet {
position: relative;
flex-wrap: inherit;
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
scroll-padding-left: 1rem;
-webkit-overflow-scrolling: touch;
margin-bottom: 1rem;
}
 
.collectionSlider .slider__slide {
padding-bottom: 0;
padding: 0 1rem;
}
 
@media (prefers-reduced-motion) {
.slider--everywhere {
scroll-behavior: auto;
}
}
 
.collectionSlider .slider.slider--everywhere .slider__slide {
margin-bottom: 0;
padding-bottom: 0;
scroll-snap-align: center;
}
 
/* Scrollbar */
 
.collectionSlider .slider {
scrollbar-color: rgb(var(--color-foreground)) rgba(var(--color-foreground), 0.04);
-ms-overflow-style: none;
scrollbar-width: none;
}
 
.collectionSlider .slider::-webkit-scrollbar {
height: 0.4rem;
width: 0.4rem;
display: none;
}
 
.no-js .slider {
-ms-overflow-style: auto;
scrollbar-width: auto;
}
 
.no-js .slider::-webkit-scrollbar {
display: initial;
}
 
.collectionSlider .slider::-webkit-scrollbar-thumb {
background-color: rgb(var(--color-foreground));
border-radius: 0.4rem;
border: 0;
}
.collectionSlider .slider::-webkit-scrollbar-track {
background: rgba(var(--color-foreground), 0.04);
border-radius: 0.4rem;
}
 
.collectionSlider .slider-counter {
margin: 0 1.2rem;
display: flex;
min-width: 2rem;
justify-content: center;
}
 
@media screen and (max-width: 749px) {
.collectionSlider .slider-counter--dots,
.collectionSlider .slider-counter--numbers {
margin: 0;
}
}
 
 
@media screen and (max-width: 749px) {
.collectionSlider .slider-counter__link {
padding: 0.7rem;
}
}
 
.collectionSlider .slider-counter__link--dots .dot {
width: 1rem;
height: 1rem;
border-radius: 50%;
border: 0.1rem solid rgba(var(--color-foreground), 0.5);
padding: 0;
display: block;
}
 
.collectionSlider .slider-counter__link--active.slider-counter__link--dots .dot {
background-color: rgb(var(--color-foreground));
}
 
@media screen and (forced-colors: active) {
.slider-counter__link--active.slider-counter__link--dots .dot {
background-color: CanvasText;
}
}
 
.slider-counter__link--dots:not(.slider-counter__link--active):hover .dot {
border-color: rgb(var(--color-foreground));
}
 
.slider-counter__link--dots .dot,
.slider-counter__link--numbers {
transition: transform 0.2s ease-in-out;
}
 
.slider-counter__link--active.slider-counter__link--numbers,
.slider-counter__link--dots:not(.slider-counter__link--active):hover .dot,
.slider-counter__link--numbers:hover {
transform: scale(1.1);
}
 
.collectionSlider .slider-counter__link--numbers {
color: rgba(var(--color-foreground), 0.5);
text-decoration: none;
}
 
.collectionSlider .slider-counter__link--numbers:hover {
color: rgb(var(--color-foreground));
}
 
.collectionSlider .slider-counter__link--active.slider-counter__link--numbers {
text-decoration: underline;
color: rgb(var(--color-foreground));
}
 
.collectionSlider .slider-buttons {
display: flex;
align-items: center;
justify-content: center;
}
 
.collectionSlider .slider-button {
color: rgba(var(--color-foreground), 0.75);
background: transparent;
border: none;
cursor: pointer;
width: 44px;
height: 44px;
display: flex;
align-items: center;
justify-content: center;
}
 
.slider-button:not([disabled]):hover {
color: rgb(var(--color-foreground));
}
 
.slider-button .icon {
height: 0.6rem;
}
 
.slider-button[disabled] .icon {
color: rgba(var(--color-foreground), 0.3);
cursor: not-allowed;
}
 
.slider-button--next .icon {
transform: rotate(-90deg);
}
 
.slider-button--prev .icon {
transform: rotate(90deg);
}
 
.slider-button--next:not([disabled]):hover .icon {
transform: rotate(-90deg) scale(1.1);
}
 
.slider-button--prev:not([disabled]):hover .icon {
transform: rotate(90deg) scale(1.1);
}
 
.spaced-section--full-width:last-child featured-slideshow-component:not(.page-width) .slideshow__controls {
border-bottom: none;
}
 
@media screen and (min-width: 750px) {
.collectionSlider .slideshow__controls {
position: relative;
}
}
 
slideshow-component:not(.page-width) .slider-buttons {
border-right: 0;
border-left: 0;
}
 
.collectionSlider .slideshow__control-wrapper {
display: flex;
width: 28rem;
overflow-x: auto;
}
 
.image--active {
border: 5px solid var(--border-color);
}
 
.counter--mobile {
display: none;
}
 
@media only screen and (max-width: 481px) {
.collectionSlider .counter--mobile {
display: flex;
}
.collectionSlider .slideshow__control-wrapper {
display: none;
}
}
 
.collectionSlider .slider-counter__link {
display: flex;
align-items: center;
justify-content: center;
}
 
.collectionSlider .smallDot {
width: 0.4rem !important;
height: 0.4rem !important;
}
 
.collectionSlider .mediumDot {
width: 0.75rem !important;
height: 0.75rem !important;
}
 
 
/* slider counter */
 
.collectionSlider .slidecontainer {
width: 100%;
}
 
.collectionSlider .sliderCounter {
-webkit-appearance: none;
width: 100%;
height: 5px;
border-radius: 5px;
background: #d3d3d3;
outline: none;
opacity: .7;
-webkit-transition: .2s;
transition: opacity .2s;
}
 
.sliderCounter:hover {
opacity: 1;
}
 
.sliderCounter::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
height: 5px;
border-radius: 5px;
background: black;
cursor: pointer;
}
 
.sliderCounter::-moz-range-thumb {
height: 5px;
border-radius: 5px;
background: black;
cursor: pointer;
}
 
.sliderCounterBox {
display: flex;
align-items: center;
}
 
.sliderCounterButton {
display: none;
position: absolute;
background: black !important;
color: white !important;
transition: all .2s ease;
z-index: 10;
}
 
.collectionSlider:hover .sliderCounterButton--prev{
left: 0;
}
 
.collectionSlider:hover .sliderCounterButton--next {
right: 0;
}
 
.sliderCounterButton--prev {
left: -50px;
}
 
.sliderCounterButton--prev > svg{
transform: rotate(90deg);
}
 
.sliderCounterButton--next {
right: -50px;
}
 
.sliderCounterButton--next > svg{
transform: rotate(-90deg);
}
 
.sliderCounterButton:hover {
transform: scale(1.1);
}
 
.sliderCounterButton > svg {
height: 2rem !important;
}
 
@media screen and (max-width: 750px) {
.sliderCounterButton--prev {
left: 0;
}
.sliderCounterButton--next {
right: 0;
}
}

 

Step #4. Add the brain.

Last thing to do is to add the brain in our section. Still at the Asset folder, open the global.js and add the code below. 

class CollectionSliderComponent extends HTMLElement {
constructor() {
super();
this.sliderControlWrapper = this.querySelector('.slider-buttons');
 
this.slider = this.querySelector('[id^="Slider-"]');
this.sliderItems = this.querySelectorAll('[id^="Slide-"]');
this.sliderCounter = this.querySelector('.sliderCounter');
this.currentPageElement = this.querySelector('.slider-counter--current');
this.pageTotalElement = this.querySelector('.slider-counter--total');
this.prevButton = this.querySelector('.slider-button--prev');
this.nextButton = this.querySelector('.slider-button--next');
 
this.sliderButtonPrev = this.querySelector('.sliderCounterButton--prev');
this.sliderButtonNext = this.querySelector('.sliderCounterButton--next');
 
this.step = 0;
this.sliderControlWrapper = this.querySelector('.slideshow__control-wrapper');
 
this.sliderControlLinksArray = Array.from(this.sliderControlWrapper.querySelectorAll('.slider-counter__link'));
this.sliderControlLinksArray.forEach(link => link.addEventListener('click', this.linkToSlide.bind(this)));
this.prevButton.addEventListener('click', this.onButtonClick.bind(this));
this.nextButton.addEventListener('click', this.onButtonClick.bind(this));
 
if(this.sliderCounter) {
this.sliderButtonPrev.addEventListener('click', this.onButtonClick.bind(this));
this.sliderButtonNext.addEventListener('click', this.onButtonClick.bind(this));
 
this.sliderCounter.addEventListener('change', this.sliderCounterUpdate.bind(this));
}
}
 
update(slide) {
this.sliderItems.forEach(image => {
image.classList.remove('image--active');
image.removeAttribute('aria-current');
});
 
this.currentPageElement.innerHTML = slide + 1;
this.pageTotalElement.innerHTML = this.sliderItems.length;
this.sliderItems[slide].classList.add('image--active');
this.sliderItems[slide].setAttribute('aria-current', true);
this.sliderControlButtons = this.querySelectorAll('.slider-counter__link');
this.sliderControlButtons.forEach(link => {
link.classList.remove('slider-counter__link--active');
link.removeAttribute('aria-current');
});
 
this.sliderControlButtons[slide].classList.add('slider-counter__link--active');
this.sliderControlButtons[slide].setAttribute('aria-current', true);
 
this.slideScrollPosition = slide * this.sliderItems[0].clientWidth;
 
this.slider.scrollTo({
left: this.slideScrollPosition
});
 
if(this.sliderCounter) {
this.sliderCounter.value = slide;
}
 
if(this.querySelector('.dot')) {
const controlWidth = this.querySelector(`[data-dot='${0}']`).clientWidth;
const controlOffset = this.querySelector(`[data-dot='${slide}']`).offsetLeft;
this.querySelector(`[data-dot='${slide}']`).scrollIntoView({block: "nearest", inline: "center"});
this.querySelectorAll(`.dot`).forEach(dot => dot.classList.remove('mediumDot'));
this.querySelectorAll(`.dot`).forEach(dot => dot.classList.remove('smallDot'));
 
if (controlOffset > controlWidth * 10){
if(slide > 4 && slide < this.sliderItems.length - 5) {
this.querySelector(`[data-dot='${slide - 5}'] > .dot`).classList.add('smallDot');
this.querySelector(`[data-dot='${slide - 4}'] > .dot`).classList.add('mediumDot');
}
}
 
if (controlOffset < (controlWidth * 10) + (controlWidth * (this.sliderItems.length - 1)) ){
if(slide > 4 && slide < this.sliderItems.length - 5) {
this.querySelector(`[data-dot='${slide + 4}'] > .dot`).classList.add('mediumDot');
this.querySelector(`[data-dot='${slide + 5}'] > .dot`).classList.add('smallDot');
}
}
}
}
 
onButtonClick(event) {
event.preventDefault();
if(event.currentTarget.name === 'next') {
this.step++;
if(this.step > this.sliderItems.length - 1) {
this.step = 0
}
} else {
this.step--;
if(this.step < 0) {
this.step = this.sliderItems.length - 1
}
}
this.currentIndex(this.step);
}
 
linkToSlide(event) {
const dotIndex = event.currentTarget.dataset.dot;
this.step = dotIndex;
this.currentIndex(this.step);
}
 
currentIndex(index) {
this.update(index);
}
 
sliderCounterUpdate(event) {
event.preventDefault();
this.step = this.sliderCounter.value;
this.currentIndex(this.step);
}
}
 
customElements.define('collection-slider-component', CollectionSliderComponent);


Step #5. Save the changes

Once you've added the code, save your changes to the theme code by clicking the SAVE button on the right hand upper corner.

Conclusion

Incorporating a featured collection with a slider option within your Shopify Dawn theme is a valuable strategy for showcasing products and enhancing the visual appeal of your store.  This dynamic element allows you to highlight specific collections, promote new arrivals, or draw attention to special offers, ultimately driving customer engagement and potentially increasing sales. By carefully selecting the featured collection, using high-quality images, and optimizing the slider's settings, you can create a compelling and user-friendly experience that encourages visitors to explore your offerings.  While the implementation may require some theme customization, the benefits of a visually engaging and strategically placed featured collection slider make it a worthwhile investment for any Shopify store owner looking to improve their online presence.

 That's it. Enjoy (",)

0 comments

Leave a comment