본문 바로가기
> 클론코딩/분석 및 활용

[CSS] How To Make An Infinite Autoplay Slider 분석과 수정

by 자몽주스 2024. 7. 9.
728x90


HTML
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>자동 슬라이드</title>
    <link href="autoplay.css" rel="stylesheet" />
  </head>
  <body>
    <div class="slider">
      <div class="slide-track">
        <div class="slide"><img src="/img/swiper-1.jpg" /></div>
        <div class="slide"><img src="/img/swiper-2.jpg" /></div>
        <div class="slide"><img src="/img/swiper-3.jpg" /></div>
        <div class="slide"><img src="/img/swiper-4.jpg" /></div>
        <div class="slide"><img src="/img/swiper-5.jpg" /></div>
        <div class="slide"><img src="/img/swiper-6.jpg" /></div>
        <div class="slide"><img src="/img/swiper-7.jpg" /></div>
        <div class="slide"><img src="/img/swiper-8.jpg" /></div>
        <div class="slide"><img src="/img/swiper-9.jpg" /></div>

        <!-- doubled -->
        <div class="slide"><img src="/img/swiper-1.jpg" /></div>
        <div class="slide"><img src="/img/swiper-2.jpg" /></div>
        <div class="slide"><img src="/img/swiper-3.jpg" /></div>
        <div class="slide"><img src="/img/swiper-4.jpg" /></div>
        <div class="slide"><img src="/img/swiper-5.jpg" /></div>
        <div class="slide"><img src="/img/swiper-6.jpg" /></div>
        <div class="slide"><img src="/img/swiper-7.jpg" /></div>
        <div class="slide"><img src="/img/swiper-8.jpg" /></div>
        <div class="slide"><img src="/img/swiper-9.jpg" /></div>
      </div>
    </div>
  </body>
</html>
CSS - 유튜브 보고 주석 단 코드. 
body {
  min-height: 100vh; /* 최소 높이를 화면 전체 높이로 설정 */
  display: grid; /* 그리드 레이아웃 사용 */
  place-items: center; /* 아이템을 가운데로 정렬 */
}

.slider {
  /* overflow: hidden; // 가로 스크롤 바 없애기 위해 주석 처리 */
  height: 250px; /* 슬라이더의 높이 설정 */

  margin: auto; /* 슬라이더를 가운데 정렬 */
  
  width: 90%; /* 슬라이더의 너비를 부모 요소의 90%로 설정 */
  display: grid; /* 그리드 레이아웃 사용 */
  place-items: center; /* 아이템을 가운데로 정렬 */
}

.slide-track {
  display: flex; /* 슬라이드를 수평으로 정렬 */
  width: calc(250px * 18); /* 슬라이드 트랙의 너비 설정 (18개의 슬라이드) */
  animation: scroll 40s linear infinite; /* 40초 동안 linear(선형) 무한히 반복하는 애니메이션 설정 */
}

.slide-track:hover {
  animation-play-state: paused; /* 슬라이드 트랙에 마우스 오버 시 애니메이션 일시 정지 */
}

/* keyframes */
@keyframes scroll {
  0% {
    transform: translateX(0); /* 애니메이션 시작 시 위치 */
  }
  100% {
    transform: translateX(calc(-250px * 9)); /* 애니메이션 끝 위치 (슬라이드 9개 이동) */
  }
}

.slide {
  height: 200px; /* 슬라이드의 높이 설정 */
  width: 250px; /* 슬라이드의 너비 설정 */
  display: flex; /* 슬라이드 내용물을 수평으로 정렬 */
  align-items: center; /* 슬라이드 내용물을 수직으로 가운데 정렬 */
  padding: 15px; /* 슬라이드 안쪽 여백 설정 */
  perspective: 100px; /* 3D 효과를 위한 원근법 설정 */
}

img {
  transition: transform 1s; /* 이미지 변환 애니메이션 시간 설정 */
  width: 100%; /* 이미지 너비를 슬라이드 너비에 맞게 설정 */
}

img:hover {
  transform: translateZ(20px); /* 이미지에 마우스 오버 시 3D 효과 적용 */
}

body min-height: 100vh를 준 이유

전체 화면 높이 확보

  • min-height: 100vh는 body 요소의 최소 높이를 뷰포트의 전체 높이(100% 뷰포트 높이)로 설정합니다.
  • 이렇게 하면 콘텐츠가 적더라도 body 요소는 항상 화면 전체를 덮을 수 있습니다.

