무한한 CSS 캐러셀 만들기

여러 시간 동안 검색하고 고군분투한 후에도 여전히 무한 CSS 캐러셀을 만드는 방법에 대한 좋은 가이드를 찾을 수 없었습니다. 이것이 html과 css를 사용하여 수행할 수 없는 이유는 없지만 거의 모든 가이드는 시도했을 때 실제로 작동하지 않는 javascript 또는 css를 사용하고 있습니다.

매우 간단하지만 작업 예제를 사용할 수 없으므로 Rhosys에서 브랜드 캐러셀을 만들기 위해 수행한 작업을 공유합니다.

물론 완성된 제품을 먼저 보고 싶을 수도 있습니다.

코드에 뛰어들기



간단한 디스플레이는 다음과 같습니다.

<section class="user-cloud">
  <div class="brands-container">
    <div class="brands-carousel">
      <picture>
        <source srcset="assets/images/s-customer-cloud1.png"
            media="(max-width: 766px)" />
        <img src="assets/images/customer-cloud1.png" />
      </picture>
      <picture>
        <source srcset="assets/images/s-customer-cloud2.png"
            media="(max-width: 766px)" />
        <img src="assets/images/customer-cloud2.png" />
      </picture>
      <picture>
        <source srcset="assets/images/s-customer-cloud3.png"
            media="(max-width: 766px)" />
        <img src="assets/images/customer-cloud3.png" />
      </picture>
      <picture>
        <source srcset="assets/images/s-customer-cloud4.png"
            media="(max-width: 766px)" />
        <img src="assets/images/s-customer-cloud4.png" />
      </picture>
    </div>
  </div>
</section>


모바일에는 4개의 이미지가 있고 데스크톱에는 3개의 이미지만 있습니다. 반응형으로 만들기 위해 picturesource가 설정된 img 태그를 사용합니다. 이미지 선택기가 작동하지 않아서 그림을 사용합니다. 이유는 모르겠지만 그것과 싸우는 것보다 이렇게 하는 것이 더 쉽습니다. 지저분한 작업x2 multiples이나 화면에 표시되어야 하는 요소의 크기를 파악할 필요가 없습니다.

그런 다음 멋진 패딩과 설정을 컨테이너에 추가합니다.

중요: 여기에서 max-width는 항상 모든 사진의 너비와 같아야 하므로 100%는 전체 사진 너비를 의미합니다.

.brands-container {
  /* all pictures should be the same size as this value. */
  max-width: 1050px;
  margin: auto;
  padding:0 1em;
  overflow: hidden;
}

.brands-carousel {
  position: relative;
  padding-left: 0;
  margin: 0;
  height: 200px;
  overflow: hidden;
}

.brands-carousel > div {
  width: 100%;
}


이것이 상대적으로 간단한 설정이며 중요한 설정은 다음과 같습니다.

/* Each picture in the carousel is 100% of the parent. */
.brands-carousel > picture {
  width: 100%;
  position: absolute;
  top: 0;
  display: flex;
  justify-content: center;
  animation: carousel 20s linear infinite;

  /* It also starts off the screen until it is time. */
  transform: translateX(100%);
}


(first-picture 키프레임에 대한 이야기는 잠시 건너뛰겠습니다.)
모든 사진은 동일한 설정으로, 화면으로 이동하고 다음 사진이 이동할 때까지 그 자리에 머무르는 데 N초가 걸립니다. 데스크탑에서 계산하면 세 장의 사진이 있으므로 각 사진은 무대에서 시간의 1/3을 얻습니다.

.brands-carousel > picture:nth-child(1) {
  animation-name: first-picture, carousel;
  animation-duration: 20s;
  animation-iteration-count: 1, infinite;
  animation-delay: 0s, 20s;
  transform: translateX(0%);
}
.brands-carousel > picture:nth-child(2) {
  animation-delay: Calc(20s * .33);
}
.brands-carousel > picture:nth-child(3) {
  animation-delay: Calc(20s * .66);
}



