YurbaSlider
A carousel that moves its slides with a transform: one or a group at a time, in a loop, centred, with drag, inertia and rubber-band edges. And a row that scrolls natively, for long lists swiped with a finger.
<link rel="stylesheet" href="/dist/yurba-slider.min.css">
<script src="/dist/yurba-slider.min.js"></script>
Give the slider the element whose children are the slides. It keeps its own classes and gap, and is wrapped in .y-slider.
<div class="cards">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
</div>
const slider = new YurbaSlider('.cards', {
slidesPerView: 3,
spaceBetween: 16,
loop: true,
})
slider.on('change', (index) => console.log('now at', index))
Slides added to the element later are picked up by themselves. A second slider on the same element destroys the first one.
| Option | Type | Description |
|---|---|---|
slidesPerView optional | number | 'auto' | Slides in view. 'auto' keeps the width the slides have in CSS. Default: 'auto'. |
slidesPerGroup optional | number | 'auto' | Slides per step. 'auto' steps by what fits in view. Default: 1. |
spaceBetween optional | number | Space between slides, px. Default: the element's CSS gap. |
centered optional | boolean | The current slide sits in the middle. |
loop optional | boolean | Endless loop. It needs a spare slide on each side of the view, otherwise it stays off. |
rewind optional | boolean | Next on the last slide goes back to the first one, and the other way round. |
free optional | boolean | 'snap' | Free scrolling with inertia. 'snap' settles on the nearest slide. |
start optional | number | Slide to start on. Default: 0. |
speed optional | number | Move duration, ms. Default: 420. |
drag optional | boolean | Drag with the mouse and swipe on touch. Default: true. |
grabCursor optional | boolean | Grab cursor over the slides. |
threshold optional | number | Pixels before a drag starts. Default: 6. |
resistance optional | number | How much the edges give when dragged past. Default: 0.35. |
autoplay optional | number | Delay between moves, ms. 0 is off. Pauses off screen, in a hidden tab, while dragging, on hover and on focus. |
pauseOnHover optional | boolean | Pause autoplay under the mouse. Default: true. |
keyboard optional | boolean | Left and right arrow keys while focus is inside. Default: true. |
wheel optional | boolean | Sideways trackpad swipes move the slides. Default: true. |
arrows optional | boolean | object | Built-in arrows, or your own buttons. See Arrows. Default: true. |
pagination optional | element | string | object | Dots, a fraction or a progress bar. See Pagination. |
overflow optional | 'hidden' | 'visible' | 'visible' lets slides show outside the slider. Default: 'hidden'. |
breakpoints optional | object | Options by minimum window width. See Breakpoints. |
icons optional | object | HTML of the built-in arrows. See Icons. |
labels optional | object | Accessible names. See Labels. |
on optional | object | Event handlers, e.g. { change: fn }. |
With native: true the row scrolls natively: the browser's own swipe on touch, plus mouse drag and snapping. Best for long rows such as stories, shelves and tabs. The arrows step by a page.
new YurbaSlider(row, { native: true, snap: false, prevLabel: 'Back', nextLabel: 'Next' })
| Option | Type | Description |
|---|---|---|
native required | true | Turns the native engine on. |
items optional | element | Container of the items, when it is not the scrolling element itself. |
inset optional | number | Where items line up. Default: the left padding. |
snap optional | boolean | Snap to items. Default: true. |
slidesPerGroup optional | number | 'auto' | The arrows step by a page, or by this many items. Default: 'auto'. |
drag, arrows, icons, autoplay optional | mixed | As for the carousel. Autoplay goes page by page. |
pagination / dots optional | element | object | Dots by page. |
prevLabel, nextLabel optional | string | Arrow labels. |
onUpdate optional | function | Called with { fits, start, end, page, pages }. |
Keys are minimum window widths. Every breakpoint the window has passed is applied on top of the base options.
new YurbaSlider('.cards', {
slidesPerView: 1,
breakpoints: {
600: { slidesPerView: 2, slidesPerGroup: 2 },
900: { slidesPerView: 3, slidesPerGroup: 3 },
},
})
Live demo
Drag with the mouse, swipe sideways on a trackpad, or focus a slide and use the arrow keys.
One, two or three in view by the window width, a whole group per step.
Centred slides in an endless loop, moving every 3 seconds. Hover to pause.
No snapping: a flick glides on and slows down.
Controls
| Input | Action |
|---|---|
| Drag or swipe | Moves the slides and settles on the nearest one. A quick flick turns at least one slide. Past an end the slides give a little and spring back. |
| Vertical swipe | Left to the page, so it still scrolls. |
| Sideways trackpad swipe | Moves the slides like a drag. Vertical wheel is left to the page. |
← / → | Previous / next while focus is inside the slider. |
Tab to a hidden slide | Brings that slide into view. |
| Click after a drag | Ignored, so a drag never opens a link it started on. |
With arrows: true the slider draws its own arrows over the slides, shown on hover and hidden at the ends and on touch screens. To use your own buttons, pass them as elements or selectors: they get disabled at the ends. arrows: false leaves them out.
new YurbaSlider('.cards', {
arrows: { prev: '.cards-prev', next: '.cards-next' },
})
An element or a selector gives dots. An object picks the type.
new YurbaSlider('.cards', {
pagination: { el: '.cards-pages', type: 'fraction' },
})
| Key | Type | Description |
|---|---|---|
el required | element | string | Where the pagination is drawn. |
type optional | string | 'dots', 'fraction' (3 / 8) or 'progress'. Default: 'dots'. |
clickable optional | boolean | Dots are buttons that go to their page. Default: true. |
API
| Method | Description |
|---|---|
update() | Measures again and keeps the current slide in place. Resizes and new slides call it by themselves. |
destroy() | Removes the slider and restores the element as it was. |
| Property | Type | Description |
|---|---|---|
index | number | The current slide. |
page, pages | number | The current page and how many there are. |
slides | array | The slide elements. |
isStart, isEnd | boolean | At the first or the last step. |
native | boolean | Which engine runs. |
The slider of an element, or null.
YurbaSlider.get('.cards')?.next()
Events
Subscribe with on(name, handler), or pass handlers in the on option. off(name, handler?) removes them. Every handler gets the slider as its last argument.
| Event | Arguments | When |
|---|---|---|
init | Ready. | |
change | index | The current slide changed. |
move | progress | Every frame of a move or a drag. |
settle | index | A move finished. |
dragStart, dragEnd | velocity on end | A drag began or ended. |
resize | Measured again. | |
update | { fits, start, end, page, pages } | Native row state changed. |
destroy | Removed. |
slider.on('change', (index) => {
caption.textContent = captions[index]
})
progress runs from 0 at the first step to 1 at the last one, frame by frame.
slider.on('move', (progress) => {
bar.style.transform = `scaleX(${progress})`
})
velocity is in pixels per millisecond, positive forward.
slider.on('dragStart', () => video.pause())
slider.on('dragEnd', (velocity) => console.log(velocity))
Customization
| Class | On |
|---|---|
.y-slider, --carousel, --native | The wrapper. |
--start, --end, --fits, --dragging, --visible, --grab | The wrapper, by state. |
.y-slider__track, --native, --snap, --dragging | The element given. |
.y-slider__slide, .is-active | Each slide of a carousel. |
.y-slider__arrow, --prev, --next | Built-in arrows. |
.y-slider__pagination, --dots, --fraction, --progress | The pagination element. |
.y-slider__dot, .y-slider__progress | Dots and the progress bar. |
The built-in arrows take any HTML: an icon font, an SVG, an image. By default they are chevron_left and chevron_right from Material Symbols Rounded, which the page loads itself. Keys left out keep the default.
new YurbaSlider('.cards', {
icons: {
prev: '<span class="material-symbols-rounded">arrow_back</span>',
next: '<svg viewBox="0 0 24 24" width="20" height="20"><path d="M9 6l6 6-6 6" fill="none" stroke="currentColor" stroke-width="2"/></svg>',
},
})
| Key | Type | Description |
|---|---|---|
prev optional | string | HTML of the previous arrow. |
next optional | string | HTML of the next arrow. |
Your own buttons passed in arrows keep their own content.
Accessible names, English by default. {index} and {total} are filled in.
new YurbaSlider('.cards', {
labels: {
prev: 'Назад',
next: 'Далі',
carousel: 'Новини',
slide: '{index} з {total}',
page: 'До слайда {index}',
},
})
With reduced motion on, moves are instant and autoplay is off.