본문 바로가기
Javascript

Carousel을 만들어 보자(Bootstrap을 이용 + 직접 만드는 방법)

by 즐코딩 2023. 1. 28.
반응형

Carousel을 만들어 보자

 

 

carousel(캐러샐)은 '회전목마'라는 뜻입니다. 아마도 중학교 시절에 merry-go-round라는 단어로 배웠던 것 같습니다.

아무튼 웹사이트 상단 부분에서 비주얼 이미지를 크게 배치해서, 자동으로 슬라이드 되도록 만들어 놓는 것들을 '캐러샐'이라고 부릅니다.

 

캐러샐은 매우 많이 사용되는 UI이기도 한데요, 만드는 방법에 있어서는 까다로운 구석이 존재합니다. 왜냐하면, 정적인 HTML/CSS 물론이거니와 이를 동작하게 해주는 Javascript도 필요해지고, 게다가 화면 전환을 자연스럽게 연출하려면 CSS로 Animation을 적용해야 하기 때문입니다.

 

워드프레스의 경우, 상당한 수준의 캐러샐 라이브러리들은 별도의 유료상품으로 판매되기도 하니까요. 그만큼 홈페이지를 만들 때 주목도를 높여줄 수 있는 carousel을, Bootstrap 템플릿을 이용해서 직접 만들어 보는 과정을 정리해둡니다.

 

 

 

캐러샐용 이미지 3장 준비

 

캐러샐용 이미지는 무료 이미지 소스를 제공하는 픽사베이(pixabay.com)을 이용해서 준비했습니다.

무료-이미지-소스를-제공하는-pixabay.com
무료 이미지 소스를 제공하는 pixabay.com

 

저는 뭔가 판타지스러운 좀비 크리처 이미지를 준비해보았습니다.(개취)

이미지들은 작업 폴더 루트에 복사해 넣었습니다.

 

zombie1.jpg
0.57MB
zombie2.jpg
0.55MB
zombie3.jpg
0.35MB

 

 

 

Bootstrap 템플릿 이용하는 방법

 

HTML 문서의 상단에 부트스트랩용 CSS를 링크해오고, HTML 문서 하단에 부트스트랩용 script를 넣어줍니다.

getbootstrap.com에서 Components 중 Carousel을 복사해다가 빈 HTML 문서에 붙여넣었습니다.

Bootstrap의-Carousel-Component를-사용합니다
Bootstrap의 Carousel Component를 사용합니다

 

그리고, 부트스트랩 템플릿에서 비어 있는 img src 경로를 이미지가 있는 경로로 타이핑을 해서 채워주었습니다.

사실, 이게 다 이긴 합니다. 아래는 준비된 템플릿입니다.

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>My Study</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" />
  </head>
  <body>
    <div id="carouselExample" class="carousel slide">
      <div class="carousel-inner">
        <div class="carousel-item active">
          <img src="zombie1.jpg" class="d-block w-100" alt="..." />
        </div>
        <div class="carousel-item">
          <img src="zombie2.jpg" class="d-block w-100" alt="..." />
        </div>
        <div class="carousel-item">
          <img src="zombie3.jpg" class="d-block w-100" alt="..." />
        </div>
      </div>
      <button class="carousel-control-prev" type="button" data-bs-target="#carouselExample" data-bs-slide="prev">
        <span class="carousel-control-prev-icon" aria-hidden="true"></span>
        <span class="visually-hidden">Previous</span>
      </button>
      <button class="carousel-control-next" type="button" data-bs-target="#carouselExample" data-bs-slide="next">
        <span class="carousel-control-next-icon" aria-hidden="true"></span>
        <span class="visually-hidden">Next</span>
      </button>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
  </body>
</html>

 

참고로, 부트스트랩 캐러셀을 사용하려면 부트스트랩용  JS 파일들을 웹문서에 불러와야 하는 걸 잊지 마세요! 왜냐하면 클릭했을 때 캐러셀이 동작을 해야 하니까 당연하겠죠?

캐러셀에-사용된-첫번째-이미지
캐러셀에 사용된 첫번째 이미지
캐러셀에-사용된-세번째-이미지
캐러셀에 사용된 세번째 이미지

 

이미지 위에 뜬 좌우의 버튼을 클릭해보세요. 잘 동작하죠? 개 쉽습니다.

부트스트랩으로 Carousel 만들기 간단하게 완료하였습니다!!

 

 

 

Carousel을 직접 코딩해서 만들기

 

