Unlocking Mobile-Friendly Slideshows: Your Shopify Horizon Theme Guide

Hey fellow store owners! Let's talk about a common head-scratcher that recently popped up in the Shopify community – something many of us have likely grappled with, especially if you're running a sleek Horizon theme. Our friend Pawthena kicked off a really insightful discussion about the "Limitations with Shopify Horizon Themes," specifically around the slideshow section.

The Slideshow Dilemma: Why Isn't It Like the Hero Section?

Pawthena hit the nail on the head: while Shopify's Hero section often gives us fantastic control over mobile-specific images and height, the Slideshow section in many themes (including Horizon, it seems) doesn't always play along. This means designing banners that look perfect on both desktop and mobile can be a real headache. You want that killer desktop image, but you also need a distinct, optimized mobile version, and you probably want to dictate the height of your slides. It's a totally reasonable expectation!

As Pawthena clarified, it wasn't just one type of slideshow; all variations seemed to share this limitation. So, what's a store owner to do when native features fall short?

Community to the Rescue: Clever Workarounds & Code Solutions

The good news? Our incredible Shopify community is full of smart folks who've figured out some solid workarounds. The discussion quickly pivoted from "this is a limitation" to "here's how we fix it." Let's dive into the most actionable solutions that emerged.

Method 1: The Responsive CSS Hide/Show Trick (Less Invasive)

One of the most popular and generally recommended approaches, as detailed by Wsp and echoed by Maximus3 and tim_tairli, involves using responsive CSS. The core idea is simple: you include both your desktop and mobile images within the same slideshow slide, then use CSS to hide one or the other based on the screen size. This keeps your theme code changes minimal, which is always a plus!

Here's how you can implement this solution:

  1. Prepare Your Images: For each slide, make sure you have both a desktop-optimized image and a mobile-optimized image ready to go.
  2. Edit Your Theme Code (slideshow.liquid or similar):

    Go to your Shopify Admin > Online Store > Themes > Actions > Edit Code. You'll typically be looking for a file like sections/slideshow.liquid or a block file like blocks/_slide.liquid (depending on your theme structure). You'll need to find where the image is rendered for each slide and add both image tags, wrapped in specific classes. Wsp provided a great example:

    
    

    You'll replace the src="" with your actual image URLs (using Liquid tags like {{ block.settings.desktop_image | image_url }} if you add new image pickers to your slide schema, or by directly uploading and referencing them if you're doing a quick manual fix).

  3. Add CSS for Responsiveness (base.css or theme.css):

    Next, find your main CSS file, often located at assets/base.css or assets/theme.css. Add the following CSS rules:

    .mobile-img {
      display: none;
    }
    
    @media screen and (max-width: 749px) {
      .desktop-img {
        display: none;
      }
    
      .mobile-img {
        display: block;
      }
    }

    This CSS snippet does exactly what we need: on screens 749px wide or smaller (typical mobile breakpoint), it hides the desktop image and shows the mobile image. On larger screens, the mobile image remains hidden.

Method 2: Deeper Theme File Modification for Integrated Settings

Moeed provided a more comprehensive solution that actually integrates the mobile image and video options directly into your slideshow block's settings. This is fantastic because it means you can manage these images right from the theme customizer, similar to how the Hero section works. It's a more involved code change, as it replaces an entire block file, but it offers a more "native" feel.

Moeed's Step-by-Step for _slide.liquid:

  1. Go to Online Store: In your Shopify Admin, navigate to Online Store.
  2. Edit Code: Click on "Actions" next to your theme, then "Edit code."
  3. Find _slide.liquid: In the file explorer, look for the blocks folder and find the _slide.liquid file.
  4. Replace the Code: Replace the entire content of that file with the code Moeed provided. Important: Always back up your theme before making such extensive changes!
{% assign block_settings = block.settings %}
{%- assign block_index = section.blocks | find_index: 'id', block.id -%}
{%- assign secti -%}

