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

[CSS] Play and Pause in Infinite Slider with CSS Only (2)

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

Play and Pause in Infinite Slider with CSS Only (youtube.com)


.slider {
  width: 100%;
  border: 1px solid red;
  height: var(--height);
  overflow: hidden;
}
.slider .list {
  display: flex;
  width: 100%;
  min-width: calc(var(--width) * var(--quantity));
  position: relative;
}
.slider .list .item {
  width: var(--width);
  height: var(--height);
  position: absolute;
  left: 100%;
  animation: autoRun 10s linear infinite;
  animation-delay: calc((10s / var(--quantity)) * (var(--position) - 1));
}

.slider .list .item img {
  width: 100%;
}

@keyframes autoRun {
  from {
    left: 100%;
  }
  to {
    left: calc(var(--width) * -1);
  }
}
animation-delay: calc((10s / var(--quantity)) * (var(--position) - 1));가 추가된 이유와 그 원리

애니메이션 딜레이의 목적

이 설정의 목적은 슬라이더의 각 아이템이 일정한 간격을 두고

순차적으로 애니메이션을 시작하도록 만드는 것입니다.

이렇게 하면 아이템들이 한 번에 겹쳐서 나타나는 것이 아니라,

순서대로 자연스럽게 슬라이드되는 효과를 줄 수 있습니다.

animation-delay 속성이란?

animation-delay는 CSS 애니메이션이 시작되기 전에 대기할 시간을 지정하는 속성입니다.

이 속성을 통해 애니메이션이 특정 시간 후에 시작되도록 지연시킬 수 있습니다.

원리 설명

1. var(--quantity)와 var(--position)

  • var(--quantity): 슬라이더 아이템의 총 개수입니다. 여기서는 10으로 설정되어 있습니다.
  • var(--position):아이템의 위치를 나타내는 변수입니다. 각 아이템마다 1부터 10까지 순서대로 설정되어 있습니다.

2. 애니메이션의 총 지속 시간

  animation: autoRun 10s linear infinite;
  • 애니메이션의 총 지속 시간은 10초입니다 (10s).

3. 딜레이 계산

animation-delay 속성의 계산식은 다음과 같습니다:

animation-delay: calc((10s / var(--quantity)) * (var(--position) - 1));

 

1. 총 시간을 각 아이템의 개수로 나누기:

10s / var(--quantity)

 

총 10초의 애니메이션 시간을 아이템의 개수(10)로 나누면,

각 아이템이 차례대로 나타나는 시간 간격이 1초가 됩니다.

즉, 각 아이템이 1초 간격으로 나타나게 됩니다.

 

 

2. 각 아이템의 위치에 따른 딜레이 계산:

calc((10s / var(--quantity)) * (var(--position) - 1))

 

  • var(--position) - 1는 아이템의 순서를 0부터 시작하도록 조정합니다.
왜 0부터 시작하도록 조정하는가? >> 애초에 첫 번째 아이템 position 을 0으로 하면 되는거 아닌가? 

calc((10s / var(--quantity)) * (var(--position) - 1))의 계산에서
왜 var(--position) - 1을 사용하여 0부터 시작하도록 조정하는지와,
애초에 첫 번째 아이템의 position을 0으로 하면 안 되는 이유를 설명드리겠습니다.

1. CSS 변수의 직관성 유지
아이템의 position을 1부터 시작하도록 설정한 이유는 다음과 같은 이유로 더 직관적입니다:
직관적 이해: 사람들은 일반적으로 첫 번째 아이템을 1로, 두 번째 아이템을 2로 생각합니다.
즉, 아이템의 순서가 자연스럽게 1부터 시작되도록 설정하면 코드의 가독성이 좋아집니다.
유지 보수 용이: 코드 작성자와 유지 보수자가 아이템의 순서를 직관적으로 이해할 수 있습니다.
이는 협업 시에도 중요한 요소입니다.

2. 계산의 용이성
calc((10s / var(--quantity)) * (var(--position) - 1))의 계산식을 통해 지연 시간을 계산할 때,
var(--position)이 1부터 시작하도록 하면 수학적 계산이 간단해집니다.
첫 번째 아이템은 지연 없이 즉시 애니메이션을 시작하고,
두 번째 아이템부터 일정한 간격으로 지연됩니다.

