@jomurgel/native-scroll-slider
v0.0.7
Published
A simple slider that leverages native overflow scroll behavior.
Maintainers
Readme
Native Scroll Slider
A lightweight, dependency-free JavaScript slider that leverages native browser scrolling for smooth, performant carousel experiences. Built with modern web standards and optimized for minimal bundle size.
✨ Features
- Ultra-lightweight: Only ~3.7KB (~0.5KB gzipped) - 90% smaller than alternatives
- Native performance: Uses browser's native scrolling for 60fps animations
- Touch-friendly: Built-in touch/swipe support without additional libraries
- Native scrolling: Touch and mouse drag scrolling work naturally - no hijacked events
- Highly configurable: 20+ options for complete customization
- Responsive: Built-in responsive breakpoints and adaptive layouts
- Accessible: Keyboard navigation and screen reader friendly
- Multiple modes: Standard, infinite scroll, bounce-back, and center mode
- Zero dependencies: Pure vanilla JavaScript, works everywhere
- Modern browsers: ES6+ with graceful degradation
📦 Installation
npm
npm install @jomurgel/native-scroll-sliderCDN (Coming Soon)
<script src="https://unpkg.com/@jomurgel/native-scroll-slider/dist/native-scroll-slider.min.js"></script>
<script>
const slider = new NativeScrollSlider(document.querySelector('.slider-track'));
</script>NPM Imports
import NativeScrollSlider from '@jomurgel/native-scroll-slider';
// or
import NativeScrollSlider from 'native-scroll-slider';Direct Download
Download from GitHub releases
🚀 Quick Start
Basic HTML Structure
<div class="slider-container" data-slider-config='{"slidesToShow": 3, "autoplay": true}'>
<div class="slider-track">
<div class="slide">Slide 1</div>
<div class="slide">Slide 2</div>
<div class="slide">Slide 3</div>
<div class="slide">Slide 4</div>
<div class="slide">Slide 5</div>
</div>
<button class="slider-prev">Previous</button>
<button class="slider-next">Next</button>
</div>JavaScript Initialization
import NativeScrollSlider from '@jomurgel/native-scroll-slider';
// Initialize with default options
const slider = new NativeScrollSlider(document.querySelector('.slider-track'));
// Or with custom options
const slider = new NativeScrollSlider(document.querySelector('.slider-track'), {
slidesToShow: 3,
autoplay: true,
autoplaySpeed: 4000,
infinite: true,
responsive: [
{
breakpoint: 768,
settings: {
slidesToShow: 1
}
}
]
});⚙️ Configuration Options
Complete Options Table
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| slidesToShow | number | 4 | Number of slides visible at once |
| slidesToScroll | number | 1 | Number of slides to scroll at once |
| infinite | boolean | false | Enable infinite scrolling |
| bounceBack | boolean | false | Enable bounce-back at edges |
| centerMode | boolean | false | Center the active slide |
| autoplay | boolean | false | Enable automatic sliding |
| autoplaySpeed | number | 3000 | Autoplay interval in milliseconds |
| gap | number | 24 | Gap between slides in pixels |
| startSlide | number | 0 | Index of initial slide |
| responsive | array | [...] | Responsive breakpoint settings (see below) |
| prevElement | string | '.prev, .slider-prev, .slider-grid-prev' | Previous button selector |
| nextElement | string | '.next, .slider-next, .slider-grid-next' | Next button selector |
| minSlideWidth | number | 0 | Minimum slide width in pixels |
| showOverflow | boolean | false | Show partial next/previous slides + enable full-width mode |
| overflowAmount | number | 0.5 | Amount of overflow slide to show (0-1) |
| containerMaxWidth | number | 1200 | Max container width for overflow mode |
| basePadding | number | 35 | Base padding for overflow mode |
Default Responsive Breakpoints
The slider includes these responsive breakpoints by default:
responsive: [
{
breakpoint: 1200,
settings: { slidesToShow: 3 }
},
{
breakpoint: 992,
settings: { slidesToShow: 2 }
},
{
breakpoint: 768,
settings: { slidesToShow: 1 }
},
{
breakpoint: 576,
settings: { slidesToShow: 1 }
}
]Configuration Methods
1. JavaScript Options
const slider = new NativeScrollSlider(track, {
slidesToShow: 3,
autoplay: true,
infinite: true
});2. Data Attributes
<div data-slider-config='{"slidesToShow": 2, "autoplay": true}'>
<div class="slider-track">...</div>
</div>3. Responsive Configuration
const slider = new NativeScrollSlider(track, {
slidesToShow: 4, // Desktop default
responsive: [
{
breakpoint: 1200,
settings: {
slidesToShow: 3
}
},
{
breakpoint: 992,
settings: {
slidesToShow: 2
}
},
{
breakpoint: 768,
settings: {
slidesToShow: 1,
centerMode: true
}
},
{
breakpoint: 576,
settings: {
slidesToShow: 1,
autoplay: false
}
}
]
});🎯 Usage Examples
Image Gallery
<div class="gallery-slider">
<div class="slider-track">
<div class="slide"><img src="image1.jpg" alt="Image 1"></div>
<div class="slide"><img src="image2.jpg" alt="Image 2"></div>
<div class="slide"><img src="image3.jpg" alt="Image 3"></div>
</div>
</div>
<script>
new NativeScrollSlider(document.querySelector('.gallery-slider .slider-track'), {
slidesToShow: 1,
infinite: true,
autoplay: true,
centerMode: true
});
</script>Product Carousel
<div class="product-carousel" data-slider-config='{"slidesToShow": 4, "showOverflow": true}'>
<div class="slider-track">
<div class="slide product-card">Product 1</div>
<div class="slide product-card">Product 2</div>
<div class="slide product-card">Product 3</div>
<div class="slide product-card">Product 4</div>
<div class="slide product-card">Product 5</div>
</div>
<button class="slider-prev">←</button>
<button class="slider-next">→</button>
</div>Hero Banner Slider
const heroSlider = new NativeScrollSlider(document.querySelector('.hero-track'), {
slidesToShow: 1,
autoplay: true,
autoplaySpeed: 5000,
infinite: true,
showOverflow: true, // Enables full-width breakout
responsive: [
{
breakpoint: 768,
settings: {
showOverflow: false
}
}
]
});Card Deck with Overflow
const cardSlider = new NativeScrollSlider(document.querySelector('.cards-track'), {
slidesToShow: 3,
showOverflow: true,
overflowAmount: 0.3,
gap: 20,
responsive: [
{
breakpoint: 768,
settings: {
slidesToShow: 1,
showOverflow: false
}
}
]
});🎨 Styling
Basic CSS
.slider-container {
position: relative;
max-width: 1200px;
margin: 0 auto;
}
.slider-track {
display: flex;
overflow-x: auto;
scroll-behavior: smooth;
scrollbar-width: none;
-ms-overflow-style: none;
}
.slider-track::-webkit-scrollbar {
display: none;
}
.slide {
flex-shrink: 0;
scroll-snap-align: start;
}
/* Navigation buttons */
.slider-prev,
.slider-next {
position: absolute;
top: 50%;
transform: translateY(-50%);
z-index: 10;
background: rgba(0,0,0,0.5);
color: white;
border: none;
padding: 10px;
cursor: pointer;
}
.slider-prev {
left: 10px;
}
.slider-next {
right: 10px;
}
.slider-prev:disabled,
.slider-next:disabled {
opacity: 0.3;
cursor: not-allowed;
}Center Mode Styling
.slide {
transition: transform 0.3s ease, opacity 0.3s ease;
opacity: 0.6;
transform: scale(0.8);
}
.slide.center {
opacity: 1;
transform: scale(1);
}📱 Responsive Design
Mobile-First Approach
const responsiveSlider = new NativeScrollSlider(track, {
// Mobile defaults (matches built-in responsive)
slidesToShow: 4, // Desktop default
// Custom responsive overrides (combines with defaults)
responsive: [
{
breakpoint: 1200,
settings: {
slidesToShow: 3,
gap: 20
}
},
{
breakpoint: 992,
settings: {
slidesToShow: 2,
gap: 16
}
},
{
breakpoint: 768,
settings: {
slidesToShow: 1,
centerMode: true,
gap: 12
}
}
]
});🔧 API Reference
Creating a Slider Instance
// Store the slider instance to access methods
const slider = new NativeScrollSlider(document.querySelector('.slider-track'));
// Or with options
const slider = new NativeScrollSlider(document.querySelector('.slider-track'), {
slidesToShow: 3,
autoplay: true
});Public Methods
// Navigation
slider.next(); // Go to next slide(s)
slider.prev(); // Go to previous slide(s)
slider.goToSlide(index); // Go to specific slide (0-based index)
// Lifecycle
slider.handleResize(); // Manually trigger resize recalculation
slider.destroy(); // Clean up event listeners and timersComplete Example
// Create slider instance
const mySlider = new NativeScrollSlider(document.querySelector('.my-slider-track'), {
slidesToShow: 3,
autoplay: true,
infinite: true
});
// Use the methods
document.querySelector('.custom-next-btn').addEventListener('click', () => {
mySlider.next();
});
document.querySelector('.custom-prev-btn').addEventListener('click', () => {
mySlider.prev();
});
// Go to specific slide
document.querySelector('.go-to-slide-3').addEventListener('click', () => {
mySlider.goToSlide(2); // 0-based index, so 2 = 3rd slide
});Public Properties
// Read-only access to slider state
slider.currentSlide; // Current slide index (number)
slider.totalSlides; // Total number of slides (number)
slider.track; // Reference to track element (HTMLElement)
slider.container; // Reference to container element (HTMLElement)
slider.isScrolling; // Whether slider is currently scrolling (boolean)Event Handling
// Listen to native scroll events on the track
const track = document.querySelector('.slider-track');
track.addEventListener('scroll', () => {
console.log('Slider scrolled');
});
// Access slider state during scroll
slider.track.addEventListener('scroll', () => {
console.log(`Current slide: ${slider.currentSlide}`);
console.log(`Is scrolling: ${slider.isScrolling}`);
});
// Listen for scroll end (when user stops scrolling)
slider.track.addEventListener('scroll', () => {
clearTimeout(slider.scrollEndTimer);
slider.scrollEndTimer = setTimeout(() => {
console.log('Scroll ended');
}, 150);
});Autoplay Control
Note: Autoplay is controlled internally through options. To control autoplay programmatically:
// Enable/disable via options
const slider = new NativeScrollSlider(track, {
autoplay: true,
autoplaySpeed: 3000
});
// Control through mouse events (built-in)
// Autoplay pauses on hover and resumes on leave automatically
// Manual control (access internal methods - use with caution)
slider.pauseAutoplay(); // Pause autoplay
slider.resumeAutoplay(); // Resume autoplay🌟 Advanced Features
Infinite Scroll
const infiniteSlider = new NativeScrollSlider(track, {
infinite: true,
autoplay: true,
slidesToShow: 3
});
// Automatically clones slides and manages seamless loopingShow Overflow Mode
const peekSlider = new NativeScrollSlider(track, {
showOverflow: true,
overflowAmount: 0.5, // Show 50% of next slide
slidesToShow: 2
});
// Shows partial slides to indicate more content
// Also enables full-width breakout functionality📊 Performance Comparison
| Library | Bundle Size (gzipped) | Dependencies | Performance | |---------|----------------------|--------------|-------------| | Native Scroll Slider | 0.5 KB | None | 60fps native | | Slick.js | 6.2 KB | jQuery | Good | | Swiper.js | 25 KB | None | Excellent | | Glide.js | 7 KB | None | Good | | Splide.js | 11 KB | None | Good |
Why Choose Native Scroll Slider?
- Smallest footprint: 90% smaller than alternatives
- Native performance: Leverages browser optimizations
- Touch-first: Built-in mobile gestures with natural drag/swipe behavior
- No hijacked scrolling: Touch and mouse events work as expected - just like any native scrolling container
- Accessibility: Works with screen readers and keyboards
- Future-proof: Uses web standards, not polyfills
🛠️ Browser Support
- Modern browsers: Chrome 60+, Firefox 55+, Safari 12+, Edge 79+
- Mobile: iOS 12+, Android 7+
- Graceful degradation: Falls back to basic scrolling in older browsers
Feature Detection
// Check for required features
const isSupported = 'scrollBehavior' in document.documentElement.style;
if (isSupported) {
new NativeScrollSlider(track, options);
} else {
// Fallback or polyfill
}🤝 Contributing
We welcome contributions! Here's how to get started:
Development Setup
# Clone the repository
git clone https://github.com/jomurgel/native-scroll-slider.git
cd native-scroll-slider
# Install dependencies
npm install
# Start development server
npm run dev
# Run tests
npm test
# Build for production
npm run buildContribution Guidelines
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Write tests for new functionality
- Ensure all tests pass (
npm test) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
Code Standards
- Use ES6+ features
- Follow existing code style
- Add JSDoc comments for new methods
- Maintain backward compatibility
- Keep bundle size minimal
🐛 Issues & Support
Reporting Issues
When reporting issues, please include:
- Browser and version
- Device type (desktop/mobile)
- Minimal reproduction case
- Expected vs actual behavior
- Console errors (if any)
Report issues: GitHub Issues
Common Issues
Q: Slider not initializing
// Ensure DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
new NativeScrollSlider(document.querySelector('.slider-track'));
});Q: Touch scrolling not working
/* Ensure proper touch-action */
.slider-track {
touch-action: pan-x;
}Q: Slides not sized correctly
// Call handleResize after dynamic content loads
slider.handleResize();📄 License
MIT License © 2024 Jo Murgel - see LICENSE file for details.
🙏 Acknowledgments
- Inspired by native browser scrolling capabilities
- Built for modern web performance standards
- Responsive breakpoints based on 2025 design playbook
- Designed with accessibility in mind
📈 Changelog
v0.0.1
- Initial release
- Core sliding functionality with desktop-first defaults (4 slides).
- Built-in responsive breakpoints (1200/992/768/576px).
- Autoplay support with hover pause/resume.
- Infinite scroll mode with dynamic clone management.
- Center mode with visual highlighting.
- Show overflow mode with full-width breakout capability.
- Touch/swipe support via native scroll behavior.
v0.0.2
- Cleanup and minor bugfixes.
v0.0.3
- Fixes minWidth handling with centerMode active.
v0.0.4
-Improves infinite scroll behavior.
v0.0.5
- Improves hanlding of next/previous buttons when the slider container width is variable.
v0.0.6
- Fixes bug where nav buttons were being ignored when multiple sliders are present.
v0.0.7
- Updates js structure. Takes proof of concept into more organized file strucutre.
- Adds demo for Github Pages
- Adds deployment updates for npm and GH pages.
Made with ❤️ by jomurgel
For more examples and documentation, visit: https://github.com/jomurgel/native-scroll-slider
