横スライド 送りボタン(ホバー付き) キャプション上部(アニメーション) さらに背景おしゃれ

< コードコピーサンプル
<!-- ここにコードをそのまま貼る --><!-- ここにコードをそのまま貼る --><!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8" />
  <title>スライドギャラリー + キャプションアニメーション</title>
  <style>
    body {
      margin: 0;
      font-family: sans-serif;
      background: #faf8f5;
    }

    .gallery-container {
      position: relative;
      width: 95%;
      max-width: 900px;
      margin: 20px auto;
      padding: 10px;
      background: #faf8f5;
      border: 3px solid #96514D;
      border-radius: 16px;
      box-shadow:
        0 8px 16px rgba(0, 0, 0, 0.1),
        inset 0 0 10px rgba(255, 255, 255, 0.4);
    }

   .scroll-wrapper {
  position: relative;
  background: linear-gradient(to right, #f8e8e0, #fff);
}


    .scroll-gallery {
      display: flex;
      overflow-x: auto;
      scroll-snap-type: x mandatory;
      scroll-behavior: smooth;
      -webkit-overflow-scrolling: touch;
      scroll-padding-left: 10px;
      scroll-padding-right: 10px;
    }

    .scroll-gallery-item {
      flex: 0 0 100%;
      scroll-snap-align: start;
      box-sizing: border-box;
      padding: 10px;
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    .scroll-gallery-item img {
      width: 100%;
      height: auto;
      border-radius: 10px;
      border: 2px solid #ccc;
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
      object-fit: cover;
      transition: transform 0.3s ease;
      display: block;
      user-select: none;
    }

    .scroll-gallery-item img:hover {
      transform: scale(1.01);
    }

    /* キャプション基本スタイル */
    .caption {
      font-size: 22px;
      font-weight: bold;
      font-family: 'Playfair Display', 'Georgia', serif;
      text-align: center;
      margin-bottom: 12px;
      background: linear-gradient(90deg, #8c5c3e, #cfa98c);
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      letter-spacing: 1.5px;
      user-select: none;

      /* 初期は隠れていて下にずれてる */
      opacity: 0;
      transform: translateY(20px);
      transition: opacity 0.8s ease, transform 0.8s ease;
    }

    .caption {
  /* 元は translateY(20px); だったのを変更 */
  opacity: 0;
  transform: translateX(100px);
  transition: opacity 0.8s ease, transform 0.8s ease;
}

.scroll-gallery-item.active .caption {
  opacity: 1;
  transform: translateX(0);
}


   .scroll-button {
  position: absolute;
  top: 0px;
  z-index: 10;
  background-color: rgba(255, 255, 255, 0.2); /* 半透明 */
  backdrop-filter: blur(8px); /* 背景ぼかし */
  -webkit-backdrop-filter: blur(8px); /* Safari対応 */
  border: 1px solid rgba(255, 255, 255, 0.4); /* 少し透明な白い枠 */
  border-radius: 50%;
  width: 40px;
  height: 40px;
  font-size: 20px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;
  user-select: none;
}


    .scroll-button:hover {
      background: rgba(255, 255, 255, 0.95);
      box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
      transform: scale(1.1);
    }

    .scroll-left {
      left: 10px;
    }

    .scroll-right {
      right: 10px;
    }

    @media (max-width: 600px) {
      .caption {
        font-size: 14px !important;
      }

      .scroll-gallery-item img {
        border-radius: 6px !important;
        border: 1px solid #ccc !important;
      }

      .scroll-button {
        width: 32px;
        height: 32px;
        font-size: 16px;
      }

      .scroll-left {
        left: 5px !important;
      }

      .scroll-right {
        right: 5px !important;
      }
    }
  </style>
</head>
<body>
  <div class="gallery-container">
    <div class="scroll-wrapper">
      <!-- 左右ボタン -->
      <button class="scroll-button scroll-left" aria-label="左にスクロール" onclick="scrollGallery(-1)">←</button>
      <button class="scroll-button scroll-right" aria-label="右にスクロール" onclick="scrollGallery(1)">→</button>

      <div class="scroll-gallery" id="gallery">
        <!-- 写真1 -->
        <div class="scroll-gallery-item">
          <div class="caption">ここにキャプションを入れる</div>
          <a href="" target="_blank" rel="noopener noreferrer">
            <img src="" alt="画像1" />
          </a>
        </div>

        <!-- 写真2 -->
        <div class="scroll-gallery-item">
          <div class="caption">ここにキャプションを入れる</div>
          <a href="" target="_blank" rel="noopener noreferrer">
            <img src="" alt="画像2" />
          </a>
        </div>



          <!-- 写真3 -->
        <div class="scroll-gallery-item">
          <div class="caption">ここにキャプションを入れる</div>
          <a href="" target="_blank" rel="noopener noreferrer">
            <img src="" alt="画像2" />
          </a>
        </div>




          <!-- 写真4 -->
        <div class="scroll-gallery-item">
          <div class="caption">ここにキャプションを入れる</div>
          <a href="" target="_blank" rel="noopener noreferrer">
            <img src="" alt="画像2" />
          </a>
        </div>



          <!-- 写真5 -->
        <div class="scroll-gallery-item">
          <div class="caption">ここにキャプションを入れる</div>
          <a href="" target="_blank" rel="noopener noreferrer">
            <img src="" alt="画像5" />
          </a>
        </div>

       
      </div>
    </div>
  </div>

  <script>
    const gallery = document.getElementById('gallery');
    const items = gallery.querySelectorAll('.scroll-gallery-item');

    function scrollGallery(direction) {
      const width = gallery.clientWidth;
      gallery.scrollBy({ left: width * direction, behavior: 'smooth' });
    }

    // キーボード操作対応
    document.addEventListener('keydown', (e) => {
      if (e.key === 'ArrowRight') scrollGallery(1);
      if (e.key === 'ArrowLeft') scrollGallery(-1);
    });

    // スクロールイベントで現在表示中アイテムの判定&activeクラス付与
    function updateActiveItem() {
      const scrollLeft = gallery.scrollLeft;
      const width = gallery.clientWidth;

      items.forEach((item, index) => {
        if (scrollLeft >= index * width - width / 2 && scrollLeft < (index + 1) * width - width / 2) {
          item.classList.add('active');
        } else {
          item.classList.remove('active');
        }
      });
    }

    // 初期表示時も判定
    updateActiveItem();

    // スクロール時に判定
    gallery.addEventListener('scroll', () => {
      // スクロールが止まったらアクティブ切り替えしたいからタイマー使う
      clearTimeout(gallery._scrollTimeout);
      gallery._scrollTimeout = setTimeout(() => {
        updateActiveItem();
      }, 100); // スクロール停止後100msで判定
    });
  </script>
</body>
</html>
<div>こんにちは!</div>