3. 0-based Indexing의 피하기
CSS 변수에서 인덱스를 0부터 시작하는 대신
1부터 시작하도록 설정하는 것은 일반적인 관행입니다.
이는 다른 상황에서도 동일한 패턴을 유지하기 위해서입니다.
예를 들어, CSS의 nth-child 선택자도 1부터 시작합니다.

예시: 1부터 시작하는 경우

첫 번째 아이템은 calc((10s / 10) * (1 - 1)) = calc(1s * 0) = 0s 지연.
두 번째 아이템은 calc((10s / 10) * (2 - 1)) = calc(1s * 1) = 1s 지연.
세 번째 아이템은 calc((10s / 10) * (3 - 1)) = calc(1s * 2) = 2s 지연.

예시: 0부터 시작하는 경우
첫 번째 아이템은 calc((10s / 10) * 0) = 0s 지연.
두 번째 아이템은 calc((10s / 10) * 1) = 1s 지연.
세 번째 아이템은 calc((10s / 10) * 2) = 2s 지연.
이 방식도 가능하지만, 일반적인 관행과 맞지 않아 가독성이 떨어질 수 있습니다.

요약 > 
가독성: 첫 번째 아이템을 1로 설정하는 것이 더 직관적이고 가독성이 좋습니다.
계산의 용이성: var(--position) - 1를 사용하면 계산이 간단해지고,
첫 번째 아이템은 지연 없이 즉시 애니메이션을 시작할 수 있습니다.
유지 보수: 코드 작성자와 유지 보수자가 쉽게 이해할 수 있도록 1부터 시작하는 방식이 더 나은 선택입니다.

  • 예를 들어, 첫 번째 아이템의 position이 1이면 1 - 1 = 0이 되어 딜레이가 0초가 됩니다.
  • 두 번째 아이템은 2 - 1 = 1이 되어 딜레이가 1초가 됩니다.
  • 이렇게 하면 각 아이템이 순서대로 1초 간격으로 나타나게 됩니다.

 

시각적 설명

  1. 첫 번째 아이템 (--position: 1)
    • calc((10s / 10) * (1 - 1))
calc((10s / 10) * (1 - 1)) 이 식 자체를 이해하기 >>
calc(1s * 0) = 0s

단계별로 이해하기
1. 10s
10s는 애니메이션의 총 지속 시간입니다. 여기서는 10초입니다.
2. 10
10은 아이템의 총 개수입니다. 예를 들어, 슬라이더에 10개의 아이템이 있습니다.
3. (1 - 1)
(var(--position) - 1)는 현재 아이템의 위치를 0부터 시작하도록 조정한 것입니다.
예를 들어, 첫 번째 아이템의 위치는 1이므로 1 - 1 = 0이 됩니다.

요약
10s / 10은 애니메이션 총 시간을 아이템 개수로 나누어
각 아이템이 몇 초 간격으로 나타나야 하는지를 결정합니다.
(var(--position) - 1)아이템의 위치를 0부터 시작하도록 조정합니다.
calc((10s / 10) * (var(--position) - 1))는 각 아이템이 애니메이션을 시작하기 전에 대기할 시간을 계산합니다.
    • calc(1s * 0) = 0s
    • 딜레이 없이 즉시 애니메이션 시작
  1. 두 번째 아이템 (--position: 2)
    • calc((10s / 10) * (2 - 1))
    • calc(1s * 1) = 1s
    • 1초 딜레이 후 애니메이션 시작
  2. 세 번째 아이템 (--position: 3)
    • calc((10s / 10) * (3 - 1))
    • calc(1s * 2) = 2s
    • 2초 딜레이 후 애니메이션 시작

전체 흐름

  • 첫 번째 아이템이 즉시 애니메이션을 시작합니다.
  • 두 번째 아이템이 1초 후 애니메이션을 시작합니다.
  • 세 번째 아이템이 2초 후 애니메이션을 시작합니다.
  • 마지막(열 번째) 아이템이 9초 후 애니메이션을 시작합니다.