콘텐츠 중앙 정렬

  • display: grid와 place-items: center 속성을 사용하면 body 안의 콘텐츠가 수직 및 수평으로 중앙에 배치됩니다.
  • 이를 통해, 콘텐츠가 적더라도 화면 중앙에 정렬된 상태를 유지할 수 있습니다.

일관된 레이아웃

  • min-height: 100vh를 사용하면 화면 크기가 커지거나 작아져도
  • body 요소가 최소한 화면 전체를 덮어 일관된 레이아웃을 유지할 수 있습니다.
  • 특히, 슬라이더와 같은 콘텐츠가 화면 중앙에 위치하도록 하기 위해 유용합니다.

body slider에 각각 display: grid와 place-items: center를 준 이유

 

서로 다른 레벨에서의 중앙 정렬을 처리하기 위해서입니다.

이 두 개의 레이아웃 컨테이너는 각각의 역할을 가지며,

 

최종적으로 콘텐츠를 중앙에 배치하는 데 기여합니다.

아래에서 각 컨테이너에 대해 자세히 설명드리겠습니다.

1. body의 display: gridplace-items: center

body 요소는 전체 화면을 덮는 컨테이너로 설정되어 있으며, 내부의 모든 콘텐츠를 중앙에 배치합니다.

이 설정은 페이지 전체에서 콘텐츠를 중앙에 정렬하기 위한 것입니다.

body {
  min-height: 100vh; /* 최소 높이를 화면 전체 높이로 설정 */
  display: grid; /* 그리드 레이아웃 사용 */
  place-items: center; /* 아이템을 수직 및 수평으로 중앙에 정렬 */
}

이 설정은 body 요소의 자식 요소인 .slider를 화면 중앙에 위치시키는 역할을 합니다.

2. slider의 display: grid와 place-items: center

slider 요소는 슬라이더 자체의 컨테이너로, 슬라이더 내부의 콘텐츠를 중앙에 정렬합니다.

이 설정은 슬라이더 내에서 이미지를 중앙에 배치하기 위한 것입니다.

.slider {
  overflow: hidden; /* 가로 스크롤 바 없애기 위해 주석 해제 */
  height: 250px; /* 슬라이더의 높이 설정 */
  margin: auto; /* 슬라이더를 가운데 정렬 */
  position: relative; /* 슬라이더를 상대 위치로 설정 */
  width: 90%; /* 슬라이더의 너비를 부모 요소의 90%로 설정 */
  display: grid; /* 그리드 레이아웃 사용 */
  place-items: center; /* 아이템을 수직 및 수평으로 중앙에 정렬 */
}

이 설정은 .slider 내의 자식 요소인 .slide-track을 슬라이더 컨테이너 내에서 중앙에 배치합니다.

종합 정리

  • body의 display: grid와 place-items: center는 페이지 전체의 중앙 정렬을 담당합니다.
  • slider의 display: grid와 place-items: center는 슬라이더 내부 콘텐츠의 중앙 정렬을 담당합니다.

이 두 단계의 정렬을 통해, 슬라이더가 화면의 중앙에 위치하게 되고

슬라이더 내의 콘텐츠도 슬라이더 컨테이너의 중앙에 위치하게 됩니다.

이는 전체 레이아웃을 균형 있게 유지하고, 사용자에게 일관된 시각적 경험을 제공합니다.


slider에 margin:auto 는 한 이유 ( 어차피 place-item 으로 가운데 정렬했음에도 불구하고 )

 

slider에 margin: auto를 사용하는 이유는

place-items: center만으로는 해결되지 않는 경우가 있기 때문

place-items: center와 margin: auto의 차이점

  • **place-items: center**그리드 컨테이너의 자식 요소를 수직 및 수평 방향으로 중앙에 정렬하는 역할을 합니다.
  • **margin: auto** 블록 요소를 그 부모 컨테이너 내에서 수평 방향으로 중앙에 정렬하는 역할을 합니다.

특정 사용 사례

  1. **place-items: center**그리드 레이아웃 내에서 자식 요소를 중앙에 배치합니다. 이는 그리드 셀 내에서 자식 요소가 중앙에 정렬되도록 합니다.
  2. **margin: auto**는 그리드 컨테이너 자체를 부모 요소 내에서 수평으로 중앙에 배치하는 데 사용됩니다. 이 경우 slider가 body 요소의 중앙에 배치되도록 합니다.

예시

