캐러셀 슬라이드 효과는 캐러셀에 시각적 흥미를 더하는 좋은 방법입니다. 사용자가 슬라이드를 스크롤하면 각 슬라이드가 스크롤 포트에 들어가고, 중앙에 배치되고, 종료될 때 애니메이션을 적용할 수 있습니다. 예를 들어 슬라이드가 페이드 인 및 아웃되거나, 회전하거나, 크기가 조정될 수 있습니다. 이를 통해 역동적이고 몰입도 높은 사용자 환경을 제공할 수 있습니다. 간단한 시작/종료 애니메이션과 달리 이 효과는 단일 연속 애니메이션을 사용하여 전체 스크롤포트에서 슬라이드의 모양을 제어합니다.
구현 방법
캐러셀 슬라이드 효과를 만드는 방법은 다음과 같습니다.
스크롤러 만들기: 이 요소는 캐러셀 슬라이드의 컨테이너 역할을 합니다. 이 예에서는
overflow-x: scroll를 사용하여 가로 스크롤을 허용합니다.<ul class="scroller"> <li class="entry">1</li> <li class="entry">2</li> <li class="entry">3</li> … </ul>.scroller { overflow-x: scroll; }애니메이션 정의: 슬라이드가 스크롤포트를 가로지를 때 슬라이드의 다양한 상태를 정의하는 CSS 애니메이션을 만듭니다. 애니메이션의 모든 부분에 키프레임을 정의할 수 있습니다. 예를 들어
50%키프레임을 포함하여 슬라이드가 스크롤 포트 중앙에 있을 때의 상태를 정의할 수 있습니다. 이 예시에서는scale속성으로 인해 슬라이드가 중앙에 가까워질수록 커지고 멀어질수록 작아집니다.@keyframes animate { 0% { scale: 0.5; } 50% { scale: 1; } 100% { scale: 0.5; } }애니메이션 및
view-timeline적용: 애니메이션을 캐러셀 슬라이드에 연결하고 컨테이너를 스크롤할 때 요소를 추적하는view-timeline에 연결합니다..scroller > * { animation: animate auto linear both; animation-timeline: view(inline); }기본적으로
view()는block축에서 요소를 추적합니다.inline축에서 추적해야 하는 경우view(inline)를 사용하면 됩니다.
예시 코드
이 코드는 익명 view-timeline을 사용하여 스크롤 시 가로 스크롤러의 캐러셀 항목에 애니메이션을 적용합니다.
@keyframes animate {
0% {
scale: 0.5;
}
50% {
scale: 1;
}
100% {
scale: 0.5;
}
}
.scroller > * {
/* Applies the animation using an `auto` duration */
animation: animate auto linear both;
/* Sets the animation timeline to use an anonymous view progress timeline, tracking the element's progress through the scroller on the inline axis */
animation-timeline: view(inline);
}
이 코드는 이름이 지정된 view-timeline을 사용하여 스크롤 시 가로 스크롤러의 캐러셀 항목에 애니메이션을 적용합니다.
@keyframes animate {
0% {
scale: 0.5;
}
50% {
scale: 1;
}
100% {
scale: 0.5;
}
}
/* This creates a named view-timeline on each carousel item. The timeline is used to drive the animation that is applied on the same element. */
.scroller > * {
/* Applies the animation using an `auto` duration */
animation: animate auto linear both;
/* Defines a named view progress timeline, tracking the element's progress through the scroller on the inline axis */
view-timeline: --item inline;
/* Sets the animation timeline to use the named view progress timeline defined above */
animation-timeline: --item;
}
권장사항
스크롤 기반 애니메이션을 사용할 때는 원활하고 접근성 높은 환경을 보장하기 위해 몇 가지 권장사항을 따르는 것이 중요합니다.
- 권장사항: 기능 감지를 포함합니다. 모든 브라우저가 스크롤 기반 애니메이션을 지원하는 것은 아닙니다.
@supports ((animation-timeline: view()) and (animation-range: entry))를 사용하여 지원 여부를 확인하고 지원하지 않는 브라우저에 대체 기능을 제공합니다.- 일부만 지원하는 브라우저를 필터링하려면 여기에
(animation-range: entry)검사를 포함해야 합니다(MUST). scroll-timeline-polyfill패키지는 기능이 완전하지 않고 알려진 문제가 많으므로 대체 전략에 사용하지 마세요.- 애니메이션이 장식용으로만 간주되는 경우 점진적 개선을 선택하고 대체 기능을 제공하지 마세요.
- 일부만 지원하는 브라우저를 필터링하려면 여기에
- 권장사항 사용자 환경설정 존중: 일부 사용자는 웹에서 모션이 적은 것을 선호합니다.
prefers-reduced-motion미디어 쿼리를 사용하여 이러한 사용자의 애니메이션을 사용 중지하거나 줄입니다. - 권장사항: 성능이 우수한 CSS 속성에만 애니메이션을 적용하세요. 가장 부드러운 애니메이션을 구현하려면 브라우저의 컴포지터 스레드에서 처리할 수 있는 속성(예:
transform및opacity)에만 애니메이션을 적용하세요.width또는height와 같은 다른 속성에 애니메이션을 적용하면 성능 문제가 발생할 수 있습니다. - 권장사항: 올바른 선언 순서를 사용합니다.
animation약식 속성을 사용하는 경우 약식이 타임라인을 재설정하지 않도록animation-timeline및animation-range를 뒤에 선언합니다.
여러 DOM 요소가 동일한 타임라인을 기반으로 애니메이션을 적용해야 하거나 view-timeline가 정의된 요소의 하위 요소에 애니메이션을 적용해야 하는 경우 이름이 지정된 view-timeline를 사용하는 것이 좋습니다. 애니메이션을 적용하는 요소가 view-timeline를 정의하는 요소이기도 한 경우 view()를 사용하여 익명의 view-timeline을 사용할 수 있습니다.
view() 함수를 사용하여 스크롤 기반 애니메이션을 만들 때 다음을 참고하세요.
- 선택사항 추적할 축을 명시적으로 지정: 기본
block축을 타겟팅하지 않는 경우 (예: 가로 스크롤러)view(block)또는view(inline)를 사용하여 추적할 축을 명시적으로 지정합니다.
view-timeline 속성을 사용하여 스크롤 기반 애니메이션을 만들 때 다음을 수행합니다.
- 이름에 CSS
<dashed-ident>를 사용합니다 (예:view-timeline: --my-custom-name). 권장 - 선택사항 추적할 축을 명시적으로 지정: 기본
block축을 타겟팅하지 않는 경우 (예: 가로 스크롤러)view-timeline-axis를 사용하여 추적할 축을 명시적으로 지정합니다. - 권장사항: 조회 범위가 작동하는지 확인합니다.
view-timeline를 선언하는 요소가 애니메이션 요소의 플랫 트리 상위 요소가 아닌 경우 공유 상위 요소에서timeline-scope를 사용하여view-timeline이름의 공개 상태를 호이스팅합니다.
브라우저 지원 및 대체 전략
따라서 일반적으로 대체 전략이 필요합니다.
스크롤 기반 애니메이션을 지원하지 않는 브라우저의 경우 대체 기능을 사용하여 시각 효과를 다시 만들 수 있습니다. 대체는 일반적으로 스크롤 리스너 (ScrollTimeline 효과의 경우) 또는 IntersectionObserver API (ViewTimeline 효과의 경우)를 사용하여 빌드됩니다.
스크롤 기반 애니메이션을 기본적으로 지원하는 브라우저에서는 항상 네이티브 CSS 구현을 사용하세요. 성능이 더 우수합니다.
대체 접근 방식을 사용하여 모든 효과를 다시 만들 수 있는 것은 아닙니다.
이 사용 사례의 경우 다음 스크립트는 스크롤 기반 애니메이션을 지원하지 않는 브라우저에 대체 기능을 적용합니다. Web Animations API (Element.animate())를 사용하여 캐러셀의 각 항목에 대해 일시중지된 애니메이션을 만듭니다. 그런 다음 스크롤러의 scroll 이벤트를 수신 대기하고 스크롤러 내 항목의 스크롤 진행 상황에 따라 각 애니메이션의 currentTime를 업데이트합니다.
// Fallback for browsers that don't support scroll-driven animations
if (!CSS.supports('(animation-timeline: view()) and (animation-range: entry)')) {
const scroller = document.querySelector('.scroller');
const entries = document.querySelectorAll('.entry');
// Create a map to store animations
const animations = new Map();
entries.forEach(entry => {
const animation = entry.animate(
{
scale: ['0.5', '1', '0.5']
},
{
duration: 1, // We'll control the time ourselves
fill: 'both'
}
);
animation.pause();
animations.set(entry, animation);
});
// Update animations on scroll
const tick = () => {
const scrollerRect = scroller.getBoundingClientRect();
entries.forEach(entry => {
const animation = animations.get(entry);
if (!animation) return;
const entryRect = entry.getBoundingClientRect();
const progress = (entryRect.left + entryRect.width / 2 - scrollerRect.left) / scrollerRect.width;
animation.currentTime = progress;
});
};
scroller.addEventListener('scroll', tick);
tick();
}