이렇게 하면 모든 아이템이 1초 간격으로 순서대로 이동하게 되어,

자연스럽고 부드러운 슬라이더 애니메이션 효과를 줄 수 있습니다.

요약

animation-delay: calc((10s / var(--quantity)) * (var(--position) - 1));를 추가한 이유는

각 슬라이더 아이템이 일정한 간격을 두고 순차적으로 애니메이션을 시작하도록 하기 위함입니다.

이렇게 하면 아이템들이 한 번에 겹쳐서 나타나는 것이 아니라,

순서대로 자연스럽게 슬라이드되는 효과를 줄 수 있습니다.

 

이 딜레이 계산식은 각 아이템의 위치에 따라 적절한 시간을 계산하여 적용하는 역할을 합니다.


배경 색 넣어주기.

.slider {
  width: 100%;
  border: 1px solid red;
  height: var(--height);
  overflow: hidden;
  background-image: linear-gradient(to right, transparent, #800, transparent);
}

마스크 이미지를 이용해서 

레이어 마스크를 사용해준다.

.slider {
  width: 100%;
  border: 1px solid red;
  height: var(--height);
  overflow: hidden;
  mask-image: linear-gradient(to right, transparent, #800, transparent);
}

 

최종

.slider {
  width: 100%;
  border: 1px solid red;
  height: var(--height);
  overflow: hidden;
  mask-image: linear-gradient(to right, transparent, #000 10% 90%, transparent);
}

슬라이더 일시 중지 기능 만들기

슬라이더에 올릴 때 item에 있는 애니메이션이 멈추게 하기

최종 코드

.slider:hover .item {
  animation-play-state: paused !important;
}

새 슬라이더 생성하기

새 슬라이더 만들기.

html 생성해주고

변수 지정해주기

효과 부여 

= 약간 포커싱 되는 느낌을 준다.

부드럽게 하기 위해서 필터 주기

item 에다가 트랜지션 주는 이유는? 

filter와 transition의 역할

1. filter: grayscale(1);와 filter: grayscale(0);

  • filter: grayscale(1);: 요소를 흑백으로 변환합니다. 1은 완전한 흑백을 의미합니다.
  • filter: grayscale(0);: 요소를 원래 색상으로 유지합니다. 0은 흑백 효과가 없는 상태를 의미합니다.

이 설정을 통해 슬라이더 아이템이 기본적으로 흑백으로 표시되고, 마우스를 올리면 원래 색상으로 돌아오는 효과를 줄 수 있습니다.

2. transition: filter 0.5s;

  • transition: filter 0.5s;: filter 속성이 변경될 때 0.5초 동안 부드럽게 전환되도록 설정합니다.

이 설정을 통해 슬라이더 아이템의 필터 효과가 즉시 변경되는 대신, 서서히 변경되어 더욱 부드러운 사용자 경험을 제공합니다.

transition을 item에 부여한 이유

  1. 마우스 호버 효과:
    • 슬라이더 아이템에 마우스를 올렸을 때, 흑백 필터가 제거되면서 색상이 복원됩니다.
    • transition을 item에 적용하여 filter 속성이 부드럽게 전환되도록 합니다.
  2. 슬라이더 전체 호버 효과:
    • 슬라이더 전체에 마우스를 올리면 애니메이션이 일시정지되고, 모든 아이템에 흑백 필터가 적용됩니다.
    • 이때도 transition이 적용되어 필터 효과가 부드럽게 나타납니다.

두번 째 슬라이더 방향은 반대로 하고 싶다면 , 

저기다가 역방향 만들어줌.

그리고 css 로 가서 

역방향 애니메이션을 만들어주고

키프레임도 만들어준다.

important 도 붙여줌.

.slider .list .item {
  width: var(--width);
  height: var(--height);
  position: absolute;
  left: 100%;
  animation: autoRun 10s linear infinite;
  transition: filter 0.5s;
  animation-delay: calc(
    (10s / var(--quantity)) * (var(--position) - 1)
  ) !important;
}
important 를 부여한 이유 >>

다른 CSS 규칙에 의해 이 속성이 덮어씌워지지 않도록 보장하기 위함입니다.
!important는 CSS에서 특정 속성이 가장 높은 우선순위를 가지게 하여,
동일한 속성에 대해 나중에 정의된 다른 규칙이 있더라도 해당 속성이 적용되도록 합니다.

!important 사용 이유

  1. 우선순위 보장:
    • 애니메이션 딜레이는 각 아이템이 순차적으로 애니메이션을 시작하도록 하는 중요한 부분입니다.
    • 다른 CSS 규칙이 나중에 정의되어 이 속성을 덮어씌우지 않도록 하기 위해 !important를 사용합니다.
  2. CSS 규칙의 일관성 유지:
    • 슬라이더의 아이템들이 정확히 정의된 지연 시간에 따라 순차적으로 애니메이션을 시작해야 합니다.
    • 만약 다른 CSS 파일이나 규칙에 의해 animation-delay가 변경된다면, 슬라이더의 애니메이션 흐름이 깨질 수 있습니다.
    • 이를 방지하기 위해 !important를 사용하여 정의된 지연 시간이 항상 적용되도록 보장합니다.

main {
  width: min(1200px, 90vw);
  margin: auto;
}

. width: min(1200px, 90vw);

1. width: min(1200px, 90vw);

  • min(1200px, 90vw):
    • min() 함수는 두 값 중 작은 값을 선택합니다.
    • 여기서는 1200px과 90vw 중 작은 값을 선택하여 main 요소의 너비를 설정합니다.
    • 1200px은 픽셀 단위의 고정 너비입니다.
    • 90vw는 뷰포트 너비(Viewport Width)의 90%를 의미합니다.
    • 예를 들어, 화면 너비가 1000px이면 90vw는 900px이 됩니다. 이 경우 min() 함수는 900px을 선택합니다.

2. margin: auto;

  • margin: auto;:
    • 수평 방향의 마진을 자동으로 설정하여 main 요소를 수평으로 가운데 정렬합니다.
    • width가 설정되어 있을 때, 남은 공간이 양쪽 마진으로 균등하게 분배됩니다.

왜 이렇게 지정했는가?

  1. 반응형 디자인:
    • width: min(1200px, 90vw);를 사용함으로써 main 요소가 반응형으로 동작하게 됩니다.
    • 화면 너비가 충분히 넓을 때는 main 요소의 너비가 최대 1200px로 제한됩니다.
    • 화면 너비가 좁을 때는 main 요소의 너비가 화면 너비의 90%로 설정됩니다. 이렇게 하면 좁은 화면에서도 적절한 여백을 유지할 수 있습니다.
  2. 중앙 정렬:
    • margin: auto;를 사용하여 main 요소를 화면 가운데에 배치합니다.
    • 이로 인해 main 요소가 항상 화면 중앙에 위치하게 되어 사용자 경험이 향상됩니다.

시각적 설명

  1. 화면 너비가 1400px일 때:
    • 90vw는 1400px * 0.9 = 1260px이 됩니다.
    • min(1200px, 1260px)은 1200px을 선택합니다.
    • 따라서 main 요소의 너비는 1200px이 되고, 화면 중앙에 배치됩니다.
  2. 화면 너비가 1000px일 때:
    • 90vw는 1000px * 0.9 = 900px이 됩니다.
    • min(1200px, 900px)은 900px을 선택합니다.
    • 따라서 main 요소의 너비는 900px이 되고, 화면 중앙에 배치됩니다.

요약

  • 반응형 디자인: width: min(1200px, 90vw);를 사용하여
  • main 요소가 화면 크기에 따라 적절히 조정되도록 합니다.
  • 중앙 정렬: margin: auto;를 사용하여 main 요소를 화면 중앙에 배치합니다.
  • 이 설정을 통해 main 요소가 다양한 화면 크기에서 일관된 레이아웃을 유지하며, 사용자 경험을 향상시킵니다.

이와 같이 width: min(1200px, 90vw);와 margin: auto;를 사용하면 반응형 디자인과 중앙 정렬을 쉽게 구현할 수 있습니다.

728x90