<section class="slider">
<h1>
CSS slider <br /><span>with
scroll snapping, scroll timeline
and bottom navigation</span>
</h1>
<div>
<ul id="s">
<li id="s1">Slide 1</li>
<li id="s2">Slide 2</li>
<li id="s3">Slide 3</li>
<li id="s4">Slide 4</li>
</ul>
</div>
<nav>
<a href="#s1">Go to Slide 1</a>
<a href="#s2">Go to Slide 2</a>
<a href="#s3">Go to Slide 3</a>
<a href="#s4">Go to Slide 4</a>
</nav>
<p>
Your browser doesn't support <code>animation-timeline</code>.
<br /><br />Please, try this demo on Chrome Canary with the
<code>--enable-experimental-web-platform-features</code>
flag enabled.
</p>
</section>
/* Adjusted from https://codepen.io/fcalderan/pen/KKmKpaZ to not include the steps() */
.slider div {
/* need to hide the horizontal scrollbar */
overflow: hidden;
/* using logical properties */
inline-size: 80%;
min-inline-size: 300px;
max-inline-size: 600px;
margin: 4rem auto 2rem;
aspect-ratio: 7 / 4;
border: 1px yellowgreen solid;
border-radius: 1rem;
}
.slider ul {
display: flex;
flex-flow: row nowrap;
overflow-x: scroll;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
block-size: calc(100% + 25px);
cursor: ew-resize;
}
.slider li {
flex: 0 0 100%;
display: inherit;
justify-content: center;
align-items: center;
scroll-snap-align: start;
scroll-snap-stop: always;
}
.slider nav {
--gap: .75rem;
position: relative;
display: flex;
gap: var(--gap);
margin: 0 auto;
inline-size: max-content;
}
@supports (animation-timeline: works) {
.slider p {
display: none;
}
.slider nav::before, .slider a {
inline-size: 1rem;
aspect-ratio: 1;
border-radius: 50%;
background: #9bc;
}
.slider a {
text-indent: 100%;
overflow: hidden;
white-space: nowrap;
opacity: .33;
}
/* timeline animation */
@scroll-timeline slide {
source: selector(#s);
orientation: inline;
time-range: 1s;
}
.slider nav::before {
content: "";
position: absolute;
z-index: 1;
display: block;
cursor: not-allowed;
transform: translateX(0);
animation: dot 1s forwards;
animation-timeline: slide;
}
@keyframes dot {
0%
{ transform: translateX(0); }
33%
{ transform: translateX(calc((100% + var(--gap)) * 1)); }
66%
{ transform: translateX(calc((100% + var(--gap)) * 2)); }
100%
{ transform: translateX(calc((100% + var(--gap)) * 3)); }
}
}
@supports (not (animation-timeline: works)) {
.slider nav {
display: none;
}
}
/* The following declarations are not strictly
* relevant for this demo to work
*/
.slider {
text-align: center;
font-family: "Montserrat";
line-height: 1.5;
padding: 0 1rem;
}
.slider * {
box-sizing: border-box;
}
.slider h1 {
font-weight: 700;
font-size: 3.4rem;
line-height: 1.2;
margin-top: 2rem;
color: #313131;
font-family: 'Hachi Maru Pop', cursive;
padding: 0 3rem;
}
.slider h1 span {
color: #9bc;
display: block;
font-size: 50%;
line-height: 1.5;
margin-top: 1rem;
}
.slider li {
font-size: 2rem;
color: yellowgreen;
}
.slider p {
position: fixed;
left: 50%;
top: 50%;
box-shadow: 0 0 0 50vmax rgba(127,155,188, .75);
text-align: left;
transform: translate(-50%, -50%);
font-size: 1.2rem;
border-radius: 1.2rem;
padding: 3rem;
margin: 0 auto;
background: #efefef;
inline-size: 86%;
max-inline-size: 800px;
}
.slider code {
background: #f8f8f8;
padding: .25rem;
border-radius: .25rem;
}
.slider nav::after {
content: "use the navigation or wipe left/right";
position: absolute;
display: block;
inline-size: 80vw;
left: 50%;
transform: translate(-50%);
top: calc(100% + 1rem);
font-family: 'Hachi Maru Pop', cursive;
color: #313131;
}
This Pen doesn't use any external JavaScript resources.