Revisiting how to build a CSS only slideshow

Week 274 was posted by Charanjit Chana on 2023-01-23.

Almost 3 years ago, I put together some CSS demos on CodePen. The one I was most proud of was a pure-CSS and HTML slideshow. The demo is fairly crude and it had three key issues:

Happy to say though, after an interaction on Twitter where I shared my post but the page jumps were pointed out. Given it had been 3 years and CSS has moved on I decided to attempt a slight re-write to achieve what I set out to achieve.

And here is my second version of a CSS only slideshow:

The only thing to note is that it still doesn't automatically go through the slides and I think that would most likely be achieved with JavaScript. In this case it would be progressive enhancement so I'd be willing to concede that point. Otherwise, this genuinely is a pure-CSS slideshow!

How to build a CSS only slideshow

I wanted to evolve what I'd built before, which was based on the <a> tag and the :target attribute, now it uses radio buttons and the :has() selector.

It took me a while to realise I could place labels elsewhere, so all aspects of the pagination are now driven by labels.

Putting the pagination aside, each slide has a next and previous input and label. If you select an input (hidden) by clicking on the label (visible), then the :has() selector is used to find the checked input from deep inside the slideshow and then allow the slide that's been requested to come to the forefront.

Using these same selectors, I can now also highlight the pagination which wasn't possible before and these have also become labels which just point to specific radio inputs.

Why not to build a CSS only slideshow

The one thing that is a bit of a pain is the fact that I've had to specify the CSS combinations for each slide. This means I couldn't have a dynamic number of slides... rather than setting specific IDs, maybe it would be possible with the :nth-child() and :has() selectors but it feels like it would just be another layer of complication rather than a robust solution.

In the real world, I'd probably programatically figure it out with a @for loop, but that's beyond the scope of a proof of concept.

Would I use a CSS only slideshow in production?

I definitely would, I'd have to refactor it but it's certainly possible and would mean I avoid JavaScript yet again!


After some more feedback, I've taken another fork and now added a check that :has() is supported by the browser. If not, then the pagination is hidden and only the first slide is show. I updated the embedded pen above to show v3, but if you want, you can still check out v2 on CodePen.

Tags: css, development, has-css

Tweet WhatsApp Keep Upvote Digg Tumblr Pin Blogger LinkedIn Skype LiveJournal Like