Responsive card row

The most common use case. On wide screens all cards fit at once so the slider freezes — no arrows, no drag, no pagination. Resize the window narrower and it wakes up automatically as slidesPerPage drops via breakpoints.

Plan A$9 / mo
Plan B$19 / mo
Plan C$39 / mo
Plan D$79 / mo
View code
<div class="c--slider-a" id="my-slider">
  <div class="c--slider-a__wrapper">
    <div class="c--slider-a__slide card">...</div>
    <div class="c--slider-a__slide card">...</div>
    <div class="c--slider-a__slide card">...</div>
    <div class="c--slider-a__slide card">...</div>
  </div>
</div>
<div id="my-pag" class="c--slider-a__pagination"></div>
.c--slider-a { position: relative; width: 100%; overflow: hidden; }
.c--slider-a__wrapper { display: flex; will-change: transform; }
.c--slider-a__slide { flex-shrink: 0; }

/* Arrows */
.c--slider-a__arrow {
  position: absolute; top: 50%; transform: translateY(-50%);
  z-index: 10; width: 40px; height: 40px; border-radius: 50%;
  border: none; background: rgba(255,255,255,0.9);
  cursor: pointer; box-shadow: 0 2px 8px rgba(0,0,0,0.18);
}
.c--slider-a__arrow--prev { left: 12px; }
.c--slider-a__arrow--next { right: 12px; }
.c--slider-a__arrow--disabled { opacity: 0.3; pointer-events: none; }
.c--slider-a {
  position: relative;
  width: 100%;
  overflow: hidden;

  &__wrapper {
    display: flex;
    will-change: transform;
  }

  &__slide {
    flex-shrink: 0;
  }

  &__arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 10;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: none;
    background: rgba(255,255,255,0.9);
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0,0,0,0.18);

    &--prev {
      left: 12px;
    }

    &--next {
      right: 12px;
    }

    &--disabled {
      opacity: 0.3;
      pointer-events: none;
    }
  }
}
import { Slider } from '@andresclua/sliderkit'
import { arrows, pagination } from '@andresclua/sliderkit-plugins'

new Slider('#my-slider', {
  gutter: 16,
  freezable: true,   // freeze when all cards fit on screen
  breakpoints: {
    0:   { slidesPerPage: 1 },
    480: { slidesPerPage: 2 },
    768: { slidesPerPage: 3 },
    1024: { slidesPerPage: 4 }, // on wide screens, all 4 fit → freezes
  },
  plugins: [
    arrows(),
    pagination({ el: '#my-pag', type: 'dots', clickable: true }),
  ],
})

Logo / partner strip

A row of partner logos that sits static on desktop (all logos visible, slider frozen) and becomes a swipeable carousel on mobile. No conditional rendering — one component handles both states.

Acme
Globex
Initech
Umbrella
Hooli
View code
<div class="c--slider-a" id="my-slider">
  <div class="c--slider-a__wrapper">
    <div class="c--slider-a__slide logo-slide">Logo A</div>
    <div class="c--slider-a__slide logo-slide">Logo B</div>
    <div class="c--slider-a__slide logo-slide">Logo C</div>
    <div class="c--slider-a__slide logo-slide">Logo D</div>
    <div class="c--slider-a__slide logo-slide">Logo E</div>
  </div>
</div>
.c--slider-a { position: relative; width: 100%; overflow: hidden; }
.c--slider-a__wrapper { display: flex; will-change: transform; }
.c--slider-a__slide { flex-shrink: 0; }

.logo-slide {
  height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px dashed #e5e7eb;
  border-radius: 8px;
  font-weight: 700;
  color: #9ca3af;
}

/* When frozen, wrapper sits as a normal flex row */
.c--slider-a--frozen .c--slider-a__wrapper {
  justify-content: space-between;
}
.logo-slide {
  height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px dashed #e5e7eb;
  border-radius: 8px;
  font-weight: 700;
  color: #9ca3af;
}

.c--slider-a {
  position: relative;
  width: 100%;
  overflow: hidden;

  &__wrapper {
    display: flex;
    will-change: transform;
  }

  &__slide {
    flex-shrink: 0;
  }

  &--frozen .c--slider-a__wrapper {
    justify-content: space-between;
  }
}
import { Slider } from '@andresclua/sliderkit'

new Slider('#my-slider', {
  gutter: 16,
  freezable: true,
  breakpoints: {
    0:   { slidesPerPage: 2 },
    640: { slidesPerPage: 3 },
    960: { slidesPerPage: 5 }, // all 5 logos fit → freezes, looks like a static row
  },
})

Disable during async loading

Call disable() while new content is being fetched so the user can't navigate mid-load, then re-enable once the data is ready. No need to destroy and rebuild the whole slider.

1
2
3
4
5
View code
<div class="c--slider-a" id="my-slider">
  <div class="c--slider-a__wrapper">
    <!-- slides populated by JS -->
  </div>
</div>
<div id="my-pag" class="c--slider-a__pagination"></div>
<button id="btn-reload">Simulate reload</button>
.c--slider-a { position: relative; width: 100%; overflow: hidden; }
.c--slider-a__wrapper { display: flex; will-change: transform; }
.c--slider-a__slide { flex-shrink: 0; width: 100%; height: 260px; }

/* Dim the slider while disabled */
.c--slider-a--disabled { opacity: 0.4; pointer-events: none; transition: opacity 0.2s; }
.c--slider-a {
  position: relative;
  width: 100%;
  overflow: hidden;

  &__wrapper {
    display: flex;
    will-change: transform;
  }

  &__slide {
    flex-shrink: 0;
    width: 100%;
    height: 260px;
  }

  &--disabled {
    opacity: 0.4;
    pointer-events: none;
    transition: opacity 0.2s;
  }
}
import { Slider } from '@andresclua/sliderkit'
import { arrows, pagination } from '@andresclua/sliderkit-plugins'

const slider = new Slider('#my-slider', {
  loop: true,
  plugins: [
    arrows(),
    pagination({ el: '#my-pag', type: 'dots', clickable: true }),
  ],
})

async function loadSlides() {
  slider.disable()               // lock navigation
  // ... await fetch('/api/slides')
  await new Promise(r => setTimeout(r, 1500)) // simulated delay
  slider.enable()                // unlock once data is ready
}

document.getElementById('btn-reload').addEventListener('click', loadSlides)