Follow Below steps to create product image slider in shopify dawn theme:
- Go to theme -> Action -> Edit Code -> Layout -> theme.liquid
- Find </head> and paste below code just above this close head tag
<!-- CSS -->
<link rel="stylesheet" href="https://unpkg.com/flickity@2/dist/flickity.min.css">
<!-- JavaScript -->
<script src="https://unpkg.com/flickity@2/dist/flickity.pkgd.min.js"></script>
3. Open Sections -> main-product.liquid and find below code.
<slider-component class="slider-mobile-gutter">
<a class="skip-to-content-link button visually-hidden" href="#ProductInfo-{{ section.id }}">
{{ "accessibility.skip_to_product_info" | t }}
</a>
<ul class="product__media-list grid grid--peek list-unstyled slider slider--mobile" role="list">
{%- assign variant_images = product.images | where: 'attached_to_variant?', true | map: 'src' -%}
{%- if product.selected_or_first_available_variant.featured_media != null -%}
{%- assign media = product.selected_or_first_available_variant.featured_media -%}
<li class="product__media-item grid__item slider__slide{% if media.media_type != 'image' %} product__media-item--full{% endif %}{% if section.settings.hide_variants and variant_images contains media.src %} product__media-item--variant{% endif %}" data-media-id="{{ section.id }}-{{ media.id }}">
{% render 'product-thumbnail', media: media, position: 'featured', loop: section.settings.enable_video_looping, modal_id: section.id, xr_button: true %}
</li>
{%- endif -%}
{%- for media in product.media -%}
{%- unless media.id == product.selected_or_first_available_variant.featured_media.id -%}
<li class="product__media-item grid__item slider__slide{% if media.media_type != 'image' %} product__media-item--full{% endif %}{% if section.settings.hide_variants and variant_images contains media.src %} product__media-item--variant{% endif %}" data-media-id="{{ section.id }}-{{ media.id }}">
{% render 'product-thumbnail', media: media, position: forloop.index, loop: section.settings.enable_video_looping, modal_id: section.id, xr_button: true %}
</li>
{%- endunless -%}
{%- endfor -%}
</ul>
<div class="slider-buttons no-js-hidden{% if product.media.size < 2 %} small-hide{% endif %}">
<button type="button" class="slider-button slider-button--prev" name="previous" aria-label="{{ 'accessibility.previous_slide' | t }}">{% render 'icon-caret' %}</button>
<div class="slider-counter caption">
<span class="slider-counter--current">1</span>
<span aria-hidden="true"> / </span>
<span class="visually-hidden">{{ 'accessibility.of' | t }}</span>
<span class="slider-counter--total">{% if section.settings.hide_variants %}{{ product.media.size | minus: variant_images.size | plus: 1 }}{% else %}{{ product.media.size }}{% endif %}</span>
</div>
<button type="button" class="slider-button slider-button--next" name="next" aria-label="{{ 'accessibility.next_slide' | t }}">{% render 'icon-caret' %}</button>
</div>
</slider-component>
4. Replace above code with below code.
{% if product.images != null %}
<div class="carousel product__image-slider" role="document" aria-label="{{ 'products.modal.label' | t }}" tabindex="0">
{%- for media in product.media -%}
<div class="carousel-cell">
{% if media.media_type == "video" %}
{{ media | media_tag: image_size: "720x", autoplay: true, loop: loop, controls: true, preload: "none", autoplay: true, height: "100%", width: "100%" }}
{% else %}
<img data-flickity-lazyload-srcset="
{{ media | img_url: '1440x' }} 1440w,
{{ media | img_url: '1080x' }} 1080w,
{{ media | img_url: '720x' }} 767w,
{{ media | img_url: '480x' }} 480w"
sizes="(min-width: 480px) 1440px, 1080px, 767px, 480px"
data-flickity-lazyload-src="{{ media | img_url: 'master' }}"
alt="{{ media.alt | escape }}"
border="0"
data-media-id="{{ media.id }}" />
{% endif %}
</div>
{%- endfor -%}
<!--- Coded by bluish.io --->
</div>
{% if product.images.size > 1 %}
<div class="carousel product__image-thumbnail">
{%- for media in product.media -%}
<div class="carousel-cell">
<img data-flickity-lazyload-srcset="
{{ media | img_url: '1440x' }} 1440w,
{{ media | img_url: '1080x' }} 1080w,
{{ media | img_url: '720x' }} 767w,
{{ media | img_url: '480x' }} 480w"
sizes="(min-width: 480px) 1440px, 1080px, 767px, 480px"
data-flickity-lazyload-src="{{ media | img_url: 'master' }}"
alt="{{ media.alt | escape }}"
border="0"
data-media-id="{{ media_id }}" />
</div>
{%- endfor -%}
<!--- Coded by ramzanmalik.in --->
</div>
{% endif %}
{% else %}
{{ 'product-1' | placeholder_svg_tag }}
{% endif %}
5. Find {% schema %} in the same main-product.liquid file and paste below code just above {% schema %}
<script>
var elem = document.querySelector('.carousel.product__image-slider');
var flkty = new Flickity( elem, {
contain: true,
imagesLoaded: true,
lazyLoad: 1,
wrapAround: true,
pageDots: false,
{% if product.images.size < 2 %}
prevNextButtons: false,
{% endif %}
adaptiveHeight: true
});
var elemThumbnail = document.querySelector('.carousel.product__image-thumbnail');
var flktyB = new Flickity( elemThumbnail, {
asNavFor: '.carousel.product__image-slider',
contain: true,
imagesLoaded: true,
lazyLoad: 4,
pageDots: false,
prevNextButtons: false
});
</script>
6. Go to Assets -> base.css and paste below code at last.
.product__image-slider {
width: 100%;
}
.product__image-slider .carousel-cell {
width: 100%;
height: auto;
margin: 0 5px
}
.product__image-slider .carousel-cell img {
width: 100%;
height: 100%;
}
.grid__item .product__image-slider {
margin-bottom: 2rem;
}
.product__image-slider .flickity-viewport {
transition: height 0.2s;
}
.flickity-button:disabled {
display: none;
}
.product__image-thumbnail .carousel-cell {
width: 20%;
margin-right: 10px;
}
.product__image-thumbnail .carousel-cell img {
width: 100%;
height: 100%;
}
@media screen and (min-width: 990px) {
.product:not(.product--no-media):not(.featured-product) .product__media-wrapper {
max-width: 50% !important;
width: calc(50% - 1rem / 2) !important;
}
.product:not(.product--no-media):not(.featured-product) .product__info-wrapper {
max-width: 50% !important;
width: calc(50% - 1rem / 2) !important;
}
}
7. Go to Assets -> global.js and find below code
constructor() {
super();
this.addEventListener('change', this.onVariantChange);
}
8. Replace above code with below code.
constructor() {
super();
this.initLoad();
this.addEventListener('change', this.onVariantChange);
}
initLoad(){
this.updateOptions();
this.updateMasterId();
this.updateMedia();
}
9. Find below code in the same global.js file.
updateMedia() {
if (!this.currentVariant) return;
if (!this.currentVariant.featured_media) return;
const newMedia = document.querySelector(
`[data-media-id="${this.dataset.section}-${this.currentVariant.featured_media.id}"]`
);
if (!newMedia) return;
const modalContent = document.querySelector(`#ProductModal-${this.dataset.section} .product-media-modal__content`);
const newMediaModal = modalContent.querySelector( `[data-media-id="${this.currentVariant.featured_media.id}"]`);
const parent = newMedia.parentElement;
if (parent.firstChild == newMedia) return;
modalContent.prepend(newMediaModal);
parent.prepend(newMedia);
this.stickyHeader = this.stickyHeader || document.querySelector('sticky-header');
if(this.stickyHeader) {
this.stickyHeader.dispatchEvent(new Event('preventHeaderReveal'));
}
window.setTimeout(() => { parent.querySelector('li.product__media-item').scrollIntoView({behavior: "smooth"}); });
}
10. Replace above code with below code.
updateMedia() {
if (!this.currentVariant) return;
if (!this.currentVariant.featured_media) return;
var current_media_id = this.currentVariant.featured_media.id;
// For product page with flickity
if (document.querySelector('.product__image-slider')) {
var media_len = document.querySelector('.product__image-slider .flickity-slider').childElementCount;
var media_id_array = [];
for (let i = 0; i < media_len; i++) {
media_id_array.push(parseInt(document.querySelector('.product__image-slider').querySelectorAll("img")[i].getAttribute('data-media-id')));
}
flkty.select(media_id_array.indexOf(current_media_id));
}
// For featured products on homepage without flickity
else if (document.querySelector('.product__media-list')) {
var featured_product_media_len = document.querySelector('.product__media-list').childElementCount;
for (let i = 0; i < featured_product_media_len; i++) {
var child = document.querySelector('.product__media-list').children[i];
if (child.getAttribute('data-media-id').indexOf(current_media_id) > 0) {
child.style.display = "block";
} else {
child.style.display = "none";
}
}
}
}