A CSS and HTML Only Carousel Slider
Why is it that sliders and carousels need a bunch of javascript and other css files to get them working?
I have seen so many complex sliders with a lot of javascript and libraries that may not even be needed.
Some of the most popular sliders are Slick Slider or Slick Carousel, which is quite old now, but i see it in many sites.
Slick 🖼️
Slick is about 44kb minimised, which is ok, but it does rely on JQuery which is.
JQuery
JQuery Min 3.6 is now only 88kb which is quite good really.
They add up to a total of 132kb which seems like not too much, but what if you could use tools that were already built into the browser and did not require even a inline javascript to get working?
The CSS Slider
So i found this CSS Slider on codepen which does seem to work most of the time, but i found it a bit unresponsive depending on which browser i tested it in and sometimes the left button would work and the right button would not do anything which could be a bit frustrating.
You can see in the demo that the right arrow button is not doing anything when clicked.
Conclusion
So it does seem that while the CSS only version of the slider does work it is slightly limited, so maybe something like flickity could be a good light weight option for a slider.
Sources and Further Reading
- https://cdnjs.com/libraries/slick-carousel
- https://css-tricks.com/css-only-carousel/
- https://codepen.io/Schepp/pen/WNbQByE
- https://codepen.io/chriscoyier/pen/XwbNwX
- https://codepen.io/desandro/pen/emjrBm
- https://flickity.metafizzy.co/
A CSS and HTML Only Carousel Slider Demo
View Demo Full Screen View Demo New Tab
A CSS and HTML Only Carousel Slider Code
HTML
<section class="carousel" aria-label="Gallery">
<ol class="carousel__viewport">
<li id="carousel__slide1"
tabindex="0"
class="carousel__slide">
<div class="carousel__snapper">
<a href="#carousel__slide4"
class="carousel__prev">Go to last slide</a>
<a href="#carousel__slide2"
class="carousel__next">Go to next slide</a>
</div>
</li>
<li id="carousel__slide2"
tabindex="0"
class="carousel__slide">
<div class="carousel__snapper"></div>
<a href="#carousel__slide1"
class="carousel__prev">Go to previous slide</a>
<a href="#carousel__slide3"
class="carousel__next">Go to next slide</a>
</li>
<li id="carousel__slide3"
tabindex="0"
class="carousel__slide">
<div class="carousel__snapper"></div>
<a href="#carousel__slide2"
class="carousel__prev">Go to previous slide</a>
<a href="#carousel__slide4"
class="carousel__next">Go to next slide</a>
</li>
<li id="carousel__slide4"
tabindex="0"
class="carousel__slide">
<div class="carousel__snapper"></div>
<a href="#carousel__slide3"
class="carousel__prev">Go to previous slide</a>
<a href="#carousel__slide1"
class="carousel__next">Go to first slide</a>
</li>
</ol>
<aside class="carousel__navigation">
<ol class="carousel__navigation-list">
<li class="carousel__navigation-item">
<a href="#carousel__slide1"
class="carousel__navigation-button">Go to slide 1</a>
</li>
<li class="carousel__navigation-item">
<a href="#carousel__slide2"
class="carousel__navigation-button">Go to slide 2</a>
</li>
<li class="carousel__navigation-item">
<a href="#carousel__slide3"
class="carousel__navigation-button">Go to slide 3</a>
</li>
<li class="carousel__navigation-item">
<a href="#carousel__slide4"
class="carousel__navigation-button">Go to slide 4</a>
</li>
</ol>
</aside>
</section>
CSS
@keyframes tonext {
75% {
left: 0;
}
95% {
left: 100%;
}
98% {
left: 100%;
}
99% {
left: 0;
}
}
@keyframes tostart {
75% {
left: 0;
}
95% {
left: -300%;
}
98% {
left: -300%;
}
99% {
left: 0;
}
}
@keyframes snap {
96% {
scroll-snap-align: center;
}
97% {
scroll-snap-align: none;
}
99% {
scroll-snap-align: none;
}
100% {
scroll-snap-align: center;
}
}
body {
max-width: 37.5rem;
margin: 0 auto;
padding: 0 1.25rem;
font-family: 'Lato', sans-serif;
}
* {
box-sizing: border-box;
scrollbar-color: transparent transparent; /* thumb and track color */
scrollbar-width: 0px;
}
*::-webkit-scrollbar {
width: 0;
}
*::-webkit-scrollbar-track {
background: transparent;
}
*::-webkit-scrollbar-thumb {
background: transparent;
border: none;
}
* {
-ms-overflow-style: none;
}
ol, li {
list-style: none;
margin: 0;
padding: 0;
}
.carousel {
position: relative;
padding-top: 75%;
filter: drop-shadow(0 0 10px #0003);
perspective: 100px;
}
.carousel__viewport {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
overflow-x: scroll;
counter-reset: item;
scroll-behavior: smooth;
scroll-snap-type: x mandatory;
}
.carousel__slide {
position: relative;
flex: 0 0 100%;
width: 100%;
background-color: #f99;
counter-increment: item;
}
.carousel__slide:nth-child(even) {
background-color: #99f;
}
.carousel__slide:before {
content: counter(item);
position: absolute;
top: 50%;
left: 50%;
transform: translate3d(-50%,-40%,70px);
color: #fff;
font-size: 2em;
}
.carousel__snapper {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
scroll-snap-align: center;
}
@media (hover: hover) {
.carousel__snapper {
animation-name: tonext, snap;
animation-timing-function: ease;
animation-duration: 4s;
animation-iteration-count: infinite;
}
.carousel__slide:last-child .carousel__snapper {
animation-name: tostart, snap;
}
}
@media (prefers-reduced-motion: reduce) {
.carousel__snapper {
animation-name: none;
}
}
.carousel:hover .carousel__snapper,
.carousel:focus-within .carousel__snapper {
animation-name: none;
}
.carousel__navigation {
position: absolute;
right: 0;
bottom: 0;
left: 0;
text-align: center;
}
.carousel__navigation-list,
.carousel__navigation-item {
display: inline-block;
}
.carousel__navigation-button {
display: inline-block;
width: 1.5rem;
height: 1.5rem;
background-color: #333;
background-clip: content-box;
border: 0.25rem solid transparent;
border-radius: 50%;
font-size: 0;
transition: transform 0.1s;
}
.carousel::before,
.carousel::after,
.carousel__prev,
.carousel__next {
position: absolute;
top: 0;
margin-top: 37.5%;
width: 4rem;
height: 4rem;
transform: translateY(-50%);
border-radius: 50%;
font-size: 0;
outline: 0;
}
.carousel::before,
.carousel__prev {
left: -1rem;
}
.carousel::after,
.carousel__next {
right: -1rem;
}
.carousel::before,
.carousel::after {
content: '';
z-index: 1;
background-color: #333;
background-size: 1.5rem 1.5rem;
background-repeat: no-repeat;
background-position: center center;
color: #fff;
font-size: 2.5rem;
line-height: 4rem;
text-align: center;
pointer-events: none;
}
.carousel::before {
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpolygon points='0,50 80,100 80,0' fill='%23fff'/%3E%3C/svg%3E");
}
.carousel::after {
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpolygon points='100,50 20,100 20,0' fill='%23fff'/%3E%3C/svg%3E");
}