가로 스크롤 컴포넌트 만들기

Project Diary/React + Firebase (Snack ShoppingMall)

가로 스크로 컴포넌트 구현 방법 기록


 

1. SnackSlider.js 파일을 생성하고 기본 컴포넌트를 작성

import React, { useRef } from "react";
import styled, { keyframes } from "styled-components";
import { Link } from "react-router-dom";

// 애니메이션 효과 정의
const hoverLine = keyframes`
  0% {
    opacity: 0;
    transform: translateX(-100%);
  }
  50% {
    opacity: 1;
    transform: translateX(0%);
  }
  100% {
    opacity: 0;
    transform: translateX(100%);
  }
`;

// 컨테이너 스타일 정의
const Container = styled.div`
  ::-webkit-scrollbar {
    display: none;
  }
  position: relative;
  padding: 50px 0 300px 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: #5a462099;
  .animal {
    position: absolute;
    top: 79%;
    right: 5%;
  }
  .flower {
    position: absolute;
    width: 30%;
    top: 0%;
    left: 0%;
  }
  h2 {
    text-align: center;
    color: #5a4620;
    font-size: 45px;
    margin-bottom: 100px;
  }
  @media screen and (max-width: 412px) {
    padding: 20px 0 200px 0;
    .animal {
      top: 70%;
    }
    .flower {
      width: 60%;
      left: -20%;
      z-index: 0;
    }
    h2 {
      font-size: 40px;
      z-index: 1;
    }
  }
`;

// 슬라이더 스타일 정의
const SliderWrapper = styled.div`
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  white-space: nowrap;
  padding: 0 120px;

  .slide {
    position: relative;
    border: 2px solid #5a4620;
    border-radius: 30px;
    flex: 0 0 30%;
    height: 600px;
    display: inline-flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    padding: 0 50px;
    margin: 0px 20px;
    background: url("./assets/image/fadein/3_bg1_pc-252c0289.webp");
    background-size: cover;
    h3 {
      color: #5a4620;
      font-size: 30px;
    }
    img {
      z-index: 2;
      width: 250px;
      margin: 40px 0;
    }
    .desc {
      text-align: center;
      color: #5a4620;
      margin-bottom: 30px;
      p {
        padding: 4px;
      }
    }
    a {
      margin-right: 50px;
      color: #5a4620;
      font-weight: bold;
      position: relative;
      &::before {
        overflow: hidden;
        content: "";
        position: absolute;
        height: 1px;
        width: 100%;
        top: 50%;
        left: 110%;
        background-color: #5a4620;
      }
      &:hover::before {
        animation: ${hoverLine} 1.5s infinite;
        visibility: visible;
      }
    }
  }
  @media screen and (max-width: 412px) {
    padding: 0px 50px;
    .slide {
      flex: 0 0 100%;
      height: 400px;
      padding: 0 10px;
      margin: 0px 20px;
      h3 {
        font-size: 25px;
      }
      img {
        width: 150px;
        margin: 20px 0 20px 0;
      }
      .desc {
        margin-bottom: 20px;
      }
    }
  }
`;

 

 

2. 가로 스크롤 구현

슬라이더를 가로로 스크롤하게 하기 위해 `overflow-x: auto`를 사용하고, `white-space: nowrap`으로 요소가 한 줄로 나열되도록 설정합니다.

``javascript
const SliderWrapper = styled.div`
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  white-space: nowrap;
  padding: 0 120px;
  .slide {
    position: relative;
    border: 2px solid #5a4620;
    border-radius: 30px;
    flex: 0 0 30%;
    height: 600px;
    display: inline-flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    padding: 0 50px;
    margin: 0px 20px;
    background: url("./assets/image/fadein/3_bg1_pc-252c0289.webp");
    background-size: cover;
  }
  @media screen and (max-width: 412px) {
    padding: 0px 50px;
    .slide {
      flex: 0 0 100%;
      height: 400px;
      padding: 0 10px;
      margin: 0px 20px;
    }
  }
`;



3. 애니메이션 및 효과 추가

슬라이더 내부의 텍스트 링크에 애니메이션을 추가하여 마우스 호버 시 효과를 줄 수 있어요.

const hoverLine = keyframes`
  0% {
    opacity: 0;
    transform: translateX(-100%);
  }
  50% {
    opacity: 1;
    transform: translateX(0%);
  }
  100% {
    opacity: 0;
    transform: translateX(100%);
  }
`;

const SliderWrapper = styled.div`
  .slide a {
    position: relative;
    color: #5a4620;
    font-weight: bold;
    &:hover::before {
      animation: ${hoverLine} 1.5s infinite;
      visibility: visible;
    }
  }
`;