HTML

スワイプ対応!PC・スマホ対応の横スクロールWebページでモーダル表示を実装する方法

Webサイトのユーザーインターフェースをより直感的で魅力的にするためには、視覚的な要素を活用した動きやインタラクションが重要です。
特に、横スクロールを利用したインタラクティブなデザインは、ユーザーの注意を引きつけ、特にモバイルデバイスでの操作性向上に大きく寄与します。
この記事では、PCとスマートフォンの両方に対応した横スクロール演出を取り入れたWebページを作成し、その中でアイコンクリック時にモーダルを表示する方法を紹介します。

このページでは、HTML、CSS、JavaScriptを使い、スワイプ対応の横スクロールを作り、ページ内のアイコンや画像をクリックした際にモーダルウィンドウを表示する仕組みを実装します。特に、レスポンシブデザインに配慮し、PC・スマホどちらでも快適に動作するように設計しています。

PC、スマホ対応(レスポンシブ)、横スクロール演出、左右スワイプ、モーダル表示とは

1. 横スクロール演出

横スクロール演出とは、ページ内で水平方向にコンテンツがスライドして表示される動きのことです。この演出を使用することで、コンテンツをよりダイナミックに見せることができ、特にイラストやアイコンを使って視覚的に魅力的なページを作成することができます。

2. スワイプ対応

スマートフォンやタブレットでは、画面をスワイプすることによってコンテンツをスクロールできることが多いです。ユーザーがタッチ操作を行うことで、横スクロールができるようにすることで、モバイルデバイスでの操作感を向上させます。

3. モーダル表示

モーダル表示とは、ユーザーが特定のコンテンツをクリックしたときに、そのコンテンツに関連する詳細な情報や画像をポップアップウィンドウとして表示する方法です。これにより、ユーザーは現在のページを離れずに追加情報を確認することができ、インタラクションの流れが途切れることなくスムーズに情報提供が可能となります。

どんな時に使える?

このような横スクロールとモーダル表示のデザインは、特に以下のような場面で有効です。

  • ポートフォリオサイト:
    制作したプロジェクトを横にスライドさせて表示し、アイコンをクリックすると詳細な情報やスクリーンショットがモーダルで表示されるようなインタラクションを加えることで、視覚的に魅力的で使いやすいポートフォリオサイトを作成できます。
  • 製品紹介ページ:
    製品やサービスをアイコンや画像で示し、クリックすることで詳細な説明をモーダルで表示することで、ユーザーの興味を引きつけやすくなります。
  • チュートリアルやインフォグラフィックス:
    スライドショー形式で進めるようなチュートリアルページで、各ステップや項目を横スクロールで表示し、クリックで詳細な情報をポップアップすることで、学習体験をより魅力的にすることができます。

PC、スマホ対応(レスポンシブ)、横スクロール演出、左右スワイプ、モーダル表示を実装

このセクションでは、上記の機能を実現するために必要なHTML、CSS、JavaScriptのコードとその内容説明を行います。

HTMLコードとコード内容説明

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>スワイプ対応の横スクロールWebページでアイコンクリックでモーダル表示するデモページ</title>
  <meta name="description" content="スワイプ対応の横スクロールWebページでアイコンクリックでモーダル表示するデモページ">
  <link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="scroll-container">
  <div class="scroll-content">
    <div class="item" data-title="Car" data-description="This is a car.">
      <div class="icon car-icon"></div>
    </div>
    <div class="item" data-title="Person" data-description="This is a person.">
      <div class="icon person-icon"></div>
    </div>
    <div class="item" data-title="Building" data-description="This is a building.">
      <div class="icon building-icon"></div>
    </div>
    <div class="item" data-title="Tree" data-description="This is a tree.">
      <div class="icon tree-icon"></div>
    </div>
    <div class="item" data-title="Sun" data-description="This is the sun.">
      <div class="icon sun-icon"></div>
    </div>
    <div class="item" data-title="Moon" data-description="This is the moon.">
      <div class="icon moon-icon"></div>
    </div>
  </div>
</div>

<div id="modal" class="modal">
  <div class="modal-content">
    <span class="close">&times;</span>
    <h2 id="modal-title"></h2>
    <p id="modal-description"></p>
  </div>
</div>

<script src="script.js"></script>
</body>
</html>

このHTMLコードでは、横スクロール可能なコンテナ (scroll-container) 内に、複数のアイテム(item)を配置しています。
各アイテムはクリック可能なアイコンを含み、そのクリックに応じてモーダルが表示される仕組みになっています。
また、modalというIDを持つ要素がモーダルの背景として表示され、モーダル内にはクリックされたアイテムに関連するタイトルと説明が表示されます。

CSSコードとコード内容説明(style.css)

body {
  margin: 0;
  background: #f0f0f0;
}
h1{
  text-align: center;
  padding: 15px;
  font-size: 22px;
}

.scroll-container {
  width: 100vw;
  height: 100vh;
  overflow-x: auto;
  overflow-y: hidden;
  display: flex;
  align-items: center;
  position: relative;
  scroll-behavior: smooth; /* Enables smooth scrolling */
  background: #333333;
}

.scroll-content {
  display: flex;
  height: 100%;
  white-space: nowrap;
}

.item {
  flex: 0 0 auto;
  width: 300px;
  height: 300px;
  margin: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #fff;
  border-radius: 10px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  cursor: pointer;
}

.icon {
  width: 100px;
  height: 100px;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 50%;
}

.car-icon {
  background-color: #ff5722;
  box-shadow: 0 0 10px rgba(255, 87, 34, 0.6);
}

