Gallery✨ Premium

Fade Slider

Crossfade slideshow: the image on screen fades out while the next one fades in at the same place, with no movement at all. Arrows, keyboard and swipe.

CSSOpacityFade

Updated

This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Gallery has 44 effects, including 6 free. Explore the category →

3 usage examples

One living room under three lightings — product page of a floor lamp maker — Fade Slider example 1

① One living room under three lightings — product page of a floor lamp maker

WhenOn the lamp's page, the visitor clicks › to see the same room in the morning, in the evening and lit for reading; the mood pill and the sentence under the price follow the image.
WhyThe three photos share exactly the same framing: with a crossfade, only what changes moves on screen, the light. A sideways slide would scroll the sofa and the wall, and the eye would lose the very difference you want to show.
SettingsFrame 300 px wide fitted to the column: --fdsl-width:100%, --fdsl-height:100%, --fdsl-radius:14px, dark arrows --fdsl-arrow-bg:rgba(30,26,22,.38), frame with no background or padding. Photos as <img>. In the capture, the scene script clicks › every 1.5 s.
Five-day forecast — small widget on a building-site dashboard — Fade Slider example 2

② Five-day forecast — small widget on a building-site dashboard

WhenThe site manager flips through the days in the weather tile, next to the task list; the strip under the widget switches from "OK to pour concrete" to "Do not pour: rain" depending on the day shown.
WhyIn a 176 px tile, a slide would push the icon out through the edge; the fade swaps one day for the next without moving the layout, like a display board. The advice read under the widget depends on the visible day, so on the slideshow's state.
Settings--fdsl-height:160px, --fdsl-ratio:auto, --fdsl-radius:10px, night-blue background set by the page, transparent slides, 26 px arrows moved to the top by the scene CSS. Each slide holds an <img> icon and text. Capture: click on › every 1.3 s.
An offshore race story on mobile — one chapter per screen — Fade Slider example 3

③ An offshore race story on mobile — one chapter per screen

WhenThe reader swipes left on the photo: the dawn start fades into the squall, then into the night and the finish; the bars at the top of the screen and the chapter list move on with them.
WhyOn a phone, the expected gesture in a story told in screens is the swipe. The fade gives the pace of a photo slideshow rather than a list: each chapter replaces the previous one entirely, title included.
SettingsFull screen: --fdsl-height:100%, --fdsl-radius:21px, no arrows in the HTML: on a phone the swipe is enough (without arrows nothing can take focus: to keep the ← → keys, add tabindex="0" to the .fdsl-carousel frame), caption moved to the bottom left. In the capture, the scene sends the real code a pointerdown then a pointerup 120 px further left; the white dot shows the gesture.

How it works

Nothing slides here: the .fdsl-slide elements are stacked on top of each other (position: absolute; inset: 0) inside .fdsl-track. Only one carries the is-active class; it goes to opacity 1 while the others drop to 0, with a 0.6 s transition. Meanwhile both images blend, which suits views taken from the same angle.

The script moves is-active from one slide to another. It reacts to clicks on .fdsl-prev and .fdsl-next, to the ← and → keys while focus is in the slideshow, and to a horizontal drag of more than 50 px (Pointer Events, finger or mouse). After the last image comes the first, and the other way round. The slideshow stays still as long as nobody acts.

To start on another image than the first, put is-active on a different slide in the HTML: the script picks it up on load. Your photos go in as an <img> inside the slide (cropped with object-fit: cover); an optional .fdsl-caption shows in the middle. The frame takes the available width up to 640 px, in a 16/10 format.

Several slideshows on a page each work on their own: the script attaches to every .fdsl-carousel, creates nothing on window and skips a block it has already prepared (data-fdsl-ready) if it runs a second time.