만약, 이러한 캐러샐을 "직접" 만들어야 한다면 코딩을 어떻게 하면 좋을까요? 부트스트랩이 아주 손쉽게 만들어주기도 하지만, 이 참에 만드는 원리까지 이해하고 다룰 수 있게 된다면, 코딩 근육이 한층 더 성장할 것이라는 생각이 듭니다.

 

부트스트랩용으로 사용했던 템플릿을 싹~ 비우고 새로운 빈 HTML 템플릿을 준비하도록 합니다.

 

 

 

 

Animation 만들기

 

보통 애니메이션은 CSS로 만들게 되는데요, Carousel은 한 방향으로만 움직이니까 one-way 애니메이션이라고도 부를 수 있겠습니다. 양방향 애니메이션은 나중에 다시 살펴볼 수 있도록 하겠습니다.

 

애니메이션을 만드는 4단계 스탭은 다음과 같습니다.

Step. 1 : 시작화면 상태 만들기
Step. 2 : 완료화면 상태 만들기
Step. 3 : 시작화면에서 완료화면으로 변하게 만들 JS 작성하기
Step. 4 : transition : all 1s;를 추가

 

시작상태, 종료상태를 만들고 변하는 스위치를 넣는데, 시작상태의 CSS에 변화시 적용될 trasition 속성을 넣는다!는 것이 애니메이션을 만드는 방법의 시작과 끝, 전부입니다.

 

 

 

Carousel은 결국 이미지를 옆으로 배치해두는 것

 

캐러셀은 가로로 쭈~욱 브라우저 화면 밖까지 이미지를 배치해 놓은 것을, Javascript를 이용해서 배치하는 위치를 변경해주는 방식으로 동작한다는 것이 핵심입니다.

 

아래 설명 이미지를 살펴보면, 브라우저 바깥쪽까지 이미지를 쭉 배치하는 예를 보여주고 있습니다.

브라우저에-꽉-차는-이미지-3개를-화면-밖까지-가로로-배치하였습니다.
브라우저에 꽉 차는 이미지 3개를 화면 밖까지 가로로 배치하였습니다.

미리 HTML/CSS로 이렇게 만들어 놓으면 되지 않을까요?

 

 

div를 이용해서 캐러셀 모양을 만듭니다

 

HTML은 다음과 같이 작성했습니다. 3개의 div를 1개의 부모(container) div가 감싸는 형태로 만들었습니다.

<body>
    <div class="container">
      <div class="slide">
        <img src="zombie1.jpg" alt="" />
      </div>
      <div class="slide">
        <img src="zombie2.jpg" alt="" />
      </div>
      <div class="slide">
        <img src="zombie3.jpg" alt="" />
      </div>
    </div>
  </body>

 

이 상태로는 이미지가 위에서 아래로 보이게 될 것입니다. 왜냐면, div가 block요소 이기 때문에 그렇겠죠?

div는-블록요소-이기-때문에-아래로-배치되겠죠?
div는 블록요소 이기 때문에 아래로 배치되겠죠?

 

CSS로 스타일링을 해주도록 해보겠습니다.

.container {
  width: 300vw;   /* vw는 viewport width, 스크린 크게에 맞춘 상대적 가로 크기 */
}                 /* 100vw 짜리 3개를 보여줘야 하므로, 300vw로 설정 */ 
.slide {
  width: 100vw;
  float: left;   /* float: left로 띄움 */
}
.slide img {
  width: 100%;   /* 이미지 크기가 너무 커서, 브라우저 가로에 대응하도록 100% */
}

 

CSS를 적용하고 나면, 사이즈가 컸던 이미지의 가로폭이 브라우저 가로폭에 딱 들어맞으면서, 300vw에 의해 하단에 스크롤바가 생겼습니다. 스크롤 바를 우측으로 이동시키면 2번, 3번 이미지를 확인할 수 있습니다.(현재는 브라우저 화면이 300vw 인 것입니다)

300vw-스타일로-인해-화면이-가로로-길어져서&#44;-하단-스크롤바가-생겼습니다
300vw 스타일로 인해 화면이 가로로 길어져서, 하단 스크롤바가 생겼습니다

 

화면이 넘치는 것을 숨겨주어야 의도한 캐러셀 형태가 될 것이기 때문에, div 하나를 더 이용해서 전체를 감싸줍니다. 그리고 style로 overflow: hidden; 을 주도록 합니다.

<body>
  <div class="outer" style="overflow: hidden">
    <div class="container">
      <div class="slide">
        <img src="zombie1.jpg" alt="" />
      </div>
      <div class="slide">
        <img src="zombie2.jpg" alt="" />
      </div>
      <div class="slide">
        <img src="zombie3.jpg" alt="" />
      </div>
    </div>
  </div>