.person-icon {
  background-color: #4caf50;
  box-shadow: 0 0 10px rgba(76, 175, 80, 0.6);
}

.building-icon {
  background-color: #2196f3;
  box-shadow: 0 0 10px rgba(33, 150, 243, 0.6);
}

.tree-icon {
  background-color: #8bc34a;
  box-shadow: 0 0 10px rgba(139, 195, 74, 0.6);
}

.sun-icon {
  background-color: #ffeb3b;
  box-shadow: 0 0 10px rgba(255, 235, 59, 0.6);
}

.moon-icon {
  background-color: #9e9e9e;
  box-shadow: 0 0 10px rgba(158, 158, 158, 0.6);
}

.modal {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  justify-content: center;
  align-items: center;
}

.modal-content {
  background: #fff;
  padding: 20px;
  border-radius: 10px;
  text-align: center;
}

.close {
  position: absolute;
  top: 10px;
  right: 20px;
  font-size: 24px;
  cursor: pointer;
}

このCSSでは、横スクロール可能なコンテナのスタイル、アイテムの見た目、アイコンのデザインを定義しています。
flexを使用してコンテナ内にアイテムを横並びに配置し、アイコンには円形のデザインを施しています。
また、モーダルウィンドウは画面全体に表示され、背景を半透明にすることで強調されます。

JavaScriptコードとコード内容説明(script.js)

document.addEventListener('DOMContentLoaded', () => {
  const scrollContainer = document.querySelector('.scroll-container');
  const modal = document.getElementById('modal');
  const modalTitle = document.getElementById('modal-title');
  const modalDescription = document.getElementById('modal-description');
  const closeModal = document.querySelector('.close');
  let isMouseDown = false;
  let startX;
  let scrollLeft;

  // Enable horizontal scrolling with left-click + drag for PC
  scrollContainer.addEventListener('mousedown', (e) => {
    if (e.button === 0) { // Left-click only
      isMouseDown = true;
      startX = e.pageX - scrollContainer.offsetLeft;
      scrollLeft = scrollContainer.scrollLeft;
      scrollContainer.style.cursor = 'grabbing';
    }
  });

  scrollContainer.addEventListener('mouseleave', () => {
    isMouseDown = false;
    scrollContainer.style.cursor = 'default';
  });

  scrollContainer.addEventListener('mouseup', () => {
    isMouseDown = false;
    scrollContainer.style.cursor = 'default';
  });

  scrollContainer.addEventListener('mousemove', (e) => {
    if (!isMouseDown) return;
    const x = e.pageX - scrollContainer.offsetLeft;
    const walk = (x - startX) * 2; // Adjust scroll speed for smoother movement
    scrollContainer.scrollLeft = scrollLeft - walk;
  });

  // Disable dragging when mouse is released even during movement
  scrollContainer.addEventListener('click', () => {
    isMouseDown = false;
  });

  // Keyboard arrow keys for horizontal scrolling on PC
  window.addEventListener('keydown', (e) => {
    const scrollAmount = 50; // Adjust scroll amount for smooth movement
    if (e.key === 'ArrowLeft') {
      scrollContainer.scrollLeft -= scrollAmount;
    } else if (e.key === 'ArrowRight') {
      scrollContainer.scrollLeft += scrollAmount;
    }
  });

  // Enable horizontal scrolling with touch for mobile
  scrollContainer.addEventListener('touchstart', (e) => {
    startX = e.touches[0].pageX - scrollContainer.offsetLeft;
    scrollLeft = scrollContainer.scrollLeft;
  });

  scrollContainer.addEventListener('touchmove', (e) => {
    const x = e.touches[0].pageX - scrollContainer.offsetLeft;
    const walk = (x - startX) * 2; // Adjust scroll speed for smoother movement
    scrollContainer.scrollLeft = scrollLeft - walk;
  });

  // Modal functionality
  const items = document.querySelectorAll('.item');
  items.forEach((item) => {
    item.addEventListener('click', () => {
      const title = item.getAttribute('data-title');
      const description = item.getAttribute('data-description');
      modalTitle.textContent = title;
      modalDescription.textContent = description;
      modal.style.display = 'flex';
    });
  });

  closeModal.addEventListener('click', () => {
    modal.style.display = 'none';
  });

  window.addEventListener('click', (e) => {
    if (e.target === modal) {
      modal.style.display = 'none';
    }
  });
});

このJavaScriptコードでは、横スクロール機能やタッチスクロール、クリックイベントを処理します。
モーダルの表示もここで制御されており、アイテムをクリックするとモーダルが表示され、閉じるボタンを押すとモーダルが非表示になります。

スワイプ対応の横スクロールWebページでアイコンクリックでモーダル表示するデモページ

実装内容は以下のデモページから確認できます。

スワイプ対応の横スクロールWebページでアイコンクリックでモーダル表示するデモページ

注意点

実装時の注意点は以下の通りです:

  • パフォーマンス
    大量のアイテムや画像を表示する場合、パフォーマンスに影響を与える可能性があります。必要に応じて、画像の遅延読み込みやスクロールイベントの最適化を行ってください。
  • モーダルの閉じ方
    モーダルを閉じる際、画面をクリックすることで閉じることができますが、他にもエスケープキーで閉じる機能を追加するとユーザーにとって使いやすくなります。

まとめ

この記事では、PCとスマートフォンに対応した横スクロール演出と、アイコンクリックでモーダルを表示するWebページを作成する方法を紹介しました。コードの実装方法に加えて、どのようなシチュエーションでこのデザインが有用かも説明しました。

 
※参考にされる場合は自己責任でお願いします。
 デモページheadタグ内のGoogleアナリティクスタグは流用しないで下さい。