carousel
Everything you need for a modern, performant carousel
Seamless continuous scrolling with automatic cloning
Mobile-friendly swipe gestures and mouse drag support
Breakpoint-based configuration for all screen sizes
Less than 10KB gzipped with zero dependencies
Optional automatic sliding with configurable intervals
Flexible API with extensive configuration options
Simple full-width carousel with infinite loop and autoplay
<div class="carousel">
<div class="carousel__inner">
<div class="carousel__slide">
<img src="banner1.jpg" alt="Banner 1">
</div>
<div class="carousel__slide">
<img src="banner2.jpg" alt="Banner 2">
</div>
<div class="carousel__slide">
<img src="banner3.jpg" alt="Banner 3">
</div>
</div>
<button class="carousel__arrow carousel__arrow--prev" type="button" aria-label="Previous">←</button>
<button class="carousel__arrow carousel__arrow--next" type="button" aria-label="Next">→</button>
<div class="carousel__pagination"></div>
</div>
.carousel__slide img {
width: 100%;
height: auto;
display: block;
}
.carousel__arrow {
border: none;
border-radius: 4px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
transition: all 0.3s ease;
font-weight: 700;
font-size: 22px;
}
.carousel__arrow:hover {
background: #f5f5f5;
transform: translateY(-50%) scale(1.05);
}
.carousel__pagination {
width: max-content;
position: absolute;
bottom: 15px;
left: 50%;
transform: translateX(-50%);
margin: 0;
padding: 8px 16px;
background: #FFFFFF;
border-radius: 40px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.carousel__pagination .merrygo-bullet {
width: 8px;
height: 8px;
background: #CED1D3;
}
.carousel__pagination .merrygo-bullet-active {
background: #000000;
}
const carousel = new MerryGo({
gallery: document.querySelector('.carousel'),
galleryInner: document.querySelector('.carousel__inner'),
prevBtn: document.querySelector('.carousel__arrow--prev'),
nextBtn: document.querySelector('.carousel__arrow--next'),
pagination: document.querySelector('.carousel__pagination'),
gap: 5,
autoplay: 5000,
infinityLoop: true
});
Multiple slides visible with responsive breakpoints
<div class="products-carousel">
<div class="products-carousel__inner">
<div class="products-carousel__slide">Product 1</div>
<div class="products-carousel__slide">Product 2</div>
<div class="products-carousel__slide">Product 3</div>
<!-- more slides -->
</div>
<button class="products-carousel__arrow products-carousel__arrow--prev" type="button" aria-label="Previous">←</button>
<button class="products-carousel__arrow products-carousel__arrow--next" type="button" aria-label="Next">→</button>
</div>
<div class="products-carousel__pagination"></div>
.products-carousel__arrow {
box-shadow: 0px 1px 8px 0px #0000001F;
font-weight: 700;
font-size: 22px;
}
.products-carousel__arrow:hover {
background: #f5f5f5;
transform: translateY(-50%) scale(1.05);
}
.products-carousel__pagination {
width: max-content;
margin: 16px auto 0;
padding: 8px 16px;
background: #FFFFFF;
border-radius: 40px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.products-carousel__pagination .merrygo-bullet {
width: 8px;
height: 8px;
background: #CED1D3;
}
.products-carousel__pagination .merrygo-bullet-active {
background: #000000;
}
const carousel = new MerryGo({
gallery: document.querySelector('.products-carousel'),
galleryInner: document.querySelector('.products-carousel__inner'),
prevBtn: document.querySelector('.products-carousel__arrow--prev'),
nextBtn: document.querySelector('.products-carousel__arrow--next'),
pagination: document.querySelector('.products-carousel__pagination'),
infinityLoop: false,
breakpoints: {
0: { slidesVisible: 1, gap: 5 },
561: { slidesVisible: 2, gap: 15 },
769: { slidesVisible: 3, gap: 15 },
1025: { slidesVisible: 4, gap: 20 }
}
});
Synchronized carousel with clickable thumbnail navigation
<!-- Thumbnails -->
<div class="gallery__thumbnails">
<input type="radio" name="thumb" id="thumb-0" checked>
<label class="gallery__thumbnail" for="thumb-0">
<img src="image1.jpg">
</label>
<input type="radio" name="thumb" id="thumb-1">
<label class="gallery__thumbnail" for="thumb-1">
<img src="image2.jpg">
</label>
<input type="radio" name="thumb" id="thumb-2">
<label class="gallery__thumbnail" for="thumb-2">
<img src="image3.jpg">
</label>
</div>
<!-- Main Gallery -->
<div class="gallery">
<div class="gallery__inner">
<div class="gallery__slide">
<img src="image1.jpg">
</div>
<div class="gallery__slide">
<img src="image2.jpg">
</div>
<div class="gallery__slide">
<img src="image3.jpg">
</div>
</div>
<button class="gallery__arrow gallery__arrow--prev" type="button" aria-label="Previous">←</button>
<button class="gallery__arrow gallery__arrow--next" type="button" aria-label="Next">→</button>
</div>
.gallery__slide img {
width: 100%;
height: auto;
display: block;
}
.gallery__arrow {
box-shadow: 0px 1px 8px 0px #0000001F;
font-weight: 700;
font-size: 22px;
}
.gallery__arrow:hover {
background: #f5f5f5;
transform: translateY(-50%) scale(1.05);
}
.gallery__thumbnails {
display: flex;
gap: 15px;
margin-top: 16px;
}
.gallery__thumbnails input[type="radio"] {
display: none;
}
.gallery__thumbnail {
width: 80px;
height: 80px;
border: 3px solid transparent;
border-radius: 8px;
overflow: hidden;
cursor: pointer;
transition: all 0.3s ease;
}
.gallery__thumbnails input:checked + .gallery__thumbnail {
border-color: #000000;
}
.gallery__thumbnail:hover {
border-color: #82898E;
}
.gallery__thumbnail img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
const thumbInputs = Array.from(
document.querySelectorAll('.gallery__thumbnails input[type="radio"]')
);
const carousel = new MerryGo({
gallery: document.querySelector('.gallery'),
galleryInner: document.querySelector('.gallery__inner'),
thumbs: thumbInputs, // Array of radio inputs
prevBtn: document.querySelector('.gallery__arrow--prev'),
nextBtn: document.querySelector('.gallery__arrow--next'),
gap: 5
});
Install MerryGo and start to create!
<script src="https://cdn.jsdelivr.net/npm/merrygo-carousel@2.0.0/dist/merrygo.js"></script>
npm install merrygo-carousel