728x90
안녕하세요. 오늘은 리액트를 사용해 슬라이드 카드 UI를 만들어보겠습니다.
슬라이드 카드는 이미지, 텍스트 등을 한 화면에서 넘기며 보여줄 수 있는 방식으로,
포트폴리오, 프로젝트 소개, 리뷰 카드 등 다양한 구성에 활용할 수 있습니다.
React에서는 외부 라이브러리 없이도 직접 구현이 가능하지만,
이번에는 react-slick을 활용해 구현해보았습니다.
1. 슬라이드 목록 만들기
자바 스크립트 배열로 슬라이드 하나하나에 들어갈 제목, 내용, 이미지 등을 담은 "목록"을 생성합니다.
const cardData = [
{
title: "1. Wall Sina",
description:
"The innermost wall, where the royal family and nobles reside.",
image: "https://source.unsplash.com/random/800x400?city",
},
{
title: "2. Wall Rose",
description: "The middle wall, home to many of the general populace.",
image: "https://source.unsplash.com/random/800x400?nature",
},
{
title: "3. Wall Maria",
description:
"The outermost and largest wall, the first to fall during the Titans' initial attack.",
image: "https://source.unsplash.com/random/800x400?space",
},
];
2. 화살표 버튼 만들기
JSX 문법을 활용해 html 형식으로 버튼을 만들어줍니다.
function PrevArrow(props) {
return (
<button
onClick={props.onClick}
style={{
position: "absolute",
left: "-60px",
top: "50%",
transform: "translateY(-50%)",
zIndex: 10,
padding: "12px 18px",
fontSize: "20px",
borderRadius: "50%",
border: "none",
backgroundColor: "rgba(0, 0, 0, 0.6)",
color: "white",
cursor: "pointer",
}}
>
←
</button>
);
}
function NextArrow(props) {
return (
<button
onClick={props.onClick}
style={{
position: "absolute",
right: "-60px",
top: "50%",
transform: "translateY(-50%)",
zIndex: 10,
padding: "12px 18px",
fontSize: "20px",
borderRadius: "50%",
border: "none",
backgroundColor: "rgba(0, 0, 0, 0.6)",
color: "white",
cursor: "pointer",
}}
>
→
</button>
);
}
3. 전체 UI 조립
먼저 슬라이더 작동 방식을 setting 해줍니다. 하단 인디케이터 표시 여부, 슬라이드 무한반복 여부, 슬라이드 전환 속도, 한 번에 보여줄 슬라이드 개수 등을 설정합니다.
이후 Slider 컴포넌트 내부에 각 카드 데이터를 html 요소로 랜더링합니
function App() {
const settings = {
dots: true,
infinite: true,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1,
nextArrow: <NextArrow />,
prevArrow: <PrevArrow />,
};
return (
<div className="slider-wrapper">
<Slider {...settings}>
{cardData.map((card, index) => (
<div key={index} className="slide">
<div
className="slide-background"
style={{ backgroundImage: `url(${card.image})` }}
>
<div className="text-box">
<h2>{card.title}</h2>
<p>{card.description}</p>
</div>
</div>
</div>
))}
</Slider>
</div>
);
}
4. 자바스크립트 전체 코드 입니다
import "./App.css";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
import Slider from "react-slick";
const cardData = [
{
title: "1. Wall Sina",
description:
"The innermost wall, where the royal family and nobles reside.",
image: "https://source.unsplash.com/random/800x400?city",
},
{
title: "2. Wall Rose",
description: "The middle wall, home to many of the general populace.",
image: "https://source.unsplash.com/random/800x400?nature",
},
{
title: "3. Wall Maria",
description:
"The outermost and largest wall, the first to fall during the Titans' initial attack.",
image: "https://source.unsplash.com/random/800x400?space",
},
];
function PrevArrow(props) {
return (
<button
onClick={props.onClick}
style={{
position: "absolute",
left: "-60px",
top: "50%",
transform: "translateY(-50%)",
zIndex: 10,
padding: "12px 18px",
fontSize: "20px",
borderRadius: "50%",
border: "none",
backgroundColor: "rgba(0, 0, 0, 0.6)",
color: "white",
cursor: "pointer",
}}
>
←
</button>
);
}
function NextArrow(props) {
return (
<button
onClick={props.onClick}
style={{
position: "absolute",
right: "-60px",
top: "50%",
transform: "translateY(-50%)",
zIndex: 10,
padding: "12px 18px",
fontSize: "20px",
borderRadius: "50%",
border: "none",
backgroundColor: "rgba(0, 0, 0, 0.6)",
color: "white",
cursor: "pointer",
}}
>
→
</button>
);
}
function App() {
const settings = {
dots: true,
infinite: true,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1,
nextArrow: <NextArrow />,
prevArrow: <PrevArrow />,
};
return (
<div className="slider-wrapper">
<Slider {...settings}>
{cardData.map((card, index) => (
<div key={index} className="slide">
<div
className="slide-background"
style={{ backgroundImage: `url(${card.image})` }}
>
<div className="text-box">
<h2>{card.title}</h2>
<p>{card.description}</p>
</div>
</div>
</div>
))}
</Slider>
</div>
);
}
export default App;
5. CSS 전체 코드 입니다
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.slider-wrapper {
width: 100%;
max-width: 900px;
margin: 50px auto;
position: relative;
}
.slick-slide > div {
height: 100%;
}
.slide {
height: 400px;
}
.slide-background {
height: 100%;
width: 100%;
position: relative;
background-size: cover;
background-position: center;
border-radius: 20px;
overflow: hidden;
}
.text-box {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: rgba(0, 0, 0, 0.6);
color: white;
border-radius: 20px;
padding: 30px;
width: 80%;
max-width: 600px;
text-align: center;
}
시연 영상입니다
'React' 카테고리의 다른 글
[React] 메뉴바로 페이지 전환하기 (0) | 2025.05.21 |
---|---|
[React] 인증번호 타이머 만들기 (0) | 2023.12.22 |
[React] 리액트 아이콘 사용하여 아이콘 적용하기 (0) | 2023.12.12 |
[React] 드래그앤 드롭으로 파일 업로드 하기 (2) | 2023.11.22 |
[React] 파일 업로드 버튼 만들기 (0) | 2023.11.12 |