Accessibility

  • Announced structure: role="region", aria-roledescription="carousel" and an aria-label on the frame; each image becomes a "slide" group named "3 of 5".
  • Invisible images neutralised: slides at opacity 0 carry inert, aria-hidden and pointer-events: none; a link on a hidden photo can be neither clicked nor reached with the keyboard.
  • Screen readers: each change is said once by an invisible aria-live="polite" area ("slide 2 of 5").
  • Controls: native buttons labelled "Previous slide" and "Next slide", white focus ring, ← and → keys.
  • Reduced motion: with prefers-reduced-motion: reduce, the image changes at once, without the fade; navigation is untouched.

Browser compatibility

Under 4 KB of JavaScript, no library. Measured on 08/11/2026 (Playwright: Chromium, Firefox, WebKit): two slideshows side by side that do not respond to each other, code pasted twice without double wiring, Tab then Enter, arrow keys, finger swipe at 390 px in Chromium and mouse drag elsewhere, reduced motion, zero errors. Minimum versions from @mdn/browser-compat-data 8.1.8, set by the inert attribute.

Chrome 102+✓ Full (measured)
Firefox 112+✓ Full (measured)
Safari 15.5+✓ Full (measured in WebKit)
Edge 102+✓ Full (Chromium engine)
iOS Safari 15.5+✓ Not checked on a real device
Android Chrome 102+✓ Full (Chromium engine)

Without inert (older browsers), the fade works, but the content of a hidden image can still receive focus. Safari 14 has no aspect-ratio: set the height with --fdsl-height. JavaScript off: only the is-active slide from the HTML is visible.

The code

HTML structure to paste into your page (the CSS + JS come with your purchase):

index.html — structure
<div class="fx-0162-root">
  <div class="fdsl-carousel" role="region" aria-roledescription="carousel" aria-label="Slideshow" data-slide="slide" data-of="of">
    <div class="fdsl-track">
      <div class="fdsl-slide is-active"><span class="fdsl-caption">Slide 1</span></div>
      <div class="fdsl-slide"><span class="fdsl-caption">Slide 2</span></div>
      <!-- … one div.fdsl-slide per image (img optional) -->
    </div>
    <button type="button" class="fdsl-arrow fdsl-prev" aria-label="Previous slide"><svg>…</svg></button>
    <button type="button" class="fdsl-arrow fdsl-next" aria-label="Next slide"><svg>…</svg></button>
  </div>
</div>

One-time payment, no subscription — the code is yours forever

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
Fade duration (CSS — --fdsl-duration on .fx-0162-root) 0.6s 1s or more gives a slideshow dissolve; 0.3s a brisk change.
Width and format (CSS — --fdsl-width, --fdsl-ratio) 640px · 16 / 10 Maximum width of the frame and width/height ratio. 1 / 1 for square visuals.
Imposed height (CSS — --fdsl-height) auto A fixed height (160px) or 100% of the parent replaces the ratio-based height.
Starting image (HTML — is-active class) first slide Put is-active on the slide to show on load.
Arrow background and corners (CSS — --fdsl-arrow-bg, --fdsl-radius) white at 20% · 1rem On light images, a dark background (rgba(0,0,0,.4)) keeps the chevrons readable.
Showcase area (CSS — --fdsl-stage-bg, --fdsl-stage-padding, --fdsl-stage-min-height) #0a0a0f · 25px 16px · 300px Dark background and spacing of the demo; set transparent, 0, 0 in a real page.
Spoken announcement (HTML — data-slide, data-of, aria-label) slide · of · Slideshow Words used for "slide 2 of 5" and the slideshow's name; translate them for a page in another language.

FAQ

Both opacities change at the same time: halfway, the old one is at 50% and so is the new one, and the frame background (#12121a) shows through a little. Give the .fdsl-carousel frame a background close to your images, or shorten the duration with --fdsl-duration.
No, each one is cropped by object-fit: cover to fill the frame. The fade simply looks best between photos with the same framing (a place at different hours, a product in several colours), because nothing moves except what changes.
Yes. Only the slide on screen receives clicks: the others are pointer-events: none and inert, so a button placed on a hidden image cannot be triggered by mistake through the one on top.