{% capture children %}
  {% liquid
    assign preview_image = block_settings.image_1
    if block_settings.media_type_1 == 'video'
      assign preview_image = block_settings.video_1.preview_image
    endif

    assign rounded_image_corners = false
    if block_settings.inherit_color_scheme == true or block_settings.inherit_color_scheme == false and section.settings.color_scheme.settings.background.rgb == block_settings.color_scheme.settings.background.rgb
      assign rounded_image_corners = true
    endif
  %}
  {% if section.settings.slide_height == 'adapt_image' and block_index == 0 and preview_image != blank %}
    {%
      # Great example of why it can be helpful for a section to be able to read the settings of its direct child blocks.
      # In this case, we want the section to be able to read the image aspect ratio of the first slide and apply it to the slideshow slides and slides.
    %}
    {% style %}
      .shopify-section-{{ section.id }} slideshow-slides,
      .shopify-section-{{ section.id }} slideshow-slide {
        min-height: {{ 1 | divided_by: preview_image.aspect_ratio | times: 100 }}vw;
      }
    {% endstyle %}
  {% endif %}

  
{%- if block_settings.toggle_overlay -%} {% render 'overlay', settings: block_settings %} {%- endif -%} {%- if preview_image -%} {%- liquid assign height = preview_image.width | divided_by: preview_image.aspect_ratio | round assign media_width_desktop = '100vw' assign media_width_mobile = '100vw' assign sizes = '(min-width: 750px) ' | append: media_width_desktop | append: ', ' | append: media_width_mobile assign lazy_sizes = 'auto, ' | append: sizes assign widths = '832, 1200, 1600, 1920, 2560, 3840' %} {%- liquid assign loading = 'lazy' if block_index == 0 and section_index <= 3 assign loading = 'eager' assign sizes = lazy_sizes endif assign fetchpriority = 'low' if block_index == 0 and secti 1 assign fetchpriority = 'high' endif -%} {%- if block_settings.media_type_1 == 'image' -%} {%- if block_settings.mobile_image_1 != blank -%} {{ block_settings.image_1 | image_url: width: 3840 | image_tag: height: height, sizes: sizes, widths: widths, class: 'slide__image', loading: loading, fetchpriority: fetchpriority }} {%- else -%} {{ block_settings.image_1 | image_url: width: 3840 | image_tag: height: height, sizes: sizes, widths: widths, class: 'slide__image', loading: loading, fetchpriority: fetchpriority }} {%- endif -%} {%- else -%} {%- if block_settings.video_1.preview_image -%} {{ block_settings.video_1.preview_image | image_url: width: 3840 | image_tag: height: height, sizes: sizes, widths: widths, loading: loading, class: 'slide__video-poster', fetchpriority: fetchpriority }} {%- endif -%} {{ block_settings.video_1 | video_tag: poster: nil, autoplay: true, loop: true, controls: false, muted: true, class: 'slide__video' }} {%- endif -%} {%- else -%} {%- liquid assign modulo_result = block_index | modulo: 2 assign placeholder_variant = 2 | minus: modulo_result assign placeholder_name = 'hero-apparel-' | append: placeholder_variant -%} {{ placeholder_name | placeholder_svg_tag: 'slide__image' }} {%- endif -%}
{% content_for 'blocks' %}
{% endcapture %} {%- capture class -%} {%- if block_settings.inherit_color_scheme == false -%} color-{{ block_settings.color_scheme }} {%- endif -%} {%- endcapture -%} {% render 'slideshow-slide', index: block_index, class: class, children: children, attributes: block.shopify_attributes, slide_size: section.settings.slide_height, navigate_to_slide: true %} {% stylesheet %} .slide__content { height: 100%; position: relative; z-index: var(--layer-flat); @supports (animation-timeline: auto) { opacity: 0; animation: slide-reveal both linear; animation-timeline: var(--slideshow-timeline); } @media (prefers-reduced-motion) { opacity: 1; animation: none; } } .slide__content > * { margin: auto; } .slide__content.background-transparent { background-color: transparent; } slideshow-slide > .slide__image-container { display: flex; width: 100%; height: 100%; overflow: hidden; position: absolute; } .slide__image-container > picture { display: contents; } .slide__image-container > .slide__image, .slide__image-container > picture > .slide__image, .slide__image-container > .slide__video, .slide__image-container > .slide__video-poster { position: relative; width: 100%; height: 100%; object-fit: cover; object-position: center center; } .slide__image-container > .slide__video-poster { position: absolute; } /* * Force Safari to recalculate the timeline state on timeline refresh (after loop) */ slideshow-component[refreshing-timeline] .slide__content { animation: none; } slideshow-slide .slide__image-container--rounded { border-radius: var(--corner-radius, 0); } {% endstylesheet %} {% schema %} { "name": "t:names.slide", "tag": null, "blocks": [ { "type": "_heading" }, { "type": "button" }, { "type": "text" }, { "type": "group" }, { "type": "image" }, { "type": "video" }, { "type": "icon" }, { "type": "jumbo-text" }, { "type": "@theme" }, { "type": "@app" } ], "settings": [ { "type": "select", "id": "media_type_1", "label": "t:settings.type", "options": [ { "value": "image", "label": "t:options.image" }, { "value": "video", "label": "t:options.video" } ], "default": "image" }, { "type": "image_picker", "id": "image_1", "label": "t:settings.image", "visible_if": "{{ block.settings.media_type_1 == 'image' }}" }, { "type": "image_picker", "id": "mobile_image_1", "label": "Mobile image", "visible_if": "{{ block.settings.media_type_1 == 'image' }}" }, { "type": "video", "id": "video_1", "label": "t:settings.video", "visible_if": "{{ block.settings.media_type_1 == 'video' }}" }, { "type": "header", "content": "t:content.layout" }, { "type": "select", "id": "content_direction", "label": "t:settings.direction", "options": [ { "value": "column", "label": "t:options.vertical" }, { "value": "row", "label": "t:options.horizontal" } ], "default": "column" }, { "type": "checkbox", "id": "vertical_on_mobile", "label": "t:settings.vertical_on_mobile", "default": true, "visible_if": "{{ block.settings.c 'row' }}" }, { "type": "select", "id": "horizontal_alignment", "label": "t:settings.alignment", "options": [ { "value": "flex-start", "label": "t:options.left" }, { "value": "center", "label": "t:options.center" }, { "value": "flex-end", "label": "t:options.right" }, { "value": "space-between", "label": "t:options.space_between" } ], "default": "flex-start", "visible_if": "{{ block.settings.c 'row' }}" }, { "type": "select", "id": "vertical_alignment", "label": "t:settings.position", "options": [ { "value": "flex-start", "label": "t:options.top" }, { "value": "center", "label": "t:options.center" }, { "value": "flex-end", "label": "t:options.bottom" } ], "default": "center", "visible_if": "{{ block.settings.c 'row' }}" }, { "type": "checkbox", "id": "align_baseline", "label": "t:settings.align_baseline", "default": false, "visible_if": "{{ block.settings.vertical_alignment == 'flex-end' }}" }, { "type": "select", "id": "horizontal_alignment_flex_direction_column", "label": "t:settings.alignment", "options": [ { "value": "flex-start", "label": "t:options.left" }, { "value": "center", "label": "t:options.center" }, { "value": "flex-end", "label": "t:options.right" } ], "default": "flex-start", "visible_if": "{{ block.settings.content_direction != 'row' }}" }, { "type": "select", "id": "vertical_alignment_flex_direction_column", "label": "t:settings.position", "options": [ { "value": "flex-start", "label": "t:options.top" }, { "value": "center", "label": "t:options.center" }, { "value": "flex-end", "label": "t:options.bottom" }, { "value": "space-between", "label": "t:options.space_between" } ], "default": "center", "visible_if": "{{ block.settings.c 'column' }}" }, { "type": "range", "id": "gap", "label": "t:settings.gap", "min": 0, "max": 100, "step": 1, "unit": "px", "default": 12 }, { "type": "header", "content": "t:content.appearance" }, { "type": "checkbox", "id": "inherit_color_scheme", "label": "t:settings.inherit_color_scheme", "default": true }, { "type": "color_scheme", "id": "color_scheme", "label": "t:settings.color_scheme", "default": "scheme-1", "visible_if": "{{ block.settings.inherit_color_scheme == false }}" }, { "type": "checkbox", "id": "toggle_overlay", "label": "t:settings.media_overlay" }, { "type": "color", "id": "overlay_color", "label": "t:settings.overlay_color", "alpha": true, "default": "#00000026", "visible_if": "{{ block.settings.toggle_overlay }}" }, { "type": "select", "id": "overlay_style", "label": "t:settings.overlay_style", "options": [ { "value": "solid", "label": "t:options.solid" }, { "value": "gradient", "label": "t:options.gradient" } ], "default": "solid", "visible_if": "{{ block.settings.toggle_overlay }}" }, { "type": "select", "id": "gradient_direction", "label": "t:settings.gradient_direction", "options": [ { "value": "to top", "label": "t:options.up" }, { "value": "to bottom", "label": "t:options.down" } ], "default": "to top", "visible_if": "{{ block.settings.toggle_overlay and block.settings.overlay_style == 'gradient' }}" }, { "type": "header", "content": "t:content.padding" }, { "type": "range", "id": "padding-block-start", "label": "t:settings.top", "min": 0, "max": 100, "step": 1, "unit": "px", "default": 0 }, { "type": "range", "id": "padding-block-end", "label": "t:settings.bottom", "min": 0, "max": 100, "step": 1, "unit": "px", "default": 0 }, { "type": "range", "id": "padding-inline-start", "label": "t:settings.left", "min": 0, "max": 100, "step": 1, "unit": "px", "default": 0 }, { "type": "range", "id": "padding-inline-end", "label": "t:settings.right", "min": 0, "max": 100, "step": 1, "unit": "px", "default": 0 } ], "presets": [ { "name": "t:names.slide", "settings": { "horizontal_alignment_flex_direction_column": "center", "inherit_color_scheme": false, "color_scheme": "scheme-6", "padding-inline-start": 48, "padding-inline-end": 48, "padding-block-start": 48, "padding-block-end": 48 }, "blocks": { "heading": { "type": "text", "name": "t:names.heading", "settings": { "text": "t:html_defaults.new_arrivals_h3" } }, "text": { "type": "text", "settings": { "text": "t:html_defaults.latest_products", "padding-block-end": 20 } }, "button": { "type": "button", "settings": { "label": "t:text_defaults.shop_now_button_label", "link": "shopify://collections/all" } } }, "block_order": ["heading", "text", "button"] } ] } {% endschema %}

This code adds a new mobile_image_1 picker to your slide settings, allowing you to upload a separate image specifically for mobile. It also includes logic for video and handles image aspect ratios to help with height control. Moeed even shared a screenshot of the result, which looks great:

Other Considerations: Two Sections or Custom Development

Maximus3 and tim_tairli also brought up another valid approach: creating two entirely separate sections for your slideshow – one configured for desktop and one for mobile – and then using CSS to hide each one based on screen size. This keeps your core theme files untouched, but it means managing two sections in the theme customizer for every slideshow, which can be a bit more cumbersome.

For ultimate flexibility, Maximus3 suggested a custom section. If you need highly specific functionality beyond just mobile images and height, hiring a developer to build a bespoke slideshow section might be the best route. Shopify Sidekick can be a useful tool here for developers to grab existing section code as a starting point.

A Word on Confidence (and When to Call for Backup)

Pawthena admitted to not being "fully confident in code," which is totally understandable! Modifying theme files can feel daunting, and ProtoMan44 wisely advised that if you're not confident, it might be better to hire a Shopify expert. Even small syntax errors can break your site, so when in doubt, it's always smart to seek professional help or thoroughly test changes on a duplicate theme first.

So, there you have it! While Shopify's Horizon themes might not offer native mobile image options for slideshows right out of the box, the community has stepped up with some excellent solutions. Whether you opt for the simpler CSS hide/show, Moeed's more integrated code modification, or even a custom section, you don't have to be limited to a single Hero section. Just remember to back up your theme, test thoroughly, and don't hesitate to ask for help if you get stuck!

Share:

Use cases

Explore use cases

Agencies, store owners, enterprise — find the migration path that fits.

Explore use cases