place-items: center가 슬라이더 컨테이너 내에서 슬라이드 트랙을 중앙에 정렬하고,

margin: auto가 슬라이더 컨테이너 자체를 수평 방향으로 중앙에 정렬합니다.

구체적인 이유

  • 슬라이더 컨테이너의 수평 정렬: margin: auto슬라이더 컨테이너(.slider)를 부모 요소인 body 내에서 수평으로 중앙에 배치합니다.
  • 슬라이더 내 콘텐츠의 중앙 정렬: place-items: center슬라이더 내부의 콘텐츠(예: .slide-track)를 슬라이더 컨테이너 내에서 중앙에 정렬합니다.

따라서, margin: auto는 슬라이더 자체를 수평으로 중앙에 배치하는 데 사용되고,

place-items: center는 슬라이더 내부의 콘텐츠를 중앙에 배치하는 데 사용됩니다.

 

이 두 가지를 조합하면, 전체 레이아웃과 내부 콘텐츠 모두 중앙에 배치된 상태를 유지할 수 있습니다.


.slide-track 에서의 width 계산법하고, keyframes scroll translateX 계산법

 

.slide-track {
  display: flex; /* 슬라이드를 수평으로 정렬 */
  width: calc(250px * 18); /* 슬라이드 트랙의 너비 설정 (18개의 슬라이드) */
  animation: scroll 40s linear infinite; /* 20초 동안 linear(선형) 무한히 반복하는 애니메이션 설정 */
}
/* keyframes */
@keyframes scroll {
  0% {
    transform: translateX(0); /* 애니메이션 시작 시 위치 */
  }
  100% {
    transform: translateX(
      calc(-250px * 9)
    ); /* 애니메이션 끝 위치 (슬라이드 9개 이동) */
  }
}

.slide-track widthkeyframes scroll translateX 계산법은

슬라이더가 매끄럽게 무한히 반복되도록 하기 위한 설정입니다.

.slide-track의 width 계산법

.slide-track의 width 슬라이드의 개수와 각 슬라이드의 너비를 바탕으로 계산됩니다.

.slide-track {
  display: flex; /* 슬라이드를 수평으로 정렬 */
  width: calc(250px * 18); /* 슬라이드 트랙의 너비 설정 */
  animation: scroll 40s linear infinite; /* 애니메이션 설정 */
}

