Back to Shopify Liquid
3 info sliders with images
Shopify Liquid

3 info sliders with images

A compact three-card info slider featuring top-aligned images, bold headings, and descriptive text. It includes custom JavaScript for touch-based dragging, auto-play functionality, and mobile-responsive pagination dots.

EasyProduct PageCRO AwarenessSliderMobile Responsive HousekeepingFeature List
255 lines · 9.2 KB
Setup 5–10 minutes 5 min read 255 lines
Key features
  • Touch-swipe and drag navigation functionality for mobile users
  • Automatic cycling (autoplay) with smooth CSS transitions
  • Custom pagination dots with active state styling
  • Responsive card layout with flexbox and maximum width constraints
Best use cases
  • Highlighting three key product benefits on a mobile product page.
  • Displaying a concise 'How it Works' section with visual aids.
  • Showcasing press mentions or quick customer value propositions.
Compatibility
  • Most Shopify themes
  • Shopify Online Store 2.0

The code

Shopify Liquid
1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Responsive Slider</title>
8 <style>
9 #v3-slider-container {
10 overflow: hidden;
11 position: relative;
12 padding: 20px 5px;
13 max-width: 1500px;
14 margin-right: auto;
15 margin-left: auto;
16 }
17
18 @media only screen and (min-width: 768px) {
19 #v3-slider-container {
20 width: max-content;
21 }
22 }
23
24 #v3-slider {
25 display: flex;
26 transition: transform 0.5s ease-in-out;
27 padding: 5px;
28 }
29
30 .v3-slider-card {
31 flex: 0 0 80%;
32 max-width: 300px;
33 height: max-content;
34 display: flex;
35 flex-direction: column;
36 background-color: #fff;
37 border: 1px solid #e0e0e0;
38 border-radius: 10px;
39 box-sizing: border-box;
40 gap: 10px;
41 transition: transform 0.3s ease;
42 justify-content: space-around;
43 margin-right: 10px;
44 }
45
46 #v3-pagination {
47 display: flex;
48 justify-content: center;
49 margin-top: 10px;
50 display: none;
51 }
52
53 .v3-pagination-dot {
54 width: 18px;
55 height: 6px;
56 background-color: #0d437d29;
57 cursor: pointer;
58 }
59
60 .v3-pagination-dot.active {
61 background-color: #f05454;
62 width: 22px;
63 border-radius: 5px;
64 }
65
66 .content-container {
67 padding: 10px;
68 }
69
70 .feature-title {
71 margin: 0px;
72 font-weight: 700;
73 color: #203E5C;
74 }
75
76 .feature-image {
77 border-top-right-radius: 10px;
78 border-top-left-radius: 10px;
79 }
80
81 .feature-description {
82 font-size: 15px;
83 font-weight: 500;
84 }
85 </style>
86</head>
87
88<body>
89 <div id="v3-slider-container">
90 <div id="v3-slider">
91 <div class="v3-slider-card">
92
93 <img src="//www.moonpod.co/cdn/shop/files/1_16.jpg?v=1720630615" class="feature-image">
94 <div class="content-container">
95 <h3 class="feature-title"><span>Relaxing Comfort</span></h3>
96 <p class="feature-description"><span>Thousands of high density beads conform to every inch of your body, mimicking floatation therapy, a known treatment for reducing stress and anxiety.</span></p>
97 </div>
98
99 </div>
100 <div class="v3-slider-card">
101
102 <img src="//www.moonpod.co/cdn/shop/files/2_13.jpg?v=1720630634" class="feature-image">
103 <div class="content-container">
104 <h3 class="feature-title"><span>Upgraded Leisure</span></h3>
105 <p class="feature-description"><span>People love to Moon Pod together. Our beads do the work, so it's easier to with loved ones. Reading, napping and gaming are all better on a Moon Pod.</span></p>
106 </div>
107
108
109 </div>
110 <div class="v3-slider-card">
111
112 <img src="//www.moonpod.co/cdn/shop/files/3_14.jpg?v=1720630634" class="feature-image">
113 <div class="content-container">
114 <h3 class="feature-title"><span class="metafield-single_line_text_field">Elevated Relaxation</span></h3>
115 <p class="feature-description"><span class="metafield-multi_line_text_field">Unparalleled support meets adaptive flexibility, relieving tension and joint pain while you relax. the perfect amount of structure for all shapes and sizes.</span></p>
116 </div>
117
118
119 </div>
120 </div>
121 <div id="v3-pagination"></div>
122 </div>
123
124 <script>
125 let sliderInitialized = false;
126
127 class ResponsiveSlider {
128 constructor(containerId, sliderId, paginationId) {
129 this.container = document.getElementById(containerId);
130 this.slider = document.getElementById(sliderId);
131 this.pagination = document.getElementById(paginationId);
132 this.cards = Array.from(this.slider.children);
133 this.cardWidth = this.cards[0].offsetWidth + 10; // Includes margin
134 this.totalWidth = this.cardWidth * this.cards.length - 10; // Adjust total width
135 this.containerWidth = this.slider.parentElement.offsetWidth;
136 this.currentIndex = 0;
137 this.isDragging = false;
138 this.startX = 0;
139 this.currentTranslate = 0;
140 this.prevTranslate = 0;
141 this.animationID = null;
142
143 this.init();
144 }
145
146 init() {
147 this.createPagination();
148 this.addEventListeners();
149 this.startAutoplay();
150 }
151
152 updatePagination() {
153 this.pagination.querySelectorAll('.v3-pagination-dot').forEach((dot, index) => {
154 dot.classList.toggle('active', index === this.currentIndex);
155 });
156 }
157
158 goToSlide(index) {
159 this.currentIndex = index;
160 const maxOffset = Math.max(this.totalWidth - this.containerWidth, 0); // Prevent gaps
161 const offset = Math.min(this.currentIndex * this.cardWidth, maxOffset);
162 this.slider.style.transition = 'transform 0.5s ease';
163 this.slider.style.transform = `translateX(-${offset}px)`;
164 this.currentTranslate = -offset;
165 this.prevTranslate = this.currentTranslate;
166 this.updatePagination();
167 }
168
169 createPagination() {
170 const totalSlides = this.cards.length;
171 this.pagination.innerHTML = '';
172 for (let i = 0; i < totalSlides; i++) {
173 const dot = document.createElement('div');
174 dot.classList.add('v3-pagination-dot');
175 dot.innerHTML = '&#8203;'; // Add zero-width space to prevent being treated as empty
176 if (i === 0) dot.classList.add('active');
177 dot.addEventListener('click', () => this.goToSlide(i));
178 this.pagination.appendChild(dot);
179 }
180 }
181
182 autoplay() {
183 this.currentIndex = (this.currentIndex + 1) % this.cards.length;
184 this.goToSlide(this.currentIndex);
185 }
186
187 startAutoplay() {
188 setInterval(() => this.autoplay(), 3000);
189 }
190
191 startDrag(event) {
192 this.isDragging = true;
193 this.startX = this.getPositionX(event);
194 this.slider.style.transition = 'none';
195 cancelAnimationFrame(this.animationID);
196 }
197
198 endDrag() {
199 this.isDragging = false;
200 const movedBy = this.currentTranslate - this.prevTranslate;
201 if (movedBy < -50 && this.currentIndex < this.cards.length - 1) {
202 this.currentIndex++;
203 }
204 if (movedBy > 50 && this.currentIndex > 0) {
205 this.currentIndex--;
206 }
207 this.goToSlide(this.currentIndex);
208 }
209
210 drag(event) {
211 if (this.isDragging) {
212 const currentPosition = this.getPositionX(event);
213 this.currentTranslate = this.prevTranslate + currentPosition - this.startX;
214 this.slider.style.transform = `translateX(${this.currentTranslate}px)`;
215 }
216 }
217
218 getPositionX(event) {
219 return event.type.includes('mouse') ? event.pageX : event.touches[0].clientX;
220 }
221
222 addEventListeners() {
223 this.slider.addEventListener('mousedown', (e) => this.startDrag(e));
224 this.slider.addEventListener('touchstart', (e) => this.startDrag(e));
225 this.slider.addEventListener('mouseup', () => this.endDrag());
226 this.slider.addEventListener('touchend', () => this.endDrag());
227 this.slider.addEventListener('mousemove', (e) => this.drag(e));
228 this.slider.addEventListener('touchmove', (e) => this.drag(e));
229 window.addEventListener('resize', () => {
230 this.slider.style.transform = 'translateX(0)';
231 this.currentIndex = 0;
232 this.updatePagination();
233 });
234 }
235 }
236
237 function initializeSlider() {
238 if (!sliderInitialized && window.innerWidth < 768) {
239 new ResponsiveSlider('v3-slider-container', 'v3-slider', 'v3-pagination');
240 sliderInitialized = true;
241 } else if (sliderInitialized && window.innerWidth >= 768) {
242 sliderInitialized = false;
243 document.getElementById('v3-slider').style.transform = 'translateX(0)';
244 document.getElementById('v3-pagination').innerHTML = '';
245 }
246 }
247
248 initializeSlider();
249
250 window.addEventListener('resize', initializeSlider);
251 </script>
252
253</body>
254
255</html>

