スクロールスナップスライダーを作成

スクロールスナップスライダーを作成する方法を紹介します。

スクロールでもボタンでもスライドの移動ができます。スライドが左端にスナップします。

スクロールでもボタンでもスライドの移動ができる

スライドが左端にスナップ

コード

<div id = "container">
	<div id="target">
		<ul id="sample">
  			<li class="slide">1</li>
			<li class="slide">2</li>
			<li class="slide">3</li>
			<li class="slide">4</li>
			<li class="slide">5</li>
			<li class="slide">6</li>
			<li class="slide">7</li>
		</ul>
		<button class="next-arrow"></button>
		<button class="prev-arrow"></button>
	</div>
</div>
#container{
	width: 100vw;
	height: 100vh;
	background: #eee;
	display: grid;
	align-items: center;
	align-content: center;
}
.container {
	width: 90vw;
	overflow: auto;
	scroll-snap-type: x;
	display: flex;
	margin: 0 auto;
	position: relative;
	background: green;
}
.container::-webkit-scrollbar {
	height: 20px;
}
.container::-webkit-scrollbar-thumb {
  background: #276976;
  background-clip: padding-box; 
}
.container::-webkit-scrollbar-track {
  background-color: #000;
}
.next-arrow{
	background: red;
	position: fixed;
	width: 30px;
	height: 30px;
	-webkit-transform: translateY(-50%);
	transform: translateY(-50%);
	top: 50%;
	right: 0;
	cursor: pointer;
}
.next-arrow::before{
	content: '';
	position: absolute;
	-webkit-transform: translate(-50%, -50%)  rotate(45deg);
	transform: translate(-50%, -50%)  rotate(45deg);
	transform-origin: center;
	left: 40%;
	top: 50%;
	width: 15px;
	height: 15px;
	border-top: solid 1px #fff;
	border-right: solid 1px #fff;
}
.prev-arrow{
	background: red;
	position: fixed;
	width: 30px;
	height: 30px;
	-webkit-transform: translateY(-50%);
	transform: translateY(-50%);
	top: 50%;
	left: 0;
	cursor: pointer;
	opacity: 0.5;
	pointer-events: none;
}
.prev-arrow::before{
	content: '';
	position: absolute;
	-webkit-transform: translate(-50%, -50%)  rotate(-45deg);
	transform: translate(-50%, -50%)  rotate(-45deg);
	transform-origin: center;
	left: 60%;
	top: 50%;
	width: 15px;
	height: 15px;
	border-top: solid 1px #fff;
	border-left: solid 1px #fff;
}
#target {
	overflow: auto;
	width: 100vw;
	height: 50svh;
	scroll-snap-type: x;
}
#sample {
	width: 350vw;
	height: 100%;
	background-color: blue;
	display: flex;
}
.slide{
	width: 50vw;
	display: grid;
	align-content: center;
	align-items: center;
	background: #666;
	scroll-snap-align: start;
	font-size: 4rem;
	text-align: center;
	color: #fff;
}
ul li.slide:first-child{
	background: orange;
}
ul li.slide:nth-child(2){
	background: green;
}
ul li.slide:nth-child(3){
	background: blue;
}
ul li.slide:nth-child(4){
	background: gray;
}
ul li.slide:nth-child(5){
	background: violet;
}
ul li.slide:last-child{
	background: green;
}
#target::-webkit-scrollbar {
	height: 15px;
}
#target::-webkit-scrollbar-thumb {
  background: #276976;
}
#target::-webkit-scrollbar-track {
  background-color: #000;
}
let target = document.getElementById('target');

function moveScroll(){
	const rect = document.documentElement.scrollWidth;
	const rectWidth = rect / 2;	
	target.scrollBy({
		top: 0,
		left: rectWidth,
		behavior: "smooth",
	});
}

function moveScroll2(){
	const rect2 = document.documentElement.scrollWidth;
	const rectWidth2 = rect2 / 2;	
	target.scrollBy({
		top: 0,
		left: -rectWidth2,
		behavior: "smooth",
	});
}

const nextBtn = document.querySelector('.next-arrow');
const prevBtn = document.querySelector('.prev-arrow');

nextBtn.addEventListener('click', () => {
	moveScroll();		
});

const getScroll = () =>{
	const rect3 = document.documentElement.scrollWidth;
	const rectWidth3 = rect3 / 2;	
	let  x = target.scrollLeft;
	//console.log(x);
	if( x > rectWidth3 * 5 -1 ){
		nextBtn.style.pointerEvents=('none');
		nextBtn.animate(
			{
				opacity: [1, 0.5]
			},
			{
				duration: 800,
				fill: 'forwards',
				easing: 'ease'
			}
		);
	}else if(x < 1){
		prevBtn.style.pointerEvents=('none');
		prevBtn.animate(
			{
				opacity: [1, 0.5]
			},
			{
				duration: 800,
				fill: 'forwards',
				easing: 'ease'
			}
		);
	}else {
		prevBtn.style.pointerEvents=('auto');
		prevBtn.animate(
			{
				opacity: [1]
			},
			{
				duration: 800,
				fill: 'forwards',
				easing: 'ease'
			}
		);
		nextBtn.style.pointerEvents=('auto');
		nextBtn.animate(
			{
				opacity: [1]
			},
			{
				duration: 800,
				fill: 'forwards',
				easing: 'ease'
			}
		);
	}
}

target.addEventListener('scroll', getScroll);

prevBtn.addEventListener('click', () => {
	moveScroll2();
});

RECOMMEND

CONTACT

Webサイト作成は、是非
CXG DESIGNへご検討ください。