【CSS/JS】マウスホイールで横スクロールできるボックス

マウスホイールで横スクロールできるボックス JS CSS
  • URLをコピーしました!

ボックスの上でマウスホイールを動かすと横方向にスクロールし、超過すると通常の縦スクロールが開始されるコードです。

目次(クリックでジャンプ)

マウスホイールで横スクロールできるボックス

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)

下記コードはSCSSで記述していますCSSでコードを使いたい方は、手動またはツール等でCSSに変換して使ってください。
オンラインSCSS→CSSコンバーター
SCSSをCSSにリアルタイムで変えるツール

.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);
    }
});

長いコードとなりましたが、これで一連の動作が出来るスクロールボックスが実装できました。

おすすめのフリーランス向け求人・案件探しサービス

高単価案件、週3日~などフレキシブルな働きが可能な事が特徴の転職サービスです。案件をチェックするだけであれば無料の為、エンジニアやデザイナーの方は是非登録してみてください。

4275件と案件数豊富です(2024年4月現在)
マウスホイールで横スクロールできるボックス JS CSS

この記事が気に入ったら
フォローしてね!

役に立った!と思ったらシェアお願いします
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

フリーランスのWebデザイナー「Kizineko」です。Webサイトのデザイン~コーディング、簡易的なプログラム実装等、Web制作に係る広くに携わっております。当ブログでは日々のメモ帳として便利なコードなどを共有しております。

目次(クリックでジャンプ)