Codrops 원본
Experimental CSS-Only Carousels with Scroll-Driven Animations
스크롤 · MIT
갤러리 안에서는 화면을 벗어나거나 움직임을 멈추면 예제도 닫힙니다. 다시 재생할 때는 처음부터 시작해요.
SOURCE FILES
원본 코드 읽기
수집한 원본 소스와 실행 안내를 함께 제공합니다.
css/demo1.css
@import "./shared.css";
@import "@fontsource-variable/inter";
@import "@fontsource/cardo/latin-400.css";
@import "@fontsource/cardo/latin-400-italic.css";
@config "../tailwind.demo1.config.js";
@layer utilities {
.animate-grow {
animation: grow linear both;
}
.animate-page {
animation: page linear both;
}
.animate-progress {
animation: progress linear both;
}
.animate-text {
animation: text linear both;
}
.animate-text-up {
animation: text-up linear both;
}
@keyframes grow {
/* 0% {
clip-path: inset(0 20% round 15cqw);
transform: translateX(calc(100cqw - 50%)) scale(0);
}
18% {
clip-path: inset(0 20% round 15cqw);
transform: translateX(calc(100cqw - 50%)) scale(0.4);
} */
0% {
clip-path: inset(0 25% round 35cqmin);
transform: translateX(70%) scale(0.15);
}
58.75% {
clip-path: inset(0 round 0);
transform: none;
}
100% {
transform: scale(1.5) translateX(-16%);
/* display: none; */
}
}
@keyframes page {
0%, 100% {
opacity: 0.5
}
58% {
opacity: 1;
}
}
@keyframes progress {
from {
transform: scaleX(calc(1/var(--slides)));
}
}
@keyframes text {
0%, 25% {
opacity: 0;
}
50% {
opacity: 1;
transform: none;
}
75%, 100% {
opacity: 0;
}
}
@keyframes text-up {
0%, 25% {
opacity: 0.5;
transform: translateY(105%);
}
50% {
opacity: 1;
transform: none;
}
75%, 100% {
opacity: 0.5;
transform: translateY(-105%);
}
}
}css/demo2.css
@import "./shared.css";
@import "@fontsource-variable/inter";
@import "@fontsource/cardo/latin-400.css";
@import "@fontsource/cardo/latin-400-italic.css";
@config "../tailwind.demo2.config.js";
@layer utilities {
.animate-bottle {
animation: bottle linear both;
@media screen(lg) {
animation-name: bottle-lg;
}
}
.animate-bg {
animation: bg linear both;
}
.animate-page {
animation: page linear both;
}
.animate-fade {
animation: fade linear both;
}
.animate-progress {
animation: progress linear both;
}
.animate-text {
animation: text linear both;
@media screen(lg) {
animation-name: text-lg;
}
@media screen(3xl) {
animation-name: text-3xl;
}
}
@keyframes bottle {
0% {
transform: scale(0.65)
}
50% {
transform: translateY(3rem);
}
100% {
transform: scale(0.65);
}
}
@keyframes bottle-lg {
0% {
transform: scale(0.65)
}
50% {
transform: translateY(3rem);
}
100% {
transform: scale(0.65) translateX(-40%);
}
}
@keyframes bg {
0% {
opacity: 0;
transform: scale(1.2)
}
50% {
opacity: 1;
transform: none
}
100% {
transform: scale(0.8)
}
}
@keyframes page {
0%, 100% {
opacity: 0.5
}
58% {
opacity: 1;
}
}
@keyframes progress {
100% {
transform: translateY(calc((var(--slides) - 1) * -100%));
}
}
@keyframes fade {
0% {
opacity: 0
}
50% {
opacity: 1
}
}
@keyframes text {
0%, 25% {
opacity: 0;
transform: translateX(50%);
}
50% {
opacity: 1;
transform: none;
}
75%, 100% {
opacity: 0;
transform: translateX(-50%);
}
}
@keyframes text-lg {
0%, 40% {
opacity: 0;
transform: translateX(50%);
}
50% {
opacity: 1;
transform: none;
}
60%, 100% {
opacity: 0;
transform: translateX(-50%);
}
}
@keyframes text-3xl {
0%, 25% {
opacity: 0;
transform: translateX(calc(25cqw + 50%));
}
50% {
opacity: 1;
transform: none;
}
75%, 100% {
opacity: 0;
transform: translateX(calc(-50% - 25cqw));
}
}
}함께 쓰는 파일 13개 보기
css/demo3.css
@import "./shared.css";
@import "@fontsource-variable/inter";
@import "@fontsource/cardo/latin-400.css";
@import "@fontsource/cardo/latin-400-italic.css";
@config "../tailwind.demo3.config.js";
@property --scroll-position {
syntax: "<number>";
inherits: true;
initial-value: 0;
}
@property --scroll-position-delayed {
syntax: "<number>";
inherits: true;
initial-value: 0;
}
@layer utilities {
.animate-text-up {
animation: text-up linear both;
}
.animate-fade {
animation: fade linear both;
}
.animate-captions {
animation: captions linear both;
}
.animate-indicator {
animation: indicator linear both;
}
.animate-progress {
animation: progress linear both;
}
.animate-scroll-pos {
animation: adjust-pos linear both;
}
@keyframes captions {
100% {
transform: translateY(calc((var(--slides) - 1)/var(--slides) * -100%));
}
}
@keyframes fade-out {
50% {
opacity: 1;
}
100% {
opacity: 0
}
}
@keyframes first {
50% {
transform: rotate(-5deg);
}
100% {
transform: rotate(-22deg) translateX(-120%);
}
}
@keyframes second {
50% {
transform: rotate(5deg)
}
}
@keyframes third {
50% {
transform: rotate(-9deg)
}
}
@keyframes fourth {
50% {
transform: rotate(9.5deg)
}
}
@keyframes fifth {
50% {
transform: rotate(9.5deg)
}
}
@keyframes sixth {
50% {
transform: rotate(9.5deg)
}
}
@keyframes text-up {
0% {
opacity: 0.5;
transform: translateY(105%);
}
50% {
opacity: 1;
transform: none;
}
100% {
opacity: 0.5;
transform: translateY(-105%);
}
}
@keyframes fade {
0% {
opacity: 0
}
50% {
opacity: 1
}
}
@keyframes indicator {
100% {
transform: translateY(calc((var(--slides) - 1) * -100%));
}
}
@keyframes progress {
from {
transform: scaleY(calc(1/var(--slides)));
}
}
@keyframes adjust-pos {
to {
--scroll-position: 1;
--scroll-position-delayed: 1;
}
}
}css/shared.css
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
@layer base {
* {
min-width: 0;
min-height: 0;
}
:root {
background: var(--color-bg);
}
a {
font-weight: 500;
}
a:not(:hover,:focus-visible,[aria-current="page"]) {
color: color-mix(in srgb, currentColor 60%, transparent);
}
/* Page loader */
:root[data-js][data-loading] body {
&::before,
&::after {
content: '';
position: absolute;
z-index: 30;
}
&::before {
top: 0;
left: 0;
width: 100%;
height: 100%;
background: var(--color-bg);
}
&::after {
top: 50%;
left: 50%;
width: 60px;
height: 60px;
margin: -30px 0 0 -30px;
border-radius: 50%;
opacity: 0.4;
background: currentColor;
animation: loaderAnim 0.7s linear infinite alternate forwards;
}
}
@keyframes loaderAnim {
to {
opacity: 1;
transform: scale3d(0.5,0.5,1);
}
}
}
@layer utilities {
.overlap {
display: grid;
grid-template-areas: "overlap";
& > * {
grid-area: overlap
}
}
.scrollbar-hidden {
-ms-overflow-style: none; /* IE */
scrollbar-width: none; /* Firefox */
&::-webkit-scrollbar {
display: none;
}
}
}index.html
<!doctype html>
<html lang="en" data-loading class="[--color-bg:theme(colors.black)] text-white antialiased">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CSS-Only Carousels | Codrops</title>
<meta name="description" content="Highly-experimental CSS-only carousel variations that use the new scroll-driven animation properties" />
<meta name="keywords" content="CSS animations, scroll-driven animations, CSS on-scroll animations" />
<meta name="author" content="Maxwell Barvian for Codrops" />
<link rel="stylesheet" href="css/demo1.css" />
<link rel="shortcut icon" href="favicon.ico">
<script>
document.documentElement.setAttribute('data-js', '')
window.addEventListener('load', () => document.documentElement.removeAttribute('data-loading'))
</script>
</head>
<body>
<div class="@container min-h-screen relative isolate flex flex-col gap-8 supports-sda:pointer-events-none overflow-clip" style="timeline-scope: --scroller, --slide-1, --slide-2, --slide-3; --slides: 3;">
<img class="absolute hidden supports-sda:block -z-20 inset-0 h-full w-full object-cover animate-grow" style="animation-timeline: --slide-1" src="img/1/biker.jpg" />
<img class="absolute hidden supports-sda:block -z-20 inset-0 h-full w-full object-cover animate-grow" style="animation-timeline: --slide-2" src="img/1/bottle.jpg" />
<img class="absolute hidden supports-sda:block -z-20 inset-0 h-full w-full object-cover animate-grow" style="animation-timeline: --slide-3" src="img/1/helmet.jpg" />
<div class="absolute hidden supports-sda:block -z-10 inset-0 h-full w-full overflow-x-auto snap-mandatory scroll-smooth snap-x scrollbar-hidden pointer-events-auto" style="scroll-timeline: --scroller x;">
<div class="grid grid-flow-col auto-cols-[70cqw] pr-[30cqw] h-full w-fit">
<div role="none" id="slide-1" class="snap-start" style="view-timeline: --slide-1 x;"></div>
<div role="none" id="slide-2" class="snap-start" style="view-timeline: --slide-2 x;"></div>
<div role="none" id="slide-3" class="snap-start" style="view-timeline: --slide-3 x;"></div>
</div>
</div>
<header class="frame relative z-50 mx-7 flex max-lg:flex-col justify-between py-6 border-b gap-2 border-white/60 pointer-events-auto">
<div class="whitespace-nowrap">
<h1 class="font-bold inline align-middle">CSS-Only Carousels</h1>
<a title="Read the article" href="https://tympanus.net/codrops/?p=75188">
<svg class="h-3 ml-0.5 inline-block align-middle" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.00006 0.25H11.7501V11H10.2501V2.81066L1.53039 11.5303L0.469727 10.4697L9.1894 1.75H1.00006V0.25Z" fill="currentColor"/>
</svg>
</a>
</div>
<nav class="flex items-center gap-10">
<a href="index.html" aria-current="page">Demo 1</a>
<a href="index2.html">Demo 2</a>
<a href="index3.html">Demo 3</a>
</nav>
</header>
<div class="flex-1 px-7 relative hidden supports-sda:flex flex-col gap-[inherit]">
<!-- Slides -->
<div class="overlap w-[17rem]">
<p class="animate-text translate-y-[50%] skew-y-[1.5deg]" style="animation-timeline: --slide-1; animation-range-start: 30cqw;">
Move around your city safely and comfortably, while reducing your carbon footprint and helping to keep the air we breathe clean.
</p>
<p class="animate-text translate-y-[50%] skew-y-[1.5deg]" style="animation-timeline: --slide-2; animation-range-start: 30cqw;">
Let’s do it responsibly and avoid having more plastic in the sea than fish. Take your refillable bottle with you and say no to plastic when drinking water.
</p>
<p class="animate-text translate-y-[50%] skew-y-[1.5deg]" style="animation-timeline: --slide-3; animation-range-start: 30cqw;">
The Reflective Helmet seamlessly integrates reflective technology, ensuring visibility without drawing unnecessary attention. The perfect choice for the mindful cyclist.
</p>
</div>
<!-- Indicator -->
<div class="w-60 my-auto">
<nav class="flex font-medium text-sm gap-5">
<a href="#slide-1" class="animate-page !text-white pointer-events-auto" style="animation-timeline: --slide-1; animation-range-start: 30cqw;">01</a>
<a href="#slide-2" class="animate-page !text-white pointer-events-auto" style="animation-timeline: --slide-2; animation-range-start: 30cqw;">02</a>
<a href="#slide-3" class="animate-page !text-white pointer-events-auto" style="animation-timeline: --slide-3; animation-range-start: 30cqw;">03</a>
</nav>
<div class="bg-white/60 mt-2">
<div class="bg-white h-0.5 animate-progress origin-left" style="animation-timeline: --scroller;"></div>
</div>
</div>
<!-- Captions -->
<div class="overlap items-end w-[31rem]">
<div>
<span class="block overflow-clip"><span class="block uppercase font-medium tracking-widest mb-4 animate-text-up" style="animation-timeline: --slide-1; animation-range-start: 30cqw;">Commuter Helmet</span></span>
<p class="pb-7 font-serif text-8xl animate-text translate-y-[205%] skew-y-6" style="animation-timeline: --slide-1; animation-range-start: 30cqw;">Perfect for urban <em>riders</em></p>
</div>
<div>
<span class="block overflow-clip"><span class="block uppercase font-medium tracking-widest mb-4 animate-text-up" style="animation-timeline: --slide-2; animation-range-start: 30cqw;">Smart bottle</span></span>
<p class="pb-7 font-serif text-8xl animate-text translate-y-[205%] skew-y-6" style="animation-timeline: --slide-2; animation-range-start: 30cqw;">We're all <em>connected</em></p>
</div>
<div>
<span class="block overflow-clip"><span class="block uppercase font-medium tracking-widest mb-4 animate-text-up" style="animation-timeline: --slide-3; animation-range-start: 30cqw;">Reflective Helmet</span></span>
<p class="pb-7 font-serif text-8xl animate-text translate-y-[205%] skew-y-6" style="animation-timeline: --slide-3; animation-range-start: 30cqw;">Ready for <em>late nights</em></p>
</div>
</div>
<a href="https://tympanus.net/Tutorials/Velvette/" class="max-lg:hidden absolute z-50 bottom-7 right-7 pointer-events-auto">Previous Demo</a>
</div>
<div class="supports-sda:hidden px-7 pb-7">
Your browser does not support scroll-driven animations. See <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_scroll-driven_animations">MDN</a> for browser compatibility tables.
</div>
</div>
</body>
</html>
index2.html
<!doctype html>
<html lang="en" data-loading class="[--color-bg:#E9DFCF] text-neutral-750 antialiased">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CSS-Only Carousels | Codrops</title>
<meta name="description" content="Highly-experimental CSS-only carousel variations that use the new scroll-driven animation properties" />
<meta name="keywords" content="CSS animations, scroll-driven animations, CSS on-scroll animations" />
<meta name="author" content="Maxwell Barvian for Codrops" />
<link rel="shortcut icon" href="favicon.ico">
<link rel="stylesheet" href="css/demo2.css" />
<script>
document.documentElement.setAttribute('data-js', '')
window.addEventListener('load', () => document.documentElement.removeAttribute('data-loading'))
</script>
</head>
<body>
<div class="@container min-h-screen relative isolate flex flex-col supports-sda:pointer-events-none overflow-clip" style="timeline-scope: --scroller, --slide-1, --slide-2, --slide-3; --slides: 3;">
<div class="absolute bg-[#EDC089] -z-20 inset-0 h-full w-full animate-fade" style="animation-timeline: --slide-2"></div>
<div class="absolute bg-[#B6D6C9] -z-20 inset-0 h-full w-full animate-fade" style="animation-timeline: --slide-3"></div>
<header class="frame mx-7 relative z-50 flex max-lg:flex-col justify-between py-6 border-b gap-2 border-black/20 pointer-events-auto">
<div class="whitespace-nowrap">
<h1 class="font-bold inline align-middle">CSS-Only Carousels</h1>
<a title="Read the article" href="https://tympanus.net/codrops/?p=75188">
<svg class="h-3 ml-0.5 inline-block align-middle" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.00006 0.25H11.7501V11H10.2501V2.81066L1.53039 11.5303L0.469727 10.4697L9.1894 1.75H1.00006V0.25Z" fill="currentColor"/>
</svg>
</a>
</div>
<nav class="flex items-center gap-10">
<a href="index.html">Demo 1</a>
<a href="index2.html" aria-current="page">Demo 2</a>
<a href="index3.html">Demo 3</a>
</nav>
</header>
<main class="lg:max-h-[1000px] hidden supports-sda:flex flex-1 py-14 lg:pb-9 relative flex-col">
<div class="max-lg:relative lg:contents">
<div class="rounded-full -z-10 absolute top-0 lg:top-14 left-1/2 -translate-x-1/2 h-3/4 aspect-[3/4] overflow-clip">
<img class="object-cover animate-bg -left-[25%] -top-[25%] absolute size-[150%] max-w-none" style="animation-timeline: --slide-1" src="img/2/beach.jpg" role="presentation" alt="" />
<img class="object-cover object-left-top animate-bg -left-[25%] -top-[25%] absolute size-[150%] max-w-none" style="animation-timeline: --slide-2" src="img/2/savanna.jpg" role="presentation" alt="" />
<img class="object-cover animate-bg object-top -left-[25%] -top-[25%] absolute size-[150%] max-w-none" style="animation-timeline: --slide-3" src="img/2/glacier.jpg" role="presentation" alt="" />
</div>
<div class="lg:absolute -z-10 inset-0 h-full w-full overflow-x-auto snap-mandatory scroll-smooth snap-x scrollbar-hidden pointer-events-auto" style="scroll-timeline: --scroller x;">
<div class="grid grid-flow-col auto-cols-[50cqw] px-[25cqw] lg:h-full w-fit">
<div class="snap-center overflow-hidden max-lg:pb-[3rem] flex items-center justify-center" style="view-timeline: --slide-1 x; view-timeline-inset: 25cqw">
<img class="animate-bottle lg:h-4/5 object-contain" style="animation-timeline: --slide-1;" src="img/2/abyss.png" alt="White water bottle" />
</div>
<div class="snap-center overflow-hidden max-lg:pb-[3rem] flex items-center justify-center" style="view-timeline: --slide-2 x; view-timeline-inset: 25cqw">
<img class="animate-bottle lg:h-4/5 object-contain" style="animation-timeline: --slide-2;" src="img/2/black.png" alt="White water bottle" />
</div>
<div class="snap-center overflow-hidden max-lg:pb-[3rem] flex items-center justify-center" style="view-timeline: --slide-3 x; view-timeline-inset: 25cqw">
<img class="animate-bottle lg:h-4/5 object-contain" style="animation-timeline: --slide-3;" src="img/2/white.png" alt="White water bottle" />
</div>
</div>
</div>
</div>
<!-- Indicator -->
<span class="flex font-semibold absolute top-14 right-7">
<span class="overflow-y-clip mr-[0.5em]">
<span class="animate-progress overlap justify-items-end" aria-hidden="true" style="animation-timeline: --scroller">
<span>01</span>
<span class="translate-y-[100%]">02</span>
<span class="translate-y-[200%]">03</span>
</span>
</span>
/
03
</span>
<!-- Text -->
<div class="px-7 max-lg:mt-10 flex flex-col items-center lg:items-start flex-1 max-lg:text-center lg:w-[29rem]">
<h2 class="uppercase font-semibold tracking-widest mb-6 whitespace-nowrap">Closca Bottle Wave</h1>
<!-- Slides -->
<div class="overlap flex-1 max-lg:items-start max-lg:justify-center max-lg:max-w-[36rem] lg:max-xl:max-w-[25cqw]">
<div class="flex flex-col items-center lg:items-start">
<h3 class="animate-text font-serif text-7xl lg:text-9xl w-fit" style="animation-timeline: --slide-1;">Abyss</h3>
<p class="animate-text font-serif text-4xl lg:text-5xl mt-2 mb-auto w-3/4" style="animation-timeline: --slide-1;">$39.90</p>
<p class="max-lg:hidden font-serif text-3xl italic animate-text my-4" style="animation-timeline: --slide-1;">By 2050, there could be more plastic in our oceans than fish.</p>
<p class="max-lg:hidden animate-text text-pr" style="animation-timeline: --slide-1;">Plastic pollution injures more than 100,000 marine animals every year. It takes around 450 years for one plastic bottle to decompose.</p>
<a href="https://closca.com" class="animate-text group pointer-events-auto inline-flex gap-4 items-center !text-current mt-6" style="animation-timeline: --slide-1;">
<span class="font-semibold">Shop Now</span>
<svg class="w-6 group-hover:translate-x-1 transition-transform" viewBox="0 0 24 11" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.5303 0.469727L23.5607 5.50006L18.5303 10.5304L17.4697 9.46973L20.6893 6.25006H0.5V4.75006H20.6893L17.4697 1.53039L18.5303 0.469727Z" fill="currentColor"/>
</svg>
</a>
</div>
<div class="flex flex-col items-center lg:items-start">
<h3 class="animate-text font-serif text-7xl lg:text-9xl w-fit" style="animation-timeline: --slide-2;">Black</h3>
<p class="animate-text font-serif text-4xl lg:text-5xl mt-2 mb-auto w-3/4" style="animation-timeline: --slide-2;">$39.90</p>
<p class="max-lg:hidden font-serif text-3xl italic animate-text my-4" style="animation-timeline: --slide-2;">The area affected by desertification is approx 11x India's size.</p>
<p class="max-lg:hidden animate-text text-pretty" style="animation-timeline: --slide-2;">Every minute, over a million plastic bottles are manufactured, and only 9% of them will have a second life.</p>
<a href="https://closca.com" class="animate-text group pointer-events-auto inline-flex gap-4 items-center !text-current mt-6" style="animation-timeline: --slide-2;">
<span class="font-semibold">Shop Now</span>
<svg class="w-6 group-hover:translate-x-1 transition-transform" viewBox="0 0 24 11" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.5303 0.469727L23.5607 5.50006L18.5303 10.5304L17.4697 9.46973L20.6893 6.25006H0.5V4.75006H20.6893L17.4697 1.53039L18.5303 0.469727Z" fill="currentColor"/>
</svg>
</a>
</div>
<div class="flex flex-col items-center lg:items-start">
<h3 class="animate-text font-serif text-7xl lg:text-9xl w-fit" style="animation-timeline: --slide-3;">White</h3>
<p class="animate-text font-serif text-4xl lg:text-5xl mt-2 mb-auto w-3/4" style="animation-timeline: --slide-3;">$39.90</p>
<p class="max-lg:hidden font-serif text-3xl italic animate-text my-4" style="animation-timeline: --slide-3;">By 2050, there could be more plastic in our oceans than fish.</p>
<p class="max-lg:hidden animate-text text-pretty" style="animation-timeline: --slide-3;">Every time you fill your bottle, you save 82.8 grams of CO2 and 12 grams of plastic.</p>
<a href="https://closca.com" class="animate-text group pointer-events-auto inline-flex gap-4 items-center !text-current mt-6" style="animation-timeline: --slide-3;">
<span class="font-semibold">Shop Now</span>
<svg class="w-6 group-hover:translate-x-1 transition-transform" viewBox="0 0 24 11" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.5303 0.469727L23.5607 5.50006L18.5303 10.5304L17.4697 9.46973L20.6893 6.25006H0.5V4.75006H20.6893L17.4697 1.53039L18.5303 0.469727Z" fill="currentColor"/>
</svg>
</a>
</div>
</div>
</div>
<a href="https://tympanus.net/Tutorials/Velvette/" class="max-lg:hidden absolute z-50 bottom-7 right-7 pointer-events-auto">Previous Demo</a>
</main>
<div class="supports-sda:hidden p-7">
Your browser does not support scroll-driven animations. See <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_scroll-driven_animations">MDN</a> for browser compatibility tables.
</div>
</div>
</body>
</html>
index3.html
<!doctype html>
<html lang="en" data-loading class="[--color-bg:#2a2a2a] isolate before:-z-20 before:absolute before:inset-0 before:w-full before:h-full before:bg-noise text-white antialiased">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CSS-Only Carousels | Codrops</title>
<meta name="description" content="Highly-experimental CSS-only carousel variations that use the new scroll-driven animation properties" />
<meta name="keywords" content="CSS animations, scroll-driven animations, CSS on-scroll animations" />
<meta name="author" content="Maxwell Barvian for Codrops" />
<link rel="stylesheet" href="css/demo3.css" />
<link rel="shortcut icon" href="favicon.ico">
<script>
document.documentElement.setAttribute('data-js', '')
window.addEventListener('load', () => document.documentElement.removeAttribute('data-loading'))
</script>
</head>
<body>
<div class="min-h-screen relative flex flex-col overflow-clip" style="timeline-scope: --scroller, --slide-1, --slide-2, --slide-3, --slide-4, --slide-5, --slide-6; --slides: 6; --item-aspect: 335/511;">
<div class="absolute bg-[#C09E6F] -z-30 inset-0 h-full w-full animate-fade" style="animation-timeline: --slide-2"></div>
<div class="absolute bg-[#B4806A] -z-30 inset-0 h-full w-full animate-fade" style="animation-timeline: --slide-3"></div>
<div class="absolute bg-[#68432D] -z-30 inset-0 h-full w-full animate-fade" style="animation-timeline: --slide-4"></div>
<div class="absolute bg-[#3B626E] -z-30 inset-0 h-full w-full animate-fade" style="animation-timeline: --slide-5"></div>
<div class="absolute bg-[#2E423D] -z-30 inset-0 h-full w-full animate-fade" style="animation-timeline: --slide-6"></div>
<header class="frame relative z-50 mx-7 flex max-lg:flex-col justify-between py-6 gap-2">
<div class="whitespace-nowrap">
<h1 class="font-bold inline align-middle">CSS-Only Carousels</h1>
<a title="Read the article" href="https://tympanus.net/codrops/?p=75188">
<svg class="h-3 ml-0.5 inline-block align-middle" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.00006 0.25H11.7501V11H10.2501V2.81066L1.53039 11.5303L0.469727 10.4697L9.1894 1.75H1.00006V0.25Z" fill="currentColor"/>
</svg>
</a>
</div>
<nav class="flex items-center gap-10">
<a href="index.html">Demo 1</a>
<a href="index2.html">Demo 2</a>
<a href="index3.html" aria-current="page">Demo 3</a>
</nav>
</header>
<div class="flex-1 hidden supports-sda:flex min-h-[300px] items-stretch">
<div class="@container-[size] relative w-full">
<div class="absolute inset-0 h-full w-full overflow-y-auto snap-mandatory scroll-smooth snap-x scrollbar-hidden" style="scroll-timeline: --scroller x; --item-width: calc(min(100cqh, 1000px) * var(--item-aspect))">
<div class="grid grid-flow-col px-[--inset-x] auto-cols-[--item-width] h-full w-fit" style="--inset-x: calc(50cqw - var(--item-width)/2)">
<div role="none" class="snap-center" style="view-timeline: --slide-1 x; view-timeline-inset: var(--inset-x)"></div>
<div role="none" class="snap-center" style="view-timeline: --slide-2 x; view-timeline-inset: var(--inset-x)"></div>
<div role="none" class="snap-center" style="view-timeline: --slide-3 x; view-timeline-inset: var(--inset-x)"></div>
<div role="none" class="snap-center" style="view-timeline: --slide-4 x; view-timeline-inset: var(--inset-x)"></div>
<div role="none" class="snap-center" style="view-timeline: --slide-5 x; view-timeline-inset: var(--inset-x)"></div>
<div role="none" class="snap-center" style="view-timeline: --slide-6 x; view-timeline-inset: var(--inset-x)"></div>
</div>
</div>
<!-- Photos -->
<div class="inset-x-0 inset-y-[7.5cqh] absolute overlap isolate items-center justify-center pointer-events-none">
<img class="h-full gbgbgb max-h-[1000px]" style="animation: first auto linear both, fade-out auto linear both; animation-timeline: --slide-1; animation-composition: add, replace;" src="img/3/fashion.jpg" alt="fashion" />
<img class="h-full max-h-[1000px] -z-[1]" style="animation: second auto linear both, first auto linear both, fade-out auto linear both; animation-timeline: --slide-1, --slide-2, --slide-2; animation-composition: add, add, replace;" src="img/3/art.jpg" alt="artwork" />
<img class="h-full max-h-[1000px] -z-[2]" style="animation: third auto linear both, second auto linear both, first auto linear both, fade-out auto linear both; animation-timeline: --slide-1, --slide-2, --slide-3, --slide-3; animation-composition: add, add, add, replace;" src="img/3/woman.jpg" alt="photography" />
<img class="h-full max-h-[1000px] -z-[3]" style="animation: fourth auto linear both, third auto linear both, second auto linear both, first auto linear both, fade-out auto linear both; animation-timeline: --slide-1, --slide-2, --slide-3, --slide-4, --slide-4; animation-composition: add, add, add, add, replace;" src="img/3/sunglasses.jpg" alt="photography" />
<img class="h-full max-h-[1000px] -z-[4]" style="animation: fifth auto linear both, fourth auto linear both, third auto linear both, second auto linear both, first auto linear both, fade-out auto linear both; animation-timeline: --slide-1, --slide-2, --slide-3, --slide-4, --slide-5, --slide-5; animation-composition: add, add, add, add, add, replace;" src="img/3/pockets.jpg" alt="photography" />
<img class="h-full max-h-[1000px] -z-[5]" style="animation: sixth auto linear both, fifth auto linear both, fourth auto linear both, third auto linear both, second auto linear both, first auto linear both; animation-timeline: --slide-1, --slide-2, --slide-3, --slide-4, --slide-5, --slide-6; animation-composition: add;" src="img/3/lights.jpg" alt="photography" />
</div>
</div>
<!-- Indicator -->
<div class="[@media(max-aspect-ratio:335/511)]:hidden flex flex-col gap-2 items-center font-medium absolute top-1/2 -translate-y-1/2 left-7">
<span class="overflow-y-clip">
<span class="animate-indicator overlap justify-items-center" aria-hidden="true" style="animation-timeline: --scroller">
<span>01</span>
<span class="translate-y-[100%]">02</span>
<span class="translate-y-[200%]">03</span>
<span class="translate-y-[300%]">04</span>
<span class="translate-y-[400%]">05</span>
<span class="translate-y-[500%]">06</span>
</span>
</span>
<div class="bg-white/20">
<div class="bg-white w-0.5 h-32 animate-progress origin-top" style="animation-timeline: --scroller;"></div>
</div>
06
</div>
<a href="https://tympanus.net/Tutorials/Velvette/" class="max-lg:hidden [writing-mode:vertical-lr] absolute z-50 top-1/2 -translate-y-1/2 right-7 pointer-events-auto">Previous Demo</a>
</div>
<!-- Captions -->
<div class="h-[0.65em] hidden supports-sda:block animate-scroll-pos [clip-path:inset(0.05em_0_0)] overflow-clip text-[min(15.625rem,20vh)]/[1.2] font-serif select-none" style="animation-timeline: --scroller;">
<div class="flex flex-col whitespace-nowrap items-center opacity-50 w-fit translate-x-[calc(50vw-50%)] animate-captions *:scale-y-[calc(var(--scroll-velocity-abs)*2+1)] *:translate-y-[calc(var(--scroll-velocity)*-100%)]" style="animation-timeline: --scroller; animation-composition: add; transition: --scroll-position-delayed 0.15s linear; --scroll-velocity: calc(var(--scroll-position) - var(--scroll-position-delayed)); --scroll-velocity-abs: max(var(--scroll-velocity), -1*var(--scroll-velocity))">
<span>Fashion</span>
<span>Artworks</span>
<span>Portraits</span>
<span>Still Life</span>
<span>Lifestyle</span>
<span>Wedding</span>
</div>
</div>
<div class="supports-sda:hidden px-7 pb-7">
Your browser does not support scroll-driven animations. See <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_scroll-driven_animations">MDN</a> for browser compatibility tables.
</div>
</div>
</body>
</html>
postcss.config.js
export default {
plugins: {
'tailwindcss/nesting': {},
tailwindcss: {},
autoprefixer: {},
}
}
tailwind.demo1.config.js
import containerQueries from '@tailwindcss/container-queries'
/** @type {import('tailwindcss').Config} */
export default {
content: ['./index.html'],
theme: {
extend: {
fontFamily: {
sans: ['Inter Variable', 'sans-serif'],
serif: ['Cardo', 'serif']
},
letterSpacing: {
widest: '0.3em'
},
supports: {
sda: 'timeline-scope: none'
}
}
},
plugins: [
containerQueries
]
}
tailwind.demo2.config.js
import contanierQueries from '@tailwindcss/container-queries'
/** @type {import('tailwindcss').Config} */
export default {
content: ['./index2.html'],
theme: {
extend: {
fontFamily: {
sans: ['Inter Variable', 'sans-serif'],
serif: ['Cardo', 'serif']
},
screens: {
'3xl': '1800px'
},
fontSize: {
'5xl': '2.75rem',
'9xl': ['7.5rem', '1']
},
spacing: {
'14': '3.5rem'
},
colors: {
neutral: {
'750': '#2d2d2d'
}
},
letterSpacing: {
widest: '0.3em'
},
supports: {
sda: 'timeline-scope: none'
}
}
},
plugins: [
contanierQueries
]
}
tailwind.demo3.config.js
import containerQueries from '@tailwindcss/container-queries'
/** @type {import('tailwindcss').Config} */
export default {
content: ['./index3.html'],
theme: {
extend: {
fontFamily: {
sans: ['Inter Variable', 'sans-serif'],
serif: ['Cardo', 'serif']
},
backgroundImage: {
noise: 'url("/img/3/noise.png")'
},
supports: {
sda: 'timeline-scope: none'
}
}
},
plugins: [
containerQueries
]
}
vite.config.js
import { defineConfig } from 'vite'
import { resolve } from 'node:path'
export default defineConfig({
base: '', // uses relative paths
build: {
rollupOptions: {
input: ['index.html', 'index2.html', 'index3.html'].map(f => resolve(__dirname, f))
}
}
})Original author attribution실행 안내·자료
Experimental CSS-Only Carousels with Scroll-Driven Animations
Original author: Max Barvian
Published by Codrops. Copyright (c) 2026 Codrops.
License: MIT, pursuant to the publisher's downloadable-demo grant.
Keep CODROPS-MIT-2026.txt and the original project notices with copies.
Third-party media exceptions and credits are recorded separately in the source inventory.
Media credits and license evidence실행 안내·자료
README.md
## Credits
- Designs from [Francesco Zagami's Dribbble](https://dribbble.com/francescozagami)
- Demo 1 images generated with [Midjourney](https://midjourney.com)
- Demo 2 images from [Closca's press kit](https://www.closca.com/a/press-kit)
- Demo 3 images from [Unsplash](https://unsplash.com)
## License
[MIT](LICENSE)
Bundled dependency licenses실행 안내·자료
@fontsource-variable/inter@5.0.16 — LICENSE
Copyright 2020 The Inter Project Authors (https://github.com/rsms/inter)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
@fontsource/cardo@5.0.8 — LICENSE
Copyright (c) 2002-2011, David J. Perry (hospes02@scholarsfonts.net)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
BEHIND THE EXAMPLE
이 장면을 만드는 원리
스크롤 타임라인 지원 분기와 콘텐츠 대체
효과를 멈추거나 제거해도 같은 정보와 행동에 도달할 수 있어야 합니다.
- 이 예제에서는
- 첫 데모는 --scroller와 슬라이드별 view-timeline을 timeline-scope로 공유합니다. 이미지·설명·번호 링크는 supports-sda 분기로 나타나고 미지원 분기는 지원 안내만 표시합니다.
코드와 함께 확인하기
코드에서 찾기
timeline-scope: --scrollerindex.html슬라이드 진행과 개별 이미지·문장의 애니메이션을 이름으로 연결합니다.
직접 해보기
타임라인을 사용할 수 없는 환경과 움직임을 제거한 경로에서 내용을 탐색합니다.
살펴볼 변화지원 안내와 별도로 세 슬라이드의 정보에 도달할 수 있어야 하며 현재 번호가 색·투명도에만 의존하는지 확인해야 합니다.
