It’s kind of amazing how far HTML and CSS will take you when building a carousel/slideshow.
- Setting some boxes in a horizontal row with CSS Flexbox is easy.
- Showing only one box at a time with
overflow
and making it swipable withoverscroll-behavior
is easy. - You can make the “slides” line up nicely with
scroll-snap-type
. - A couple of
#jump-links
is all you need to make navigation for it, which you can make all nice and smooth withscroll-behavior
.
Christian Schaefer has taken it a little further with next and previous buttons, plus an auto-play feature that stops playing once interaction starts.
About that auto-play thing — it’s a bonafide CSS trick:
- First I slowly offset the scroll snap points to the right, making the scroll area follow along due to being snapped to them.
- After having scrolled the width of a whole slide, I deactivate the snapping. The scroll area is now untied from the scroll snap points.
- Now I let the scroll snap points jump back to their initial positions without them “snap-dragging” the scroll area back with them
- Then I re-engage the snapping which now lets the scroll area snap to a different snap point 🤯
Cool.
JavaScript-powered slideshows (e.g. with Flickty) can be real nice, too. There is just something neat about getting it done with so little code.
And speaking of how far we can get with HTML and CSS, here are a few related takes on image carousels and galleries.
- How to Make a CSS-Only Carousel (Robin Rendle)
- How To Build an Infinite Scroll Image Gallery with React and CSS Grid (DigitalOcean)
- A Super Flexible CSS Carousel, Enhanced With JavaScript Navigation (Maks Akymenko)
- Carousels Don’t Have to Be Complicated (Chris Coyier)
Exactly what Bulma is missing !
Here’s a fun autoplaying one from years ago :) https://codepen.io/dbj/details/XNmvYo
I tried it out in React and for some reason the buttons don’t work. Anybody know why?
https://codesandbox.io/s/dreamy-currying-mmic6
I also noticed the scrollbar for the first example looking somewhat ugly in Firefox (Windows), and the second example not working when clicking the big buttons in Firefox (Windows).
Is there a modern way peeps are preventing the “anchor jump” – for example I’m using this in the middle of a page and don’t want the slider jumping to the top each time a user clicks on the slide nav (using your first method)…
Same here. I don’t mind jumping to some ID point on the page, but my use requires some text remains visible above the Carousel. Further, instead of the dots at bottom, I intend to put (CSS) text-based buttons ABOVE the carousel. I can kludge them to that position by changing the “bottom” spec to a “top” negative number, but clicking to a carousel page scrolls it to the top of the window, making everything above it disappear.
In answer to others’ question, the repositioning is because the code changes frames by an
<a>
jump to another specified anchor. But the jump not only moves the view sideways, it moves it to the top of the browser window. AFAIK, there’s no way to jump only sideways.Currently I’m playing with various position settings, but prospects don’t seem good, and I consider negative positioning always to be a kludge.
2.5 years late to the party, but I found a solution on this site.
https://markus.oberlehner.net/blog/super-simple-progressively-enhanced-carousel-with-css-scroll-snap/
The author uses a JS event listener to prevent the jumping. Worked like a charm for me.
Hi! I am trying to use the CSS-only Carousel you have posted here, and I can’t figure out how to get rid of the number that is on top of it, like the “1”, “2”, etc. How do I get rid of those? I am putting images in the background of the carousel, and the numbers look bad on top of it.
Hi Katie,
I had this too and it was because I hadn’t included this section that removes the list style –
It’s a counter that is incremented, inserted by a content value. I think you can get rid of it simply by replacing the value with a null string. But if you don’t need the counter, it might be better to get rid of the code that defines it, along with omitting this content line.
Below, I’ve comment out the original, and replaced it:
.carousel__slide:before {
/* content: counter(item); */
content: “” ;
Hi, I am curious how could you make the buttons active, depending on which one you pressed or which screen you swiped to?
I’d like to adapt a version of this to add a heading carousel to my website at https://www.stevesims.com. Can I ask how you hide the navigation arrows please?
The side buttons are defined in this part of the CSS code. Deleting this style makes them disappear. I haven’t tested to see if that area is still hot. Myself, I want the Previous/Next buttons, but they should be moved outside the slide area or made transparent (depending on the carousel’s placement in the overall page), so they don’t obscure content, which might be text or an important image detail.
.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;
}
Hi, I used the CSS-only version and everything is OK except, when I place carousel on css grid. Every when I click on any control button, page focus on carousel (scrolls the page down and hide the top menu). How can I prevent these focus?
There’s a bug in Christian Schaefer’s carousel – when you traverse to the last image in the carousel, and then back to the first, the next button does not work. Any idea on how to prevent that?
I tried the two CSS-only carousels. Everytime a #jump-link is pressed, besides doing the intended it also jumps the box to the top of the page. Not sure what is causing this behavior. Kindly help me prevent this. Link for reference:
https://www.hotlink.com/page/SIY00WE7CKD6/INOYHMTDX1IM
Also in the auto-slide the next button does not work at first until some other button is used.
Hey do you know when i can change the number by image ?
hello
I have a question, how can I change the numbers to different images for each of the slides?
I noticed that this code doesn’t allow links inside the slides. There is a way to solve this?
I like that Christian Schaefer’s is CSS only, and I want the side scroll buttons. And the autoscroll is interesting, as in some situations it can clue the user that changing is possible. But that’s pretty obvioius from the side buttons and if the bottom buttons are made into text buttons at top. (See another of my comments re that.)
But two issues: 1. It doesn’t really demonstrate the range of content, as it just moves the first slide back into place. 2. Autoscroll pauses only on click or hover. If user moves cursor away, it resumes, and that’s REALLY annoying.
So how do we omit autoscrolling altogether? I’m afraid I don’t understand the explanation enough to revised it except trial and error.