How to install 3 info sliders with images on your Shopify theme

This snippet belongs in sections/main-product.liquid, directly under the Add to cart button, where it reinforces the purchase decision. Expect the whole job to take about 5–10 minutes.

  1. 1From your Shopify admin, open Online Store → Themes, click the button on your live theme and choose Duplicate. Always work on a copy so you can roll back instantly.
  2. 2On the duplicated theme, click … → Edit code to open the theme code editor.
  3. 3Open sections/main-product.liquid in the file tree. If your theme uses different file names, search for the template that renders the area where you want the block to show up.
  4. 4Click Copy code on this page, then paste the snippet directly under the Add to cart button, where it reinforces the purchase decision.
  5. 5The snippet ships with its own scoped <style> block, so you do not need to touch base.css or theme.css. If you prefer to keep CSS centralised, move the contents of the style tag into your theme stylesheet and delete the inline block.
  6. 6Keep the <script> tag at the end of the snippet. It only runs once the surrounding markup exists in the DOM, so moving it higher up the file can break the behaviour.
  7. 7Click Save, then hit Preview and check the block on desktop, tablet and mobile widths.
  8. 8When you are happy with the result, publish the duplicated theme from Online Store → Themes → Actions → Publish.

How to customise it

Every value below lives inside the snippet, so you can adapt 3 info sliders with images to your brand without touching the rest of the theme.

  • Colours — the snippet uses #fff, #e0e0e0, #f05454, #203E5C. Replace those values inside the style block with your brand palette, keeping at least a 4.5:1 contrast ratio between text and background so the block stays accessible.
  • Sizing — adjust the font-size values (15px) and the padding so the block carries the same visual weight as the elements around it.
  • Cornersborder-radius: 10px controls the roundness. Set it to 0 for a sharper editorial look, or increase it for a softer, app-like feel.
  • Images — replace the placeholder image URLs with your own assets. Upload them under Content → Files in Shopify admin and use the generated CDN URL, or reference a theme asset with {{ 'my-image.png' | asset_url }}.
  • Copy — rewrite the hard-coded text (for example “Responsive Slider”) in your own brand voice, and translate it if you sell in more than one language.
  • Timing — the countdown duration is set in the script. Change the target time or the interval value to control how long the offer runs before it resets.
  • Responsive behaviour — the @media query defines the mobile breakpoint. Adjust the pixel value if your theme uses a different breakpoint scale.

