Add a seamless infinite scroll to your carousels with fading edges that blend cleanly into your background. Control the speed, direction, and fade width – ideal for logo bars, tool grids, or any section where you want constant, smooth motion.
Custom css
The CSS to make the animation for this power up is included in the top level parent container Advanced > Custom CSS. No additional setup needed. Just copy the component and the styles come with it.
/* =========================
Element UI Carousel Fade Overlay
HOW TO USE:
1. Add class "eui-fade-container" to the parent container holding your carousels
2. Add class "eui-fade-carousel" to each carousel (scrolls right to left)
3. Add class "eui-fade-carousel-lr" to any carousel you want scrolling left to right
4. Change --fade-bg to match your section background colour
5. Update the rgba values below to match (use an RGB converter)
SPEED: Edit the SPEED value in the JS — lower = faster, higher = slower
========================= */
.eui-fade-container {
position: relative;
overflow: hidden;
--fade-bg: #111111;
--fade-width: 320px;
}
.eui-fade-container::before {
content: "";
position: absolute;
inset: 0;
z-index: 50;
pointer-events: none;
background: linear-gradient(
to right,
var(--fade-bg) 0%,
rgba(17, 17, 17, 0) var(--fade-width),
rgba(17, 17, 17, 0) calc(100% - var(--fade-width)),
var(--fade-bg) 100%
);
}
/* Tablet */
@media (max-width: 1024px) {
.eui-fade-container {
--fade-width: 160px;
}
}
/* Mobile */
@media (max-width: 767px) {
.eui-fade-container {
--fade-width: 90px;
}
}
Custom Javascript
JavaScript is loaded via a HTML widget. Don’t remove it – it powers the animation.
<script>
(function () {
// EDIT: lower = faster, higher = slower
const SPEED = 12000; // try 9000 (faster) or 16000 (slower)
function setupMarquee(swiperRoot, reverseDirection) {
const swiper = swiperRoot && swiperRoot.swiper;
if (!swiper) return;
// Prevent re-applying settings repeatedly (causes jitter/speed ramps)
if (swiper.el && swiper.el.dataset && swiper.el.dataset.euiMarqueeInit === "1") return;
if (swiper.el && swiper.el.dataset) swiper.el.dataset.euiMarqueeInit = "1";
// Force marquee-style behavior
swiper.params.loop = true;
swiper.params.autoplay = swiper.params.autoplay || {};
swiper.params.autoplay.delay = 0;
swiper.params.autoplay.disableOnInteraction = false;
swiper.params.autoplay.pauseOnMouseEnter = false;
swiper.params.autoplay.waitForTransition = false;
swiper.params.speed = SPEED;
swiper.params.autoplay.reverseDirection = !!reverseDirection;
// Linear easing
if (swiper.wrapperEl) {
swiper.wrapperEl.style.transitionTimingFunction = "linear";
}
// Stop first, then hard reset transition to avoid the initial "burst"
if (swiper.autoplay && swiper.autoplay.stop) swiper.autoplay.stop();
// Make sure we're not mid-transition when we restart
if (typeof swiper.setTransition === "function") swiper.setTransition(0);
if (swiper.wrapperEl) swiper.wrapperEl.style.transitionDuration = "0ms";
// Refresh + restart cleanly on the next frame
swiper.update();
requestAnimationFrame(() => {
// Re-apply speed + linear after update (Swiper can override)
swiper.params.speed = SPEED;
if (typeof swiper.setTransition === "function") swiper.setTransition(SPEED);
if (swiper.wrapperEl) {
swiper.wrapperEl.style.transitionTimingFunction = "linear";
swiper.wrapperEl.style.transitionDuration = SPEED + "ms";
}
if (swiper.autoplay && swiper.autoplay.start) swiper.autoplay.start();
});
}
function init() {
// Normal direction (usually right -> left)
document
.querySelectorAll(".eui-fade-carousel .swiper, .eui-fade-carousel .swiper-container")
.forEach((el) => setupMarquee(el, false));
// Left -> right
document
.querySelectorAll(".eui-fade-carousel-lr .swiper, .eui-fade-carousel-lr .swiper-container")
.forEach((el) => setupMarquee(el, true));
}
// Elementor can render late, so run a few times
window.addEventListener("load", init);
setTimeout(init, 600);
setTimeout(init, 1600);
})();
</script>