<div class="slider">
	<div class="slider-list">
		<div class="slider-track">
			<div class="slide">1</div>
			<div class="slide">2</div>
			<div class="slide">3</div>
			<div class="slide">4</div>
			<div class="slide">5</div>
			<div class="slide">6</div>
			<div class="slide">7</div>
		</div>
	</div>
</div>
.slider {
  position: relative;
  width: 680px;
  margin: 50px auto 0;
  user-select: none;
  touch-action: pan-y;
}

.slider-list {
  overflow: hidden;
}

.slide {
  border: 1px solid #000;
  width: 200px;
  height: 200px;
  font-size: 16px;
}

.slide img {
  pointer-events: none;
}

.slider-list.grab {
  cursor: grab;
}

.slider-list.grabbing {
  cursor: grabbing;
}

.slider-track {
/*============================*/
  width: fit-content;
/*============================*/
  display: grid;
  grid-auto-flow: column;
  grid-column-gap: 40px;
}
const slider = document.querySelector('.slider');
const sliderList = slider.querySelector('.slider-list');
const sliderTrack = slider.querySelector('.slider-track');
const trfRegExp = /([-0-9.]+(?=px))/;
let posX1 = 0;


const getEvent = (event) => {
  return (event.type.search('touch') !== -1) ? event.touches[0] : event;
}

const swipeStart = (event) => {
  let evt = getEvent(event);
  posX1 = evt.clientX;
  document.addEventListener('touchmove', swipeAction);
  document.addEventListener('mousemove', swipeAction);
  document.addEventListener('touchend', swipeEnd);
  document.addEventListener('mouseup', swipeEnd);
  sliderList.classList.remove('grab');
  sliderList.classList.add('grabbing');
}

const swipeAction = (event) => {
  let evt = getEvent(event);
  let transform = +sliderTrack.style.transform.match(trfRegExp)[0];
  posX2 = posX1 - evt.clientX;
  posX1 = evt.clientX;
  
//=======================================================
  let dT = transform - posX2;
  let sliderListWidth = parseInt(window.getComputedStyle(sliderList, null).getPropertyValue('width'));
  let sliderTrackWidth = parseInt(window.getComputedStyle(sliderTrack, null).getPropertyValue('width'));
  if (dT <= 0 && dT >= sliderListWidth - sliderTrackWidth) {
    sliderTrack.style.transform = `translate(${transform - posX2}px)`;
  }
//=======================================================
  
}

const swipeEnd = () => {
  document.removeEventListener('touchmove', swipeAction);
  document.removeEventListener('mousemove', swipeAction);
  document.removeEventListener('touchend', swipeEnd);
  document.removeEventListener('mouseup', swipeEnd);
  sliderList.classList.add('grab');
  sliderList.classList.remove('grabbing');
}

sliderTrack.style.transform = 'translate(0px)';
sliderList.classList.add('grab');
slider.addEventListener('touchstart', swipeStart);
slider.addEventListener('mousedown', swipeStart);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.