Common mistakes to avoid

These are the issues merchants run into most often when installing a snippet like this one.

  • Editing the live theme directly. Duplicate it first — a single unbalanced Liquid tag can take a storefront down mid-campaign.
  • Pasting the code into the wrong file. Dropped into layout/theme.liquid instead of sections/main-product.liquid, this block will render on every page of the store, including ones where it makes no sense.
  • Renaming the CSS classes in the markup but not in the style block, or vice versa. The class names have to match exactly or the styling silently disappears.
  • Adding the snippet twice on the same page. The script targets its selector, so two copies can conflict or double-fire.
  • Running a countdown that resets on every page load and never actually expires. Shoppers notice fake urgency, and in the EU and UK it can breach consumer-protection rules.
  • Publishing without testing on a real phone. Most Shopify traffic is mobile, and layout problems almost always surface there first.

Performance notes

What this block costs you in load time, and how to keep that cost at zero.

  • The CSS is inline and scoped to this block, so it adds no extra network request. At a few kilobytes it has no measurable effect on your Lighthouse score.
  • The JavaScript is vanilla — no jQuery, no external library, no additional request. Keep it after the markup so it never blocks rendering.
  • Add loading="lazy" plus explicit width and height attributes to every image in the snippet. That prevents Cumulative Layout Shift, which is a Core Web Vitals ranking factor.
  • Run PageSpeed Insights before and after you add the block so you have a concrete number rather than a guess.

SEO & accessibility

How to add this block without damaging your on-page structure or your rich results.

  • Nothing in this snippet should replace your page <h1>. Keep product and page headings intact and use <h2> or <h3> for the block's own heading so the document outline stays clean.
  • Write a descriptive alt attribute for every image. Empty or generic alt text is one of the most common accessibility and SEO issues on Shopify stores.
  • If the block shows review or rating content, keep it consistent with the structured data your review app already outputs. Duplicating or contradicting rating markup can cost you the rich result entirely.
  • The block does not create a new URL, so there is no canonical or indexing change to make. It improves on-page engagement signals rather than crawlability.
Frequently asked questions

3 info sliders with images — questions merchants ask

Will this snippet work with my theme?

It is built with standard Liquid, HTML and CSS, so it works with Dawn and virtually every Online Store 2.0 theme, as well as most vintage themes. The only thing that changes between themes is the file you paste it into — if yours has no sections/main-product.liquid, look for the equivalent template that renders the same area.

Do I need an app to use it?

No. This is theme code you own outright: no monthly fee, no third-party script tag, and no app that can break your storefront the next time it updates.

How long does it take to add “3 info sliders with images” to a store?

Most merchants have it live in under fifteen minutes — duplicate the theme, paste the code, adjust the colours and copy, preview on mobile, publish.

The block appears but nothing happens. What is wrong?

That is almost always a script-order problem. Check that the script tag is still at the bottom of the snippet and that the markup was not pasted inside another script or a Liquid comment block. Open your browser console and look for an error naming the snippet's selector.

The styling looks broken after pasting. How do I fix it?

Confirm you copied the whole snippet including the closing style tag, then check whether one of your theme's own CSS rules is overriding it. If a theme rule wins, increase the specificity of the snippet's selector rather than scattering !important through the file.

Will it slow my store down?

Not meaningfully. It is inline markup with scoped CSS and at most a few lines of vanilla JavaScript — no external libraries, no extra HTTP request. Optimising your product images will always have a far bigger impact on load time.

Can I use it on a client store or a commercial project?

Yes. Every snippet in the MCO Hub library is free to copy, modify and ship on any store, including client work. Attribution is appreciated but not required.

Related snippets

Keep exploring