ボックスの上でマウスホイールを動かすと横方向にスクロールし、超過すると通常の縦スクロールが開始されるコードです。
目次(クリックでジャンプ)
マウスホイールで横スクロールできるボックス
overflow-x: auto;で横スクロールできるボックスを作ったが、PC表示時にいちいち小さいスクロールバーをクリックしてスライドするのが面倒。
また、人によっては横スクロールできる事に気づかず見てもらえない可能性があったため、要素の上でマウスホイールを縦に動かすと、その要素が自動的に横スクロールされるボックスを作りました。
- 要素の上でマウス縦スクロール=ボックス上で横にスクロール
- スクロールが終わると、通常の縦スクロールに戻り次のセクションに行く
- 横スクロールボックスでも見てもらえる
- 全体のレイアウトをシンプルに抑えられる
完成図(Codepen)
See the Pen horizontal scroll wrapper by ananchan (@kizikizi) on CodePen.
HTML
<div class="scroll__wrapper">
<div class="scroll__wrapper__list">
<div class="scroll__wrapper__list__item">
<img src="https://kizineko.com/coppy/wp-content/uploads/2024/04/no-image-768x432.png">
<h3>タイトル</h3>
<p>ここに内容</p>
</div>
<div class="scroll__wrapper__list__item">
<img src="https://kizineko.com/coppy/wp-content/uploads/2024/04/no-image-768x432.png">
<h3>タイトル</h3>
<p>ここに内容</p>
</div>
<div class="scroll__wrapper__list__item">
<img src="https://kizineko.com/coppy/wp-content/uploads/2024/04/no-image-768x432.png">
<h3>タイトル</h3>
<p>ここに内容</p>
</div>
</div>
</div>
<div class="mob"></div>
適宜画像や内容は変更して使ってください。
CSS(SCSS)
.mob {
width: 100%;
height: 500px;
background: #cccccc;
margin: 2rem 15px;
}
.scroll__wrapper {
position: relative;
overflow-x: auto;
overflow-y: hidden;
padding: 0 0 2rem 0.5rem;
&::-webkit-scrollbar {
height: 10px;
}
&::-webkit-scrollbar-thumb {
background: var(--primary-color);
border-radius: 10px;
}
&::-webkit-scrollbar-button {
display: none;
}
&::-webkit-scrollbar-track-piece:start,
&::-webkit-scrollbar-track-piece:end {
background-color: transparent;
}
&__list {
display: flex;
gap: 2rem;
&::after {
content: "";
width: 150px;
display: block;
position: relative;
flex: 0 0 auto
}
&__item {
color: #000;
width: 40%;//適宜変更してください
flex: 0 0 auto;
border-radius: 0.5rem;
transition: .3s;
img {
width: 100%;
}
h3 {
font-size: 1.25rem;
margin: 0.5rem 0;
}
p {
font-size: 0.9rem;
margin-bottom: 0;
}
&:hover {
scale: 1.02;
opacity: 0.8;
}
}
}
}
Javascript
document.addEventListener("DOMContentLoaded", function() {
const scrollWrappers = document.querySelectorAll('.scroll__wrapper');
let allowVerticalScrolls = Array.from(scrollWrappers).map(() => true);
let lastDeltaYs = Array.from(scrollWrappers).map(() => 0);
scrollWrappers.forEach((scrollWrapper, index) => {
scrollWrapper.addEventListener('wheel', function(event) {
const deltaY = event.deltaY;
const deltaX = deltaY * 0.5;
scrollWrapper.scrollLeft += deltaX;
if (deltaY !== 0 && allowVerticalScrolls[index]) {
smoothScroll(scrollWrapper, scrollWrapper.scrollTop, scrollWrapper.scrollTop + deltaY, 400);
if ((scrollWrapper.scrollLeft >= (scrollWrapper.scrollWidth - scrollWrapper.clientWidth) && deltaY > 0) ||
(scrollWrapper.scrollLeft <= 0 && deltaY < 0)) {
allowVerticalScrolls[index] = true;
} else {
event.preventDefault();
}
} else {
if ((scrollWrapper.scrollLeft >= (scrollWrapper.scrollWidth - scrollWrapper.clientWidth) && deltaY > 0) ||
(scrollWrapper.scrollLeft <= 0 && deltaY < 0)) {
allowVerticalScrolls[index] = true;
} else {
event.preventDefault();
}
}
lastDeltaYs[index] = deltaY;
});
});
function smoothScroll(element, from, to, duration) {
const startTime = performance.now();
const scrollDistance = to - from;
function step(timestamp) {
const currentTime = timestamp - startTime;
const progress = Math.min(currentTime / duration, 1);
element.scrollTop = from + progress * scrollDistance;
if (progress < 1) {
window.requestAnimationFrame(step);
}
}
window.requestAnimationFrame(step);
}
});
長いコードとなりましたが、これで一連の動作が出来るスクロールボックスが実装できました。