설명:

  • .slide-track에는 총 18개의 슬라이드가 있습니다.
  • 각 슬라이드의 너비는 250px입니다.
    .slide {
      height: 200px; /* 슬라이드의 높이 설정 */
      width: 250px; /* 슬라이드의 너비 설정 */
  • width: calc(250px * 18)는 슬라이드 트랙의 전체 너비를 계산합니다.

keyframes scroll의 translateX 계산법

keyframes scroll의 translateX 슬라이드 트랙이 한 사이클 동안 얼마나 이동할지를 정의합니다.

@keyframes scroll {
  0% {
    transform: translateX(0); /* 애니메이션 시작 위치 */
  }
  100% {
    transform: translateX(calc(-250px * 9)); /* 애니메이션 끝 위치 */
  }
}

설명:

  • 0% { transform: translateX(0); }는 애니메이션 시작 시 슬라이드 트랙의 위치입니다.
  • 100% { transform: translateX(calc(-250px * 9)); }는 애니메이션 끝 위치로,
  • 슬라이드 트랙이 왼쪽으로 9개의 슬라이드 너비만큼 이동합니다.

왜 9개의 슬라이드만큼 이동하는가?

트랙에 있는 슬라이드가 9개만큼 이동하면 트랙이 정확히 으로 나뉘게 됩니다.

 

처음 9개의 슬라이드는 화면에서 완전히 사라지고,

뒤에 붙어 있는 9개의 복제 슬라이드가 처음 9개의 슬라이드 대신 화면에 나타나게 됩니다.

이렇게 하면 트랙이 무한히 반복되는 것처럼 보입니다. 

  • 슬라이드 트랙의 슬라이드가 9개씩 반복되는 이유무한 루프 애니메이션을 만들기 위해서입니다.
  • 트랙에 18개의 슬라이드를 배치하여 각 슬라이드가 2번 반복되도록 했습니다.
  • 이는 처음 9개의 슬라이드가 끝나면 그 다음 9개의 슬라이드가 자연스럽게 이어지게 하기 위함입니다.
  • 슬라이드 트랙이 9개의 슬라이드 너비만큼 이동하면 처음 9개의 슬라이드가 왼쪽으로 사라지고,
  • 그 뒤에 있는 9개의 슬라이드가 보입니다.
  • 슬라이드 트랙이 계속 이동하면 처음 슬라이드들이 다시 나타나며, 무한 반복 애니메이션이 됩니다.

요약

  1. .slide-track의 width는 전체 슬라이드 트랙의 너비를 정의하며,
  2. 총 18개의 슬라이드가 있기 때문에 250px * 18으로 계산합니다.
  3. @keyframes scroll의 translateX(calc(-250px * 9))은 애니메이션이 끝날 때 슬라이드 트랙이 왼쪽으로 9개의 슬라이드 너비만큼 이동하도록 설정합니다.
  4. 이는 무한 반복 애니메이션을 만들기 위해 슬라이드가 부드럽게 이어지도록 합니다.

이렇게 설정하면 슬라이드가 빈 여백 없이 반복되는 효과를 만들 수 있습니다.


slide 너비(width: 250px)를 기준으로 곱해주는 이유

슬라이드 너비를 기준으로 계산하는 이유


수정하기
수정된 CSS 
body {
  min-height: 100vh; /* 최소 높이를 화면 전체 높이로 설정 */
  display: grid; /* 그리드 레이아웃 사용 */
  place-items: center; /* 아이템을 가운데로 정렬 */
}

.slider {
  overflow: hidden; /* 가로 스크롤 바 없애기 */
  height: 250px; /* 슬라이더의 높이 설정 */
  margin: auto; /* 슬라이더를 가운데 정렬 */
  position: relative; /* 슬라이더를 상대 위치로 설정 */
  width: 90%; /* 슬라이더의 너비를 부모 요소의 90%로 설정 */
  display: grid; /* 그리드 레이아웃 사용 */
  place-items: center; /* 아이템을 가운데로 정렬 */
}

.slide-track {
  display: flex; /* 슬라이드를 수평으로 정렬 */
  width: calc(250px * 18); /* 슬라이드 트랙의 너비 설정 (18개의 슬라이드) */
  animation: scroll 20s linear infinite; /* 20초 동안 linear(선형) 무한히 반복하는 애니메이션 설정 */
}

.slide-track:hover {
  animation-play-state: paused; /* 슬라이드 트랙에 마우스 오버 시 애니메이션 일시 정지 */
}

/* keyframes */
@keyframes scroll {
  0% {
    transform: translateX(0); /* 애니메이션 시작 시 위치 */
  }
  100% {
    transform: translateX(calc(-250px * 9)); /* 애니메이션 끝 위치 (슬라이드 9개 이동) */
  }
}

.slide {
  height: 200px; /* 슬라이드의 높이 설정 */
  width: 250px; /* 슬라이드의 너비 설정 */
  display: flex; /* 슬라이드 내용물을 수평으로 정렬 */
  align-items: center; /* 슬라이드 내용물을 수직으로 가운데 정렬 */
  padding: 15px; /* 슬라이드 안쪽 여백 설정 */
  perspective: 100px; /* 3D 효과를 위한 원근법 설정 */
}

img {
  transition: transform 1s; /* 이미지 변환 애니메이션 시간 설정 */
  width: 100%; /* 이미지 너비를 슬라이드 너비에 맞게 설정 */
}

img:hover {
  transform: translateZ(20px); /* 이미지에 마우스 오버 시 3D 효과 적용 */
}

1. .slider의 overflow: hidden 주석 해제

기존 코드는 주석 처리되어 있었는데, 이를 해제하여 슬라이드가 밖으로 넘치지 않도록 했습니다.

.slider {
  overflow: hidden; /* 가로 스크롤 바 없애기 위해 주석 해제 */
  /* 나머지 속성은 동일 */
}

2. .slide-track의 width와 animation 조정

슬라이드 트랙의 너비와 애니메이션 시간을 조정했습니다.

슬라이드 트랙의 너비를 슬라이드 개수에 맞춰 정확히 계산하고,

애니메이션 시간을 조정하여 슬라이드가 자연스럽게 반복되도록 했습니다.

.slide-track {
  width: calc(250px * 18); /* 슬라이드 트랙의 너비 설정 (18개의 슬라이드) */
  animation: scroll 20s linear infinite; /* 애니메이션 시간을 20초로 변경 */
  /* 나머지 속성은 동일 */
}

20초로만 변경됨.


place-items 속성

 

place-items는 CSS 그리드 레이아웃에서 사용되는 단축 속성으로,

그리드내의 아이템

수직(align-items) 및 수평(justify-items) 방향 모두에서 정렬하는 역할을 합니다.

 

place-items는 그리드 컨테이너 내의 아이템을

수직(align-items) 및 수평(justify-items) 방향 모두에서 정렬하는 단축 속성입니다.

CSS 플렉스박스 레이아웃

플렉스박스 레이아웃에서는 place-items 속성을 사용할 수 없습니다.

대신, align-items와 justify-content 속성을 각각 사용하여 아이템을 수직 및 수평 방향에서 정렬해야 합니다.

  • align-items: 플렉스 컨테이너 내의 아이템을 수직 방향으로 정렬합니다.
  • justify-content: 플렉스 컨테이너 내의 아이템을 수평 방향으로 정렬합니다.

place-items 속성값

place-items 속성은 두 가지 값,

align-items와 justify-items의 값을 순서대로 받습니다.

아래는 가능한 값들의 예입니다:

  • place-items: start; - 수직 및 수평 방향 모두에서 아이템들을 시작 위치에 정렬합니다.
  • place-items: end; - 수직 및 수평 방향 모두에서 아이템들을 끝 위치에 정렬합니다.
  • place-items: center; - 수직 및 수평 방향 모두에서 아이템들을 가운데 정렬합니다.
  • place-items: stretch; - 아이템들을 컨테이너의 크기에 맞게 늘립니다 (기본값).

또한 두 값을 각각 다르게 지정할 수도 있습니다:

place-items: center start; /* 수직 방향은 중앙, 수평 방향은 시작 위치에 정렬 */

이 경우 첫 번째 값은 align-items를, 두 번째 값은 justify-items를 설정합니다.

요약

  • CSS 그리드 레이아웃: place-items를 사용하여 수직 및 수평 방향에서 아이템을 정렬할 수 있습니다.
  • CSS 플렉스박스 레이아웃: place-items를 사용할 수 없으며,
  • align-items와 justify-content를 사용하여 수직 및 수평 방향에서 아이템을 정렬합니다.

body {
  min-height: 100vh; /* 최소 높이를 화면 전체 높이로 설정 */
  // display: grid; /* 그리드 레이아웃 사용 */
  // place-items: center; /* 아이템을 가운데로 정렬 */
}

.slider {
  overflow: hidden; /* 가로 스크롤 바 없애기 */
  height: 250px; /* 슬라이더의 높이 설정 */
  // margin: auto; /* 슬라이더를 가운데 정렬 */
  position: relative; /* 슬라이더를 상대 위치로 설정 */
  // width: 90%; /* 슬라이더의 너비를 부모 요소의 90%로 설정 */
  // display: grid; /* 그리드 레이아웃 사용 */
  // place-items: center; /* 아이템을 가운데로 정렬 */
}

.slide-track {
  display: flex; /* 슬라이드를 수평으로 정렬 */
  width: calc(250px * 18); /* 슬라이드 트랙의 너비 설정 (18개의 슬라이드) */
  animation: scroll 20s linear infinite; /* 20초 동안 linear(선형) 무한히 반복하는 애니메이션 설정 */
}

.slide-track:hover {
  animation-play-state: paused; /* 슬라이드 트랙에 마우스 오버 시 애니메이션 일시 정지 */
}

/* keyframes */
@keyframes scroll {
  0% {
    transform: translateX(0); /* 애니메이션 시작 시 위치 */
  }
  100% {
    transform: translateX(
      calc(-250px * 9)
    ); /* 애니메이션 끝 위치 (슬라이드 9개 이동) */
  }
}

.slide {
  height: 200px; /* 슬라이드의 높이 설정 */
  width: 250px; /* 슬라이드의 너비 설정 */
  display: flex; /* 슬라이드 내용물을 수평으로 정렬 */
  align-items: center; /* 슬라이드 내용물을 수직으로 가운데 정렬 */
  padding: 15px; /* 슬라이드 안쪽 여백 설정 */
  perspective: 100px; /* 3D 효과를 위한 원근법 설정 */
}

img {
  transition: transform 1s; /* 이미지 변환 애니메이션 시간 설정 */
  width: 100%; /* 이미지 너비를 슬라이드 너비에 맞게 설정 */
}

img:hover {
  transform: translateZ(20px); /* 이미지에 마우스 오버 시 3D 효과 적용 */
}
728x90