/* The keyframes for desktop */
@keyframes first-picture {
  0% { transform: translateX(0%); }
  7.5%, 33% { transform: translateX(0); }
  40.5%, 100% { transform: translateX(-100%); }
}

@keyframes carousel {
  0% { transform: translateX(100%); }
  7.5%, 33% { transform: translateX(0); }
  40.5%, 100% { transform: translateX(-100%); }
}


따라서 메인 키프레임은 캐러셀입니다. 각 이미지는 시간의 1/3 동안 무대에 있기 때문에 20s 시간의 7.5%를 사용하여 미끄러져 들어가고 33%가 끝날 때까지 거기에 머무르며 전송됩니다. 각 이미지는 들어가는 데 7.5%가 걸리므로 나가는 데에도 7.5%가 걸립니다.33% + 7.5% = 40.5 .

그리고 이것은 20대의 33%가 완전히 표시되는 이미지가 없을 때까지 한 가지를 제외하고 거의 완벽하게 작동합니다. 이에 대한 수정은 첫 번째 이미지를 두 번 표시하는 해킹입니다. 시작할 때까지 화면에 표시하고 출발할 때까지 오른쪽 화면에서 동시에 표시합니다. 그런 다음 두 번째 애니메이션을 한 라운드 지연시킵니다. 이 때문에 first-picture 키프레임이 필요하며 이는 훌륭하게 작동합니다.

/* The keyframes for mobile */
@keyframes first-picture-responsive {
  0% { transform: translateX(0%); }
  5.5%, 25% { transform: translateX(0); }
  30.5%, 100% { transform: translateX(-100%); }
}

@keyframes carousel-responsive {
  0% { transform: translateX(100%); }
  5.5%, 25% { transform: translateX(0); }
  30.5%, 100% { transform: translateX(-100%); }
}


데스크탑에 네 번째 사진을 표시하지 않음

.brands-carousel > picture:last-child {
  display: none;
}


모바일에서는 약간의 조정을 할 것입니다. 3개에 20초가 아니라 4개 이미지에 27초가 있고 각 이미지는 스테이지에서 시간의 1/4을 차지합니다.

@media screen and (max-width: 766px) {
  .brands-carousel > picture {
    animation: carousel-responsive 27s linear infinite;
  }

  .brands-carousel > picture:nth-child(1) {
    animation-name: first-picture-responsive, carousel-responsive;
    animation-duration: 27s;
    animation-iteration-count: 1, infinite;
    animation-delay: 0s, 27s;
  }

  .brands-carousel > picture:nth-child(2) {
    animation-delay: Calc(27s * .25);
  }
  .brands-carousel > picture:nth-child(3) {
    animation-delay: Calc(27s * .50);
  }
  .brands-carousel > picture:nth-child(4) {
    animation-delay: Calc(27s * .75);
    display: block;
  }
}


마무리



전체 애니메이션 루프의 시간을 변경하려면 20s를 새 전체 시간으로 바꿉니다. 전환이 화면에 표시되는 시간을 변경하려면 7.5%를 더 작은 값으로 줄입니다(그리고 40.5%도 같은 양만큼 줄입니다). 다른 변경을 하려면(즉, 이미지가 정지된 시간을 늘리려면 총 시간의 33%를 기준으로 계산한 다음 전환 비율을 다시 계산해야 합니다.

현재 정적 이미지는 7.5% ~ 33%로 화면에서 20대(5.1s)의 25.5%입니다. 전환 시간( 6s )을 줄이지 않고 화면에 7.5% * 20s = 1.5s 표시되도록 하려면. 전체 애니메이션의 총 새 시간6 / .255 = 23.5s을 계산하면 새 전환 비율이 1.5s / 23.5s = 6.4%이므로 새 키프레임은

/* # Updating all the 20s => 23.5s */
@keyframes carousel {
  0% { transform: translateX(100%); }
  6.4%, 33% { transform: translateX(0); }
  39.4%, 100% { transform: translateX(-100%); }
}


그리고 그게 다야.

여기 link to the code

좋은 웹페이지 즐겨찾기