jekyll-before-after
August 22, 2026 · View on GitHub
A Jekyll plugin providing a {% before_after %} Liquid tag for rendering a polished, accessible drag-to-reveal image comparison slider. Supports horizontal and vertical orientations, overlay labels, responsive images, keyboard navigation, and full CSS custom property theming. Pure vanilla JS — no external dependencies, GitHub Pages compatible.
Installation
Add to your Gemfile:
gem "jekyll-before-after"
Add to _config.yml:
plugins:
- jekyll-before-after
Copy _before-after.scss to your site's CSS directory and import it.
Run bundle install.
Usage
{% before_after
before="/images/main-street-2018.jpg"
after="/images/main-street-2024.jpg"
before_label="2018"
after_label="2024"
%}
All options
| Option | Default | Description |
|---|---|---|
before | (required) | Path to the "before" image |
after | (required) | Path to the "after" image |
before_label | "Before" | Label overlaid on the before side |
after_label | "After" | Label overlaid on the after side |
start | 50 | Initial slider position (0–100) |
orientation | horizontal | horizontal or vertical |
alt_before | "" | Alt text for the before image |
alt_after | "" | Alt text for the after image |
srcset_before | "" | srcset value for responsive before image |
srcset_after | "" | srcset value for responsive after image |
sizes | "(max-width: 768px) 100vw, 100vw" | sizes attribute when using srcset |
Responsive images
Pass srcset_before and srcset_after to render a <picture> element:
{% before_after
before="/images/street-before.jpg"
after="/images/street-after.jpg"
srcset_before="/images/street-before-480.jpg 480w, /images/street-before-960.jpg 960w"
srcset_after="/images/street-after-480.jpg 480w, /images/street-after-960.jpg 960w"
sizes="(max-width: 600px) 100vw, 80vw"
%}
Vertical orientation
{% before_after
before="/images/building-2015.jpg"
after="/images/building-2025.jpg"
orientation=vertical
before_label="2015"
after_label="2025"
%}
Multiple sliders
Multiple sliders on the same page are fully supported. The JavaScript block is emitted only once per page regardless of how many sliders you include.
Configuration
Set site-wide defaults in _config.yml:
before_after:
start: 50
orientation: horizontal
before_label: "Before"
after_label: "After"
Styling
Copy _before-after.scss to your project and import it. All visual properties are controlled via CSS custom properties:
| Variable | Default | Description |
|---|---|---|
--ba-handle-color | #fff | Handle line and knob color |
--ba-knob-size | 2.75rem | Drag knob diameter |
--ba-knob-icon-color | #333 | Arrow icon color inside knob |
--ba-line-width | 2px | Divider line thickness |
--ba-label-bg | rgba(0,0,0,0.55) | Label background |
--ba-label-color | #fff | Label text color |
--ba-label-radius | 3px | Label border radius |
--ba-radius | 4px | Container border radius |
--ba-focus-ring | rgba(255,255,255,0.8) | Keyboard focus ring color |
Example override
.before-after {
--ba-handle-color: #e67e22;
--ba-knob-size: 3rem;
--ba-label-bg: rgba(0, 0, 0, 0.75);
}
Interaction
- Drag the handle to reveal
- Click anywhere on the image to jump the slider to that position
- Keyboard: focus the handle and use arrow keys (5% steps; hold Shift for 1% steps)
- Touch and stylus supported via Pointer Events API
Requirements
- Jekyll >= 3.9
- Ruby >= 2.7
License
MIT — see LICENSE.txt.