Overview
Before/after image slider displays two images (“Before” and “After”) with a draggable range input to reveal more/less of each image.
Optionally, you can add content blocks (heading/text/buttons) beside the slider, similar to an “Image with text” content column.
Key features
Interactive drag slider (range input) to compare before vs after images.
Optional labels on each image (Before/After text) with customizable:
text
color
position
size
Optional content column (blocks) with:
heading, caption, rich text, button
Multiple section widths:
grid / full / full bleed behaviors
Supports section box layout (boxed background).
RTL/LTR aware via
{% render 'direction' %}.
Assets loaded
Always:
section-before-after-image-slider.css
Only when the section has blocks (content column exists):
component-image-with-text.css
JS (only outside Theme Editor):
before-after-image-slider.js(deferred)
(In design mode, script is skipped—likely to avoid duplicate initialization / editor conflicts.)
Layout logic
Container + heading
Top wrapper class depends on enable_section_box_layout:
If NOT boxed:
Wrapper gets
color-{{ color_scheme }} gradientHeading is rendered inside:
.page-width(and optionally--fulldepending on section width)
If boxed:
Outer wrapper becomes
page-width(and maybe--full)A nested
.section__boxcarriescolor_scheme+ heading + content
Section width handling (section.settings.section_width)
Used in a few places:
If
section_width != 'grid':outer container and heading wrapper get
page-width--full
If
section_width == 'full_bleed':the slider does not get
card-radius overflow-hidden(so it can bleed edge-to-edge)content positioning classes add special modifiers to handle content order
Optional content column (blocks)
When section.blocks.size > 0:
Wrapper gets:
ba-image-slider-inner--has-contentContent container:
#ImageWithText--{{ section.id }}classes are aligned with your image-with-text system:
desktop content position:
image-with-text__content--{{ desktop_content_position }}desktop alignment:
image-with-text__content--desktop-{{ desktop_content_alignment }}mobile alignment:
image-with-text__content--mobile-{{ mobile_content_alignment }}
Desktop order toggle
If show_content_first_in_desktop is false:
wrapper adds
ba-image-slider-inner--content-aftercontent container may get
ba-image-slider-content--content-after(only whenfull_bleed)
If true:
content shows first on desktop, and in
full_bleedmode it addsba-image-slider-content--content-first.
Supported blocks
heading
heading,heading_sizeoptional bold:
enable_bold_headingoptional gradient style if
section.settings.gradient_headingis set
caption
captiontext_style+text_sizeuppercase if style is
caption-with-letter-spacing
text
rich text via
block.settings.textstyle via
text_style
button
button_label,button_link,button_styleif
button_style == 'link'uses a link-with-icon pattern + chevron icon
Slider component
Main element:
<before-after-image-slider class="ba-image-slider ba-image-slider--{{ direction }} ...">Direction
direction comes from {% render 'direction' %} (commonly used for RTL/LTR).
Your CSS likely uses .ba-image-slider--rtl vs .ba-image-slider--ltr to flip behavior.
CSS variables passed inline
--image-height: {{ image_height }}0px;Note: this is intentionally
value + "0px"(so 45 becomes 450px).
That means your setting probably stores “45” but you want 450px.
Just make sure the schema label reflects that (e.g., “Height (x10 px)” or store 450 directly).
Drag cursor colors (RGB):
--drag-cursor-foreground: r, g, b--drag-cursor-background: r, g, b
Before / After images
Each side is a use-animate media element:
Adds
ba-image-slider__image--containifimage_fit == 'contain'.Uses placeholders if image is blank:
before:
hero-apparel-1after:
hero-apparel-2
Images are output with loading: 'lazy' and responsive widths list.
Optional labels on images
If before_text is set:
Renders a
<span>overlay with:color via CSS variable
--color-foreground: r,g,bposition via:
{{ before_text_position }}: var(--text-position-value);(so
before_text_positionmust be a CSS property name likeleft/right/top/bottom)
Same logic for after_text.
Label size:
{{ section.settings.text_size }}class
Drag handle UI
Decorative handle icon inside
.ba-image-slider__slider-buttonActual control:
<input type="range" min="0" max="100" value="50" ... aria-label="{{ accessibility_info }}">
So accessibility is covered via accessibility_info.
Padding + section heading styles
Same pattern as your other sections:
mobile padding = 0.75× values
desktop padding = full values (≥ 750px)
includes your shared
section-heading-stylessnippet
Notes / potential pitfalls
--image-height: {{ image_height }}0pxcan be confusing for merchants. If your schema setting is “45”, they won’t expect 450px. Consider:store real px in setting, or
rename label to make scaling obvious.
The slider JS is skipped in design mode; if you want it interactive in the editor, you’d need a safe init that won’t conflict with Shopify editor reloads.
Comments
0 comments
Please sign in to leave a comment.