</body>

 

이렇게 해주면, 브라우저 하단의 가로 스크롤이 사라지고 첫번째 캐러셀 이미지 하나만 브라우저 가로폭에 꽉 찬 형태로 보여지게 됩니다. overflow: hidden;을 적용하였기 때문에 브라우저 화면에서 흘러 넘치는 2번, 3번 이미지는 숨김처리가 된 것입니다.

overflow:hidden으로-2&#44;-3번째-이미지는-숨겼습니다
overflow: hidden으로 2, 3번째 이미지는 숨겼습니다

 

이제 화면을 좌우로 넘길 수 있는 버튼만 준비되면 되지 않을까요?

캐러셀 하단에 버튼을 3개 만들어 넣습니다. 그리고 [2]번 버튼을 클릭할 때, .container를 -100vw 만큼 이동시켜 주면 되지 않을까요? 어디 한번 코드를 작성해보도록 합시다.

 

<body>
  <div class="outer" style="overflow: hidden">
    <div class="container">
      <div class="slide">
        <img src="zombie1.jpg" alt="" />
      </div>
      <div class="slide">
        <img src="zombie2.jpg" alt="" />
      </div>
      <div class="slide">
        <img src="zombie3.jpg" alt="" />
      </div>
    </div>
  </div>
  <button class="slide1">1</button>
  <button class="slide2">2</button>
  <button class="slide3">3</button>
</body>
.container {
  width: 300vw;
  transition: all 1s;   /* 변환 움직임을 부드럽게 하기 위해 추가 */
}
.slide {
  width: 100vw;
  float: left;
}
.slide img {
  width: 100%;
}
document.querySelector(".slide2").addEventListener("click", function () {
  document.querySelector(".container").style = "margin-left: -100vw;";
});

 

HTML/CSS + Javascript 코드는 위와 같이 작성했습니다. 브라우저에서 실행을 시킨 후 [2] 번 버튼을 클릭해보면, 2번째 슬라이드로 잘~ 이동하는 모습을 확인할 수 있습니다. 신기하죠? 네, 신기합니다.

버튼을-클릭하면-다음-이미지가-슬라이드-인으로-들어옵니다.
버튼을 클릭하면 다음 이미지가 슬라이드 인으로 들어옵니다.

 

 

[팁] 애니메이션에서는 margin 보다 translate()을 사용하자

 

위 예제 코드에서는 margin-left를 사용해서 container를 움직였는데요, 애니메이션을 적용할 때는 magin 보다는 translate() 함수를 사용하는 게 성능적인 면에서 잇점이 크다고 합니다. margin은 Static 한 웹문서 시절에 만든 CSS 속성이잖아요?

 

때문에 이처럼 애니메이션을 구성할 때는 translateX(-100vw); 라고 써주는 것이 보다 좋겠습니다.

아래는, 오늘 포스팅의 최종 코드입니다.(코드들을 그냥 1개 문서로 모았습니다.)

 

최종 결과물 코드

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Carousel</title>
    <style>
      .container {
        width: 300vw;
        transition: all 1s;
      }
      .slide {
        width: 100vw;
        float: left;
      }
      .slide img {
        width: 100%;
      }
    </style>
  </head>
  <body>
    <div class="outer" style="overflow: hidden">
      <div class="container">
        <div class="slide">
          <img src="zombie1.jpg" alt="" />
        </div>
        <div class="slide">
          <img src="zombie2.jpg" alt="" />
        </div>
        <div class="slide">
          <img src="zombie3.jpg" alt="" />
        </div>
      </div>
    </div>
    <button class="slide1">1</button>
    <button class="slide2">2</button>
    <button class="slide3">3</button>
  </body>
  <script>
    document.querySelector(".slide2").addEventListener("click", function () {
      document.querySelector(".container").style = "transform: translateX(-100vw);";
    });
  </script>
</html>

 

 

 

마치며

 

뭔가 복잡하기만 해 보였던, Carousel을 부트스트랩을 이용해서 간단하게 만들어 본 후, Vanilla JS를 이용해서 직접 코드를 작성해보면서 캐러셀의 원리를 파악해보는 시간을 가져보았습니다.

 

분량이 길어져서 끊지만, 나머지 버튼들에 대한 기능 구현은 앞의 내용들을 토대로, 직접 한번 시도 해보시기 바랍니다.

백견이 불여일행! 지금 더딘듯 진행이 되어도, 직접 코딩을 경험 해보면서 깨닫는 것이 결국 가장 빠른 길이 됩니다.

 

즐거운 코딩생활, 즐코딩.

KINcoding.

 